Make sure memory map is sorted

This commit is contained in:
bzt 2021-03-28 10:25:07 +02:00
parent 1ac24e3c06
commit b43fe2d3b2
12 changed files with 56 additions and 16 deletions

Binary file not shown.

Binary file not shown.

BIN
dist/bootboot.bin vendored

Binary file not shown.

BIN
dist/bootboot.efi vendored

Binary file not shown.

BIN
dist/bootboot.rom vendored

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -3,9 +3,9 @@
#define sizeof_boot_bin 512
extern unsigned char binary_boot_bin[512];
#define sizeof_bootboot_bin 13312
extern unsigned char binary_bootboot_bin[9282];
extern unsigned char binary_bootboot_bin[9284];
#define sizeof_bootboot_efi 103614
extern unsigned char binary_bootboot_efi[46277];
extern unsigned char binary_bootboot_efi[46349];
#define sizeof_bootboot_img 35488
extern unsigned char binary_bootboot_img[20152];
#define sizeof_bootboot_rv64 8192

View File

@ -65,7 +65,7 @@ int fsz_add_inode(char *filetype, char *mimetype)
in->flags=FSZ_IN_FLAG_INLINE;
in->size=sizeof(FSZ_DirEntHeader);
memcpy(in->data.small.inlinedata,FSZ_DIR_MAGIC,4);
hdr->checksum=crc32_calc((unsigned char*)hdr+16,hdr->numentries*sizeof(FSZ_DirEnt));
hdr->checksum=crc32_calc((unsigned char*)hdr + 16, in->size - 16);
}
}
if(mimetype!=NULL){
@ -120,7 +120,7 @@ void fsz_link_inode(int inode, char *path, int toinode)
in->modifydate=t * 1000000;
in->size+=sizeof(FSZ_DirEnt);
qsort((char*)hdr+sizeof(FSZ_DirEntHeader), hdr->numentries, sizeof(FSZ_DirEnt), fsz_direntcmp);
hdr->checksum=crc32_calc((unsigned char*)hdr+16,hdr->numentries*sizeof(FSZ_DirEnt));
hdr->checksum=crc32_calc((unsigned char*)hdr + 16, in->size - 16);
in->checksum=crc32_calc(in->filetype,1016);
in2->numlinks++;
in2->checksum=crc32_calc(in2->filetype,1016);

View File

@ -1,5 +1,5 @@
/*
* include/osZ/fsZ.h
* include/fsZ.h
*
* Copyright (C) 2017 bzt (bztsrc@gitlab)
*
@ -92,7 +92,7 @@ typedef struct {
} __attribute__((packed)) FSZ_SuperBlock;
#define FSZ_MAGIC "FS/Z"
#define FSZ_RAIDMAGIC "FSRD"
#define FSZ_RAID_MAGIC "FSRD"
#define FSZ_SB_EALG_SHACBC 0 /* encrypted with SHA-XOR-CBC */
#define FSZ_SB_EALG_AESCBC 1 /* encrypted with AES-256-CBC */
@ -145,7 +145,7 @@ typedef struct {
uint64_t sec;
uint32_t sec_hi;
uint32_t chksum;
} __attribute__((packed)) FSZ_SDEntry;
} __attribute__((packed)) FSZ_SectorDir;
/* used with FSZ_IN_FLAG_SD* mappings. */
/* file version structure. You can use this to point to version5, version4 etc. */
@ -361,6 +361,24 @@ typedef struct {
#define FSZ_DIR_FLAG_UNSORTED (1<<0)
#define FSZ_DIR_FLAG_HASHED (2<<0)
enum {
FSZ_DIR_DSP_DEFAULT, /* use global configuration */
FSZ_DIR_DSP_DETAILED,
FSZ_DIR_DSP_LIST,
FSZ_DIR_DSP_ICONS,
FSZ_DIR_DSP_PREVIEW
};
enum {
FSZ_DIR_SORT_DEFAULT, /* use global configuration */
FSZ_DIR_SORT_NAME_ASC,
FSZ_DIR_SORT_NAME_DESC,
FSZ_DIR_SORT_SIZE_ASC,
FSZ_DIR_SORT_SIZE_DESC,
FSZ_DIR_SORT_TIME_ASC,
FSZ_DIR_SORT_TIME_DESC
};
/* directory entries are fixed in size and lexicographically ordered.
* this means a bit slower writes, but also incredibly faster look ups. */
@ -403,8 +421,9 @@ typedef struct {
* by an empty string. Meta label sectors in i-nodes point to the starting logical sector with
* contiguous meta values in a key id value pairs (with possibly binary values), filled up
* with zeros to be multiple of sector size.
*
* Normally meta labels do not exceed logical sector size. But when they do, the allocation
*/
/* Normally meta labels do not exceed logical sector size. But when they do, the allocation
* must be careful to allocate contiguous sectors for a meta block. This complicates things
* a bit when large meta label blocks (>4096) are written, but simplifies a lot on read by
* eliminating the need of translating LSNs for meta labels file. As meta labels are read more
@ -450,7 +469,7 @@ typedef struct {
/* followed by 32 bytes long FSZ_SectorList entries, padded to logical sector size,
* followed by the data sectors pointed by those FSZ_SectorList entries */
#define FSZ_JT_MAGIC "FSTR"
#define FSZ_JT_MAGIC "FSTR"
/*********************************************************
* Encryption *

View File

@ -635,7 +635,7 @@ getmemmap:
mov dword [bootboot.initrd_ptr], eax
.entryok: ;get limit of memory
mov eax, dword [di+8] ;load size
xor al, al
and al, 0F0h ;clear lower tetrad for type
mov edx, dword [di+12]
add eax, dword [di] ;add base
adc edx, dword [di+4]

View File

@ -1244,8 +1244,8 @@ gzerr: panic("Unable to uncompress");
/* Get memory map */
uint64_t srt, end, ldrend = (uintptr_t)paging + (37+(bootboot->numcores*initstack+PAGESIZE-1)/PAGESIZE)*PAGESIZE;
uint64_t iniend = (uint64_t)(uintptr_t)core.ptr + core.size;
MMapEnt *mmapent=(MMapEnt *)&(bootboot->mmap);
uint64_t iniend = (uint64_t)(uintptr_t)core.ptr + core.size, a, b;
MMapEnt *mmapent=(MMapEnt *)&(bootboot->mmap), *sort;
for (i = 0; (int)i < lib_sysinfo.n_memranges; i++) {
srt = lib_sysinfo.memrange[i].base;
end = srt + lib_sysinfo.memrange[i].size;
@ -1274,6 +1274,14 @@ gzerr: panic("Unable to uncompress");
// split into two regions
mmapent->ptr = srt;
mmapent->size = (INITRD_BASE - srt) | (r & 0xF);
// bubble up record. It's okay to use an ineffective, but simple sort here, because there are no
// more records than a couple hundred, and in most scenearios they are already sorted, meaning this
// loop will never run at all. But in the unlikely event they aren't sorted, this will fix that.
for(sort = mmapent - 1; sort >= (MMapEnt *)&(bootboot->mmap) && sort[0].ptr > sort[1].ptr; sort--) {
a = sort[0].ptr; b = sort[0].size;
sort[0].ptr = sort[1].ptr; sort[0].size = sort[1].size;
sort[1].ptr = a; sort[1].size = b;
}
mmapent++;
bootboot->size += sizeof(MMapEnt);
srt = iniend;
@ -1285,6 +1293,11 @@ gzerr: panic("Unable to uncompress");
} else {
mmapent->ptr = srt;
mmapent->size = (end - srt) | (r & 0xF);
for(sort = mmapent - 1; sort >= (MMapEnt *)&(bootboot->mmap) && sort[0].ptr > sort[1].ptr; sort--) {
a = sort[0].ptr; b = sort[0].size;
sort[0].ptr = sort[1].ptr; sort[0].size = sort[1].size;
sort[1].ptr = a; sort[1].size = b;
}
mmapent++;
bootboot->size += sizeof(MMapEnt);
}

View File

@ -1467,7 +1467,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
UINTN bsp_num=0, i, j=0, x,y, handle_size=0,memory_map_size=0, map_key=0, desc_size=0;
UINT32 desc_version=0, a, b;
UINT64 lba_s=0,lba_e=0,sysptr;
MMapEnt *mmapent, *last=NULL;
MMapEnt *mmapent, *last=NULL, *sort;
file_t ret={NULL,0};
CHAR16 **argv, *initrdfile, *configfile, *help=
L"SYNOPSIS\n BOOTBOOT.EFI [ -h | -? | /h | /? | -s ] [ INITRDFILE [ ENVIRONFILE [...] ] ]\n\nDESCRIPTION\n Bootstraps an operating system via the BOOTBOOT Protocol.\n If arguments not given, defaults to\n FS0:\\BOOTBOOT\\INITRD as ramdisk image and\n FS0:\\BOOTBOOT\\CONFIG for boot environment.\n Additional \"key=value\" command line arguments will be appended to the\n environment. If INITRD not found, it will use the first bootable partition\n in GPT. If CONFIG not found, it will look for /sys/config inside the\n INITRD (or partition). With -s it will scan the memory for an initrd ROM.\n\n As this is a loader, it is not supposed to return control to the shell.\n\n";
@ -2077,6 +2077,14 @@ get_memory_map:
} else {
last=mmapent;
bootboot->size+=16;
// bubble up record. It's okay to use an ineffective, but simple sort here, because there are no
// more records than a couple hundred, and in most scenearios they are already sorted, meaning this
// loop will never run at all. But in the unlikely event they aren't sorted, this will fix that.
for(sort = mmapent - 1; sort >= (MMapEnt *)&(bootboot->mmap) && sort[0].ptr > sort[1].ptr; sort--) {
lba_s = sort[0].ptr; lba_e = sort[0].size;
sort[0].ptr = sort[1].ptr; sort[0].size = sort[1].size;
sort[1].ptr = lba_s; sort[1].size = lba_e;
}
mmapent++;
}
}