mirror of
https://gitlab.com/bztsrc/bootboot.git
synced 2023-02-13 20:54:32 -05:00
Finished porting to coreboot
This commit is contained in:
parent
7c10d17e02
commit
834de6b900
37 changed files with 2431 additions and 86 deletions
|
@ -252,9 +252,9 @@ meghajtót, vagy amikor az "initrd" egy statikusan linkelt futtatható, mint pé
|
|||
a boot partícióra és már mehet is!
|
||||
|
||||
A BOOTBOOT Protokoll előírja, hogy a fájl rendszer meghajtók ([itt](https://gitlab.com/bztsrc/bootboot/blob/master/x86_64-efi/fs.h),
|
||||
[itt](https://gitlab.com/bztsrc/bootboot/blob/master/x86_64-bios/fs.inc) és [itt](https://gitlab.com/bztsrc/bootboot/blob/master/aarch64-rpi/fs.h))
|
||||
elkülönítve legyenek a betöltő forrásának többi részétől. Ez azért van, mert elsősorban azoknak a hobbi OS fejlesztőknek
|
||||
készült, akik saját fájl rendszert használnak.
|
||||
[itt](https://gitlab.com/bztsrc/bootboot/blob/master/x86_64-bios/fs.inc), [itt](https://gitlab.com/bztsrc/bootboot/blob/master/aarch64-rpi/fs.h)
|
||||
és [itt](https://gitlab.com/bztsrc/bootboot/blob/master/x86_64-cb/fs.h)) elkülönítve legyenek a betöltő forrásának többi részétől.
|
||||
Ez azért van, mert elsősorban azoknak a hobbi OS fejlesztőknek készült, akik saját fájl rendszert használnak.
|
||||
|
||||
A referencia implementációk támogatják a [cpio](https://en.wikipedia.org/wiki/Cpio)-t (hpodc, newc és crc variáns),
|
||||
az [ustar](https://en.wikipedia.org/wiki/Tar_(computing))-t, az osdev.org féle [SFS](http://wiki.osdev.org/SFS)-t,
|
||||
|
|
|
@ -252,9 +252,10 @@ want to use your own file system but you don't have written an fs driver for it
|
|||
your initrd on the boot partition, and you're ready to rock and roll!
|
||||
|
||||
The BOOTBOOT Protocol expects the file system drivers ([here](https://gitlab.com/bztsrc/bootboot/blob/master/x86_64-efi/fs.h),
|
||||
[here](https://gitlab.com/bztsrc/bootboot/blob/master/x86_64-bios/fs.inc) and [here](https://gitlab.com/bztsrc/bootboot/blob/master/aarch64-rpi/fs.h))
|
||||
to be separated from the rest of the loader's source. This is so because it was designed to help the needs of hobby
|
||||
OS developers, specially for those who want to write their own file systems.
|
||||
[here](https://gitlab.com/bztsrc/bootboot/blob/master/x86_64-bios/fs.inc), [here](https://gitlab.com/bztsrc/bootboot/blob/master/aarch64-rpi/fs.h)
|
||||
and [here](https://gitlab.com/bztsrc/bootboot/blob/master/x86_64-cb/fs.h)) to be separated from the rest of the loader's source.
|
||||
This is so because it was designed to help the needs of hobby OS developers, specially for those who want to write their own file
|
||||
systems.
|
||||
|
||||
The reference implementations support [cpio](https://en.wikipedia.org/wiki/Cpio) (all hpodc, newc and crc variants),
|
||||
[ustar](https://en.wikipedia.org/wiki/Tar_(computing)), osdev.org's [SFS](http://wiki.osdev.org/SFS),
|
||||
|
|
|
@ -24,7 +24,7 @@ $(LIBPAYLOAD_DIR):
|
|||
|
||||
ifneq ($(strip $(wildcard libpayload)),)
|
||||
include $(XCOMPILE)
|
||||
LPGCC = CC="$(GCC_CC_aarch64)" "$(LIBPAYLOAD_DIR)/bin/lpgcc"
|
||||
LPGCC = CC="$(GCC_CC_arm64)" "$(LIBPAYLOAD_DIR)/bin/lpgcc"
|
||||
$(TARGET):
|
||||
$(LPGCC) $(CFLAGS) -o $(TARGET) bootboot.c
|
||||
else
|
||||
|
|
|
@ -969,13 +969,13 @@ int GetLFB(uint32_t width, uint32_t height)
|
|||
}
|
||||
}
|
||||
//if we already have a framebuffer, release it
|
||||
if(bootboot->fb_ptr!=NULL) {
|
||||
if(bootboot->fb_ptr) {
|
||||
mbox[0] = 8*4;
|
||||
mbox[1] = MBOX_REQUEST;
|
||||
mbox[2] = 0x48001; //release buffer
|
||||
mbox[3] = 8;
|
||||
mbox[4] = 8;
|
||||
mbox[5] = (uint32_t)(((uint64_t)bootboot->fb_ptr));
|
||||
mbox[5] = (uint32_t)bootboot->fb_ptr;
|
||||
mbox[6] = 0;
|
||||
mbox[7] = 0;
|
||||
mbox_call(MBOX_CH_PROP,mbox);
|
||||
|
@ -1033,7 +1033,7 @@ int GetLFB(uint32_t width, uint32_t height)
|
|||
bootboot->fb_width=mbox[5];
|
||||
bootboot->fb_height=mbox[6];
|
||||
bootboot->fb_scanline=mbox[33];
|
||||
bootboot->fb_ptr=(void*)((uint64_t)mbox[28]);
|
||||
bootboot->fb_ptr=(uint64_t)mbox[28];
|
||||
bootboot->fb_size=mbox[29];
|
||||
bootboot->fb_type=mbox[24]?FB_ABGR:FB_ARGB;
|
||||
kx=ky=0;
|
||||
|
@ -1065,11 +1065,11 @@ void putc(char c)
|
|||
line=offs;
|
||||
mask=1<<(font->width-1);
|
||||
for(x=0;x<font->width;x++){
|
||||
*((uint32_t*)((uint64_t)bootboot->fb_ptr + line))=((int)*glyph) & (mask)?color:0;
|
||||
*((uint32_t*)(bootboot->fb_ptr + line))=((int)*glyph) & (mask)?color:0;
|
||||
mask>>=1;
|
||||
line+=4;
|
||||
}
|
||||
*((uint32_t*)((uint64_t)bootboot->fb_ptr + line))=0;
|
||||
*((uint32_t*)(bootboot->fb_ptr + line))=0;
|
||||
glyph+=bytesperline;
|
||||
offs+=bootboot->fb_scanline;
|
||||
}
|
||||
|
@ -1259,15 +1259,15 @@ int bootboot_main(uint64_t hcl)
|
|||
#endif
|
||||
if(mp>0) {
|
||||
// we got response from raspbootcom
|
||||
sp=uart_getc();
|
||||
sp|=uart_getc()<<8; sp|=uart_getc()<<16; sp|=uart_getc()<<24;
|
||||
sp=uart_getc(); sp|=uart_getc()<<8; sp|=uart_getc()<<16; sp|=uart_getc()<<24;
|
||||
if(sp>0 && sp<INITRD_MAXSIZE*1024*1024) {
|
||||
uart_puts("OK");
|
||||
initrd.size=sp;
|
||||
initrd.ptr=pe=(uint8_t*)&_end;
|
||||
while(sp--) *pe++ = uart_getc();
|
||||
goto gotinitrd;
|
||||
}
|
||||
} else
|
||||
uart_puts("SE");
|
||||
}
|
||||
|
||||
/* initialize SDHC card reader in EMMC */
|
||||
|
@ -1341,7 +1341,7 @@ diskerr:
|
|||
// locate BOOTBOOT directory
|
||||
uint64_t data_sec, root_sec, clu=0, cclu=0, s, s2, s3;
|
||||
fatdir_t *dir;
|
||||
uint32_t *fat32=(uint32_t*)((uint8_t*)&_end+bpb->rsc*512);
|
||||
uint32_t *fat32=(uint32_t*)((uint8_t*)&_end+512);
|
||||
uint16_t *fat16=(uint16_t*)fat32;
|
||||
uint8_t *ptr;
|
||||
data_sec=root_sec=((bpb->spf16?bpb->spf16:bpb->spf32)*bpb->nf)+bpb->rsc;
|
||||
|
@ -1711,7 +1711,7 @@ viderr:
|
|||
for(j=ky=0;ky<bootboot->fb_height;ky++) {
|
||||
r=j;
|
||||
for(kx=0;kx<bootboot->fb_width;kx+=2,r+=8)
|
||||
*((uint64_t*)((uint64_t)bootboot->fb_ptr + r))=0;
|
||||
*((uint64_t*)(bootboot->fb_ptr + r))=0;
|
||||
j+=bootboot->fb_scanline;
|
||||
}
|
||||
kx=ky=0; color=0xFFDD33;
|
||||
|
@ -1745,7 +1745,7 @@ viderr:
|
|||
paging[4*512+511]=(uint64_t)((uint8_t*)&__paging+36*PAGESIZE)|0b11|(3<<8)|(1<<10);// pointer to core L3
|
||||
j = (fb_addr>>(12)) & 0x1FF;
|
||||
for(r=0;r<31*512;r++)
|
||||
paging[5*512+j+r]=(uint64_t)((uint8_t*)bootboot->fb_ptr+r*PAGESIZE)|0b11|(2<<8)|(1<<10)|(2<<2)|(1L<<54); //map framebuffer
|
||||
paging[5*512+j+r]=(uint64_t)(bootboot->fb_ptr+r*PAGESIZE)|0b11|(2<<8)|(1<<10)|(2<<2)|(1L<<54); //map framebuffer
|
||||
// core L3
|
||||
// dynamically map these. Main struct, environment string and code segment
|
||||
for(r=0;r<(core.size/PAGESIZE);r++)
|
||||
|
|
Binary file not shown.
Binary file not shown.
BIN
dist/bootboot.efi
vendored
BIN
dist/bootboot.efi
vendored
Binary file not shown.
9
dist/bootboot.h
vendored
9
dist/bootboot.h
vendored
|
@ -57,9 +57,10 @@ extern "C" {
|
|||
#define PROTOCOL_BIGENDIAN 0x80
|
||||
|
||||
/* loader types, just informational */
|
||||
#define LOADER_BIOS (0<<2)
|
||||
#define LOADER_UEFI (1<<2)
|
||||
#define LOADER_RPI (2<<2)
|
||||
#define LOADER_BIOS (0<<2)
|
||||
#define LOADER_UEFI (1<<2)
|
||||
#define LOADER_RPI (2<<2)
|
||||
#define LOADER_COREBOOT (3<<2)
|
||||
|
||||
/* framebuffer pixel format, only 32 bits supported */
|
||||
#define FB_ARGB 0
|
||||
|
@ -98,7 +99,7 @@ typedef struct {
|
|||
uint8_t datetime[8]; /* in BCD yyyymmddhhiiss UTC (independent to timezone) */
|
||||
uint64_t initrd_ptr; /* ramdisk image position and size */
|
||||
uint64_t initrd_size;
|
||||
uint8_t *fb_ptr; /* framebuffer pointer and dimensions */
|
||||
uint64_t fb_ptr; /* framebuffer pointer and dimensions */
|
||||
uint32_t fb_size;
|
||||
uint32_t fb_width;
|
||||
uint32_t fb_height;
|
||||
|
|
BIN
dist/bootboot.img
vendored
BIN
dist/bootboot.img
vendored
Binary file not shown.
BIN
dist/bootboot.rom
vendored
BIN
dist/bootboot.rom
vendored
Binary file not shown.
|
@ -42,7 +42,7 @@ grub.iso: ../mkbootimg/mkbootimg initdir mkbootimg.json
|
|||
|
||||
# test the disk image
|
||||
rom: initrd.rom
|
||||
qemu-system-x86_64 -option-rom ../bootboot.bin -option-rom initrd.rom -serial stdio
|
||||
qemu-system-x86_64 -option-rom ../dist/bootboot.bin -option-rom initrd.rom -serial stdio
|
||||
|
||||
bios:
|
||||
qemu-system-x86_64 -drive file=disk-x86.img,format=raw -serial stdio
|
||||
|
@ -60,10 +60,13 @@ eficdrom:
|
|||
qemu-system-x86_64 -bios $(OVMF) -m 64 -cdrom disk-x86.img -serial stdio
|
||||
|
||||
linux:
|
||||
qemu-system-x86_64 -kernel ../bootboot.bin -drive file=disk-x86.img,format=raw -serial stdio
|
||||
qemu-system-x86_64 -kernel ../dist/bootboot.bin -drive file=disk-x86.img,format=raw -serial stdio
|
||||
|
||||
sdcard:
|
||||
qemu-system-aarch64 -M raspi3 -kernel ../bootboot.img -drive file=disk-rpi.img,if=sd,format=raw -serial stdio
|
||||
qemu-system-aarch64 -M raspi3 -kernel ../dist/bootboot.img -drive file=disk-rpi.img,if=sd,format=raw -serial stdio
|
||||
|
||||
coreboot:
|
||||
qemu-system-x86_64 -bios coreboot.rom -drive file=disk-x86.img,format=raw -serial stdio
|
||||
|
||||
# clean up
|
||||
clean:
|
||||
|
|
|
@ -6,6 +6,7 @@ BOOTBOOT Minta Bootolható Lemezkép Fájlok
|
|||
- disk-rpi.img.gz: minta lemezkép AArch64-hez RaspberryPi 3-on és 4-en
|
||||
- disk-x86.img.gz: minta lemezkép x86_64-hez (CDROM, BIOS, UEFI)
|
||||
- initrd.rom.gz: minta initrd ROM kép (beágyazott BIOS rendszerekhez)
|
||||
- coreboot.rom.gz: minta coreboot ROM kép BOOTBOOT payload-al
|
||||
|
||||
Mielőtt használhatnád a lemezképeket, ki kell csomagolni őket a `gzip -d` paranccsal. A lemezképeket az [mkbootimg](https://gitlab.com/bztsrc/bootboot/tree/master/mkbootimg)
|
||||
paranccsal hoztam létre, és a kiírásukhoz fizikai lemezre az [USBImager](https://gitlab.com/bztsrc/usbimager)-t vagy a `dd` parancsot javaslom.
|
||||
|
@ -28,6 +29,9 @@ Lásd mkbootimg.json. Nézz bele a Makefile-ba is, az elején fogsz látni konfi
|
|||
|
||||
Aztán csak futtasd a `make` parancsot.
|
||||
|
||||
A coreboot.rom fordításához [pecselt coreboot fordító környezet](https://gitlab.com/bztsrc/bootboot/tree/master/x86_64-cb)
|
||||
szükséges.
|
||||
|
||||
Tesztelés
|
||||
---------
|
||||
|
||||
|
@ -65,3 +69,7 @@ indítja.
|
|||
make sdcard
|
||||
```
|
||||
Ez "raspi3" gépet emulálva tölti be a minta kernelt SD kártya meghajtóról (kell hozzá a qemu-system-aarch64).
|
||||
```
|
||||
make coreboot
|
||||
```
|
||||
BOOTBOOT tesztelése mint coreboot payload (nincs BIOS se UEFI).
|
||||
|
|
|
@ -6,6 +6,7 @@ See [BOOTBOOT Protocol](https://gitlab.com/bztsrc/bootboot) for common details.
|
|||
- disk-rpi.img.gz: an example image for AArch64 and RaspberryPi 3 and 4
|
||||
- disk-x86.img.gz: an example image for x86_64 (CDROM, BIOS, UEFI)
|
||||
- initrd.rom.gz: an example initrd ROM image (for embedded BIOS systems)
|
||||
- coreboot.rom.gz: an example coreboot ROM image with BOOTBOOT payload
|
||||
|
||||
Before you can use the images, uncompress them with `gzip -d`. I've used [mkbootimg](https://gitlab.com/bztsrc/bootboot/tree/master/mkbootimg)
|
||||
to generate these images, and I recommend [USBImager](https://gitlab.com/bztsrc/usbimager) or `dd` to write them to physical disks.
|
||||
|
@ -28,6 +29,8 @@ See mkbootimg.json. Look at the beginning of the Makefile too, you'll find confi
|
|||
|
||||
Then just run `make`.
|
||||
|
||||
Compiling coreboot.rom requires a [patched coreboot build environment](https://gitlab.com/bztsrc/bootboot/tree/master/x86_64-cb).
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
|
@ -64,3 +67,7 @@ Will boot the example kernel by booting BOOTBOOT via the [Linux/x86 Boot Protoco
|
|||
make sdcard
|
||||
```
|
||||
Will boot the example kernel from SDCard emulating "raspi3" machine under qemu (requires qemu-system-aarch64).
|
||||
```
|
||||
make coreboot
|
||||
```
|
||||
To test BOOTBOOT as a coreboot payload (no BIOS, no UEFI).
|
||||
|
|
BIN
images/coreboot.rom.gz
Normal file
BIN
images/coreboot.rom.gz
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -2,8 +2,8 @@
|
|||
|
||||
extern unsigned char binary_boot_bin[512];
|
||||
extern unsigned char binary_bootboot_bin[11776];
|
||||
extern unsigned char binary_bootboot_efi[96950];
|
||||
extern unsigned char binary_bootboot_img[34616];
|
||||
extern unsigned char binary_bootboot_efi[96946];
|
||||
extern unsigned char binary_bootboot_img[34672];
|
||||
extern unsigned char binary_LICENCE_broadcom[1594];
|
||||
extern unsigned char binary_bootcode_bin[52480];
|
||||
extern unsigned char binary_fixup_dat[7274];
|
||||
|
|
|
@ -61,7 +61,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(0,(unsigned char*)hdr+sizeof(FSZ_DirEntHeader),hdr->numentries*sizeof(FSZ_DirEnt));
|
||||
hdr->checksum=crc32_calc((unsigned char*)hdr+sizeof(FSZ_DirEntHeader),hdr->numentries*sizeof(FSZ_DirEnt));
|
||||
}
|
||||
}
|
||||
if(mimetype!=NULL){
|
||||
|
@ -77,7 +77,7 @@ int fsz_add_inode(char *filetype, char *mimetype)
|
|||
}
|
||||
in->changedate=t * 1000000;
|
||||
in->modifydate=t * 1000000;
|
||||
in->checksum=crc32(0,in->filetype,1016);
|
||||
in->checksum=crc32_calc(in->filetype,1016);
|
||||
fs_len+=fsz_secsize;
|
||||
return fs_len/fsz_secsize-1;
|
||||
}
|
||||
|
@ -116,10 +116,10 @@ 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(0,(unsigned char*)hdr+sizeof(FSZ_DirEntHeader),hdr->numentries*sizeof(FSZ_DirEnt));
|
||||
in->checksum=crc32(0,in->filetype,1016);
|
||||
hdr->checksum=crc32_calc((unsigned char*)hdr+sizeof(FSZ_DirEntHeader),hdr->numentries*sizeof(FSZ_DirEnt));
|
||||
in->checksum=crc32_calc(in->filetype,1016);
|
||||
in2->numlinks++;
|
||||
in2->checksum=crc32(0,in2->filetype,1016);
|
||||
in2->checksum=crc32_calc(in2->filetype,1016);
|
||||
}
|
||||
|
||||
void fsz_add_file(char *name, unsigned char *data, unsigned long int size)
|
||||
|
@ -269,7 +269,7 @@ void fsz_add_file(char *name, unsigned char *data, unsigned long int size)
|
|||
memcpy(in->filetype,"text",4);
|
||||
}
|
||||
}
|
||||
in->checksum=crc32(0,in->filetype,1016);
|
||||
in->checksum=crc32_calc(in->filetype,1016);
|
||||
fs_len+=s;
|
||||
fsz_link_inode(inode,name,0);
|
||||
}
|
||||
|
@ -333,5 +333,5 @@ void fsz_close()
|
|||
if(!sb) return;
|
||||
if(!sb->numsec) sb->numsec = fs_len / fsz_secsize;
|
||||
sb->freesec = fs_len / fsz_secsize;
|
||||
sb->checksum = crc32(0,(unsigned char *)&sb->magic,508);
|
||||
sb->checksum = crc32_calc((unsigned char *)&sb->magic,508);
|
||||
}
|
||||
|
|
|
@ -43,8 +43,8 @@
|
|||
* the superblock. Current implementation only supports 64 bits, that gives you the
|
||||
* capacity of 64 Zettabytes with 4096 bytes sector size. */
|
||||
|
||||
/* for CRC32 the ANSI method is used, CCITT32 CRC with polynominal 0x04c11db7
|
||||
* (same as the one in EFI GPT and in gzip checksums) */
|
||||
/* for CRC32 the Castagnoli method is used, polynomial 0x1EDC6F41 (differs to ANSI
|
||||
* CRC32a in EFI GPT and in gzip) but has hardware support on many architectures */
|
||||
|
||||
/* sizeof = 16, one Access Control Entry, UUID without the last byte */
|
||||
typedef struct {
|
||||
|
|
|
@ -365,6 +365,47 @@ void makerom()
|
|||
printf("mkbootimg: %s %s.\r\n", "initrd.rom", lang[SAVED]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an initrd ROM image into a Flashmap image area (section, partition, range whatever)
|
||||
*/
|
||||
int flashmapadd(char *file)
|
||||
{
|
||||
unsigned char *data=NULL, *desc;
|
||||
FILE *f;
|
||||
unsigned int size=0,bs=((initrd_size[0]+511)/512)*512;
|
||||
/* see if file exists and contains a Flashmap */
|
||||
if(!file || !*file) return 0;
|
||||
f=fopen(file,"r");
|
||||
if(!f) return 0;
|
||||
fseek(f,0L,SEEK_END);
|
||||
size=(unsigned int)ftell(f);
|
||||
fseek(f,0L,SEEK_SET);
|
||||
data=(unsigned char*)malloc(size + bs);
|
||||
if(!data) { fprintf(stderr,"mkbootimg: %s\r\n",lang[ERR_MEM]); exit(1); }
|
||||
data[0] = 0; fread(data,size,1,f);
|
||||
fclose(f);
|
||||
if(memcmp(data, "__FMAP__", 8)) { free(data); return 0; }
|
||||
if(!initrd_buf[0] || bs < 1) { fprintf(stderr,"mkbootimg: %s\r\n",lang[ERR_NOINITRD]); exit(1); }
|
||||
/* add a new or replace the last partition descriptor */
|
||||
desc = data + 0x38 + data[0x36] * 42;
|
||||
if(!memcmp(desc - 34, "INITRD", 7)) desc -= 42; else data[0x36]++;
|
||||
size = (*((unsigned int*)(desc - 42)) + *((unsigned int*)(desc - 38)) + 4095) & ~4095;
|
||||
memset(desc, 0, 42);
|
||||
memcpy(desc + 0, &size, 4);
|
||||
memcpy(desc + 4, &bs, 4);
|
||||
memcpy(desc + 8, "INITRD", 6);
|
||||
memcpy(data + size,initrd_buf[0],initrd_size[0]);
|
||||
if(initrd_size[0] < (int)bs) memset(data + size + initrd_size[0], 0, bs - initrd_size[0]);
|
||||
size += bs; *((unsigned int*)(data + 0x12)) = *((unsigned int*)(data + 0x3c)) = size;
|
||||
/* write out */
|
||||
f=fopen(file,"wb");
|
||||
if(!f) { fprintf(stderr,"mkbootimg: %s %s\r\n", lang[ERR_WRITE], file); exit(3); }
|
||||
fwrite(data,size,1,f);
|
||||
fclose(f);
|
||||
printf("mkbootimg: %s %s.\r\n", file, lang[SAVED]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function
|
||||
*/
|
||||
|
@ -387,12 +428,14 @@ int main(int argc, char **argv)
|
|||
" ./mkbootimg check <kernel elf / pe>\r\n"
|
||||
" ./mkbootimg <%s> initrd.rom\r\n"
|
||||
" ./mkbootimg <%s> bootpart.bin\r\n"
|
||||
" ./mkbootimg <%s> <flashmap rom>\r\n"
|
||||
" ./mkbootimg <%s> <%s>\r\n\r\n",lang[HELP3],lang[HELP4],
|
||||
lang[HELP4],lang[HELP4],lang[HELP5]);
|
||||
lang[HELP4],lang[HELP4],lang[HELP4],lang[HELP5]);
|
||||
printf( "%s:\n"
|
||||
" ./mkbootimg check mykernel/mykernel.x86_64.elf\r\n"
|
||||
" ./mkbootimg myos.json initrd.rom\r\n"
|
||||
" ./mkbootimg myos.json bootpart.bin\r\n"
|
||||
" ./mkbootimg myos.json coreboot.rom\r\n"
|
||||
" ./mkbootimg myos.json myos.img\r\n",
|
||||
lang[HELP6]);
|
||||
return 0;
|
||||
|
@ -456,7 +499,7 @@ int main(int argc, char **argv)
|
|||
fwrite(initrd_buf[0],initrd_size[0],1,f);
|
||||
fclose(f);
|
||||
printf("mkbootimg: %s %s.\r\n", "initrd.bin", lang[SAVED]);
|
||||
} else {
|
||||
} else if(!flashmapadd(argv[2])) {
|
||||
esp_makepart();
|
||||
if(!strcmp(argv[2], "bootpart.bin")) {
|
||||
/* write out */
|
||||
|
|
|
@ -204,3 +204,4 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
|
|||
void esp_makepart();
|
||||
void gpt_maketable();
|
||||
void img_write(char *fn);
|
||||
uint32_t crc32_calc(unsigned char *start,int length);
|
||||
|
|
|
@ -193,3 +193,47 @@ void initrduncompress()
|
|||
} else
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* precalculated CRC32c lookup table for polynomial 0x1EDC6F41 (castagnoli-crc)
|
||||
*/
|
||||
uint32_t crc32c_lookup[256]={
|
||||
0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
|
||||
0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
|
||||
0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
|
||||
0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
|
||||
0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
|
||||
0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
|
||||
0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
|
||||
0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
|
||||
0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
|
||||
0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
|
||||
0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
|
||||
0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
|
||||
0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
|
||||
0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
|
||||
0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
|
||||
0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
|
||||
0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
|
||||
0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
|
||||
0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
|
||||
0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
|
||||
0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
|
||||
0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
|
||||
0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
|
||||
0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
|
||||
0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
|
||||
0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
|
||||
0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
|
||||
0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
|
||||
0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
|
||||
0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
|
||||
0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
|
||||
0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
|
||||
};
|
||||
uint32_t crc32_calc(unsigned char *start,int length)
|
||||
{
|
||||
uint32_t crc32_val=0;
|
||||
while(length--) crc32_val=(crc32_val>>8)^crc32c_lookup[(crc32_val&0xff)^(unsigned char)*start++];
|
||||
return crc32_val;
|
||||
}
|
||||
|
|
|
@ -33,23 +33,23 @@
|
|||
;* text segment occupied: 800-7C00, bss: 8000-x
|
||||
;*
|
||||
;* Memory map
|
||||
;* 0h - 600h reserved for the system
|
||||
;* 600h - 800h stage1 (MBR/VBR, boot.bin)
|
||||
;* 800h - 6C00h stage2 (this)
|
||||
;* 6C00h - 7C00h stack
|
||||
;* 8000h - 9000h bootboot structure
|
||||
;* 9000h - A000h environment
|
||||
;* A000h - B000h disk buffer / PML4
|
||||
;* B000h - C000h PDPE, higher half core 4K slots
|
||||
;* C000h - D000h PDE 4K
|
||||
;* D000h - E000h PTE 4K
|
||||
;* E000h - F000h PDPE, 4G physical RAM identity mapped 2M
|
||||
;* F000h -10000h PDE 2M
|
||||
;* 10000h -11000h PDE 2M
|
||||
;* 11000h -12000h PDE 2M
|
||||
;* 12000h -13000h PDE 2M
|
||||
;* 13000h -14000h PTE 4K
|
||||
;* 14000h -A0000h core stacks (1k per core)
|
||||
;* 0h - 600h reserved for the system
|
||||
;* 600h - 800h stage1 (MBR/VBR, boot.bin)
|
||||
;* 800h - 6C00h stage2 (this)
|
||||
;* 6C00h - 7C00h stack (7000h - 700Fh SMP trampoline code)
|
||||
;* 8000h - 9000h bootboot structure
|
||||
;* 9000h - A000h environment
|
||||
;* A000h - B000h disk buffer / PML4
|
||||
;* B000h - C000h PDPE, higher half core 4K slots
|
||||
;* C000h - D000h PDE 4K
|
||||
;* D000h - E000h PTE 4K
|
||||
;* E000h - F000h PDPE, 4G physical RAM identity mapped 2M
|
||||
;* F000h - 10000h PDE 2M
|
||||
;* 10000h - 11000h PDE 2M
|
||||
;* 11000h - 12000h PDE 2M
|
||||
;* 12000h - 13000h PDE 2M
|
||||
;* 13000h - 14000h PTE 4K
|
||||
;* 14000h - 9F000h core stacks (1k per core)
|
||||
;*
|
||||
;* At first big enough free hole, initrd. Usually at 1Mbyte.
|
||||
;*
|
||||
|
@ -2200,7 +2200,7 @@ longmode_init:
|
|||
dec cx
|
||||
jnz @b
|
||||
xor rbx, rbx
|
||||
@@: shl rbx, 10 ; 1k stack for each core
|
||||
@@: shl rbx, 10 ; 1k stack for each core
|
||||
|
||||
; set stack and call _start() in sys/core
|
||||
xor rsp, rsp ;sp = core_num * -1024
|
||||
|
|
|
@ -57,9 +57,10 @@ PROTOCOL_DYNAMIC equ 2
|
|||
PROTOCOL_BIGENDIAN equ 080h
|
||||
|
||||
; loader types, just informational
|
||||
LOADER_BIOS equ 0
|
||||
LOADER_UEFI equ 4
|
||||
LOADER_RPI equ 8
|
||||
LOADER_BIOS equ 0
|
||||
LOADER_UEFI equ 4
|
||||
LOADER_RPI equ 8
|
||||
LOADER_COREBOOT equ 16
|
||||
|
||||
; framebuffer pixel format, only 32 bits supported
|
||||
FB_ARGB equ 0
|
||||
|
|
|
@ -28,7 +28,7 @@ ifneq ($(strip $(wildcard libpayload)),)
|
|||
include $(XCOMPILE)
|
||||
LPGCC = CC="$(GCC_CC_x86_32)" "$(LIBPAYLOAD_DIR)/bin/lpgcc"
|
||||
$(TARGET):
|
||||
$(LPGCC) $(CFLAGS) -o $(TARGET) bootboot.c
|
||||
$(LPGCC) $(CFLAGS) -o $(TARGET) bootboot.c tinflate.c smp.S
|
||||
else
|
||||
# If libpayload is not found, first build libpayload,
|
||||
# then do the make, this time it'll find libpayload
|
||||
|
|
|
@ -3,7 +3,7 @@ BOOTBOOT Coreboot x86_64 Implementáció
|
|||
|
||||
Általános leírásért lásd a [BOOTBOOT Protokoll](https://gitlab.com/bztsrc/bootboot)t.
|
||||
|
||||
Ez [coreboot](https://coreboot.org) payloadként implementálja a BOOTBOOT Protokollt. Jelenleg __FEJLESZTÉS ALATT__.
|
||||
Ez [coreboot](https://coreboot.org) payloadként implementálja a BOOTBOOT Protokollt.
|
||||
A coreboot fordítási környezetben fordítandó.
|
||||
|
||||
Fordítás
|
||||
|
@ -43,6 +43,11 @@ $ make menuconfig
|
|||
alatta a 'Mainboard vendor' legyen '(Emulation)'
|
||||
alatta a 'Mainboard model' legyen 'QEMU x86 i440fx/piix4'
|
||||
válaszd az 'Exit'-t
|
||||
válaszd a 'Devices' menüt
|
||||
válaszd a 'Display' menüt
|
||||
alatta a 'Framebuffer mode' legyen 'Linear "high-resolution" framebuffer'
|
||||
válaszd az 'Exit'-t
|
||||
válaszd az 'Exit'-t
|
||||
válaszd a 'Payload' menüt
|
||||
válaszd az 'Add a Payload' opciót
|
||||
válaszd ki a 'BOOTBOOT'-ot
|
||||
|
@ -50,6 +55,8 @@ $ make menuconfig
|
|||
válaszd az 'Exit'-t
|
||||
válaszd a 'Yes'-t
|
||||
```
|
||||
Fontos, hogy a kijelzőt "linear framebuffer"-re állítsd, mert a BOOTBOOT nem kezeli az elavult, nem portolható VGA szöveges
|
||||
módot. Sajnos a libpayload nem támogatja a futás időben való beállítást.
|
||||
|
||||
### 5. lépés - A coreboot fordítása
|
||||
|
||||
|
@ -59,11 +66,32 @@ $ make
|
|||
|
||||
### 6. lépés - A frissen fordított ROM tesztelése QEMU-n
|
||||
|
||||
Bővebb információért lásd a [coreboot dokumentáció](https://doc.coreboot.org/mainboard/emulation/qemu-i440fx.html)t.
|
||||
Bővebb információért lásd a [coreboot dokumentáció](https://doc.coreboot.org/mainboard/emulation/qemu-i440fx.html)t. Az
|
||||
[images](https://gitlab.com/bztsrc/bootboot/tree/master/images) mappában találsz lefordított coreboot.rom binárist.
|
||||
```sh
|
||||
$ qemu-system-x86_64 -bios $(COREBOOT)/build/coreboot.rom -drive file=$(BOOTBOOT)/images/disk-x86.img,format=raw -serial stdio
|
||||
```
|
||||
|
||||
Initrd hozzáadása a ROM-hoz
|
||||
---------------------------
|
||||
|
||||
Ahhoz, hogy bekerülhessen a ROM-ba, először is generálni kell egy initrd-t. Ez lehet (opcionálisan gzippelt) tar, cpio, stb.
|
||||
archívum. Ugyancsak létrehozható az [mkbootimg](https://gitlab.com/bztsrc/bootboot/tree/master/mkbootimg) alkalmazással is:
|
||||
```sh
|
||||
$ ./mkbootimg myos.json initrd.bin
|
||||
```
|
||||
Ezután a coreboot repójában található `cbfstool` alkalmazással lehet az initrd lemezképet a ROM képhez hozzáadni:
|
||||
```sh
|
||||
$ ./build/util/cbfstool/cbfstool $(COREBOOT)/build/coreboot.rom add -t raw -f $(BOOTBOOT)/initrd.bin -n bootboot/initrd
|
||||
```
|
||||
Ehhez hasonlóan hozzá lehet adni egy alapértelmezett környezeti fájlt is (csak akkor használja, ha a szokásos helyeken nem
|
||||
találta):
|
||||
```sh
|
||||
$ ./build/util/cbfstool/cbfstool $(COREBOOT)/build/coreboot.rom add -t raw -f environment.txt -n bootboot/config
|
||||
```
|
||||
Ez természetesen csak akkor működik, ha a libpayload `CONFIG_LP_CBFS=y` opcióval lett fordítva. Ennek hiányában az initrd
|
||||
egy "INITRD" nevű Flashmap partíción is elhelyezhető (bár az fmaptool és az fmd formátum kezelése nem kicsit pilótavizsgás).
|
||||
|
||||
Gép állapot
|
||||
-----------
|
||||
|
||||
|
@ -81,4 +109,5 @@ Limitációk
|
|||
|
||||
- Mivel védett módban indul, csak az első 4G-nyi RAM-ot képezi le.
|
||||
- A CMOS nvram nem tárol időzónát, ezért mindig GMT+0 kerül a bootboot.timezone-ba.
|
||||
- Coreboot-ban nem lehet felbontást váltani, ezért a "screen=" opciót nem kezeli.
|
||||
- Csak a SHA-XOR-CBC titkosítást ismeri, nincs AES
|
||||
|
|
|
@ -3,7 +3,7 @@ BOOTBOOT Coreboot x86_64 Implementation
|
|||
|
||||
See [BOOTBOOT Protocol](https://gitlab.com/bztsrc/bootboot) for common details.
|
||||
|
||||
Implements the BOOTBOOT Protocol as a [coreboot](https://coreboot.org) payload. Currently __EXPERIMENTAL__.
|
||||
Implements the BOOTBOOT Protocol as a [coreboot](https://coreboot.org) payload.
|
||||
Must be compiled using the coreboot build environment.
|
||||
|
||||
Compilation
|
||||
|
@ -43,6 +43,11 @@ $ make menuconfig
|
|||
Beside 'Mainboard vendor' should be '(Emulation)'
|
||||
Beside 'Mainboard model' should be 'QEMU x86 i440fx/piix4'
|
||||
select 'Exit'
|
||||
select 'Devices' menu
|
||||
select 'Display' menu
|
||||
Beside 'Framebuffer mode' should be 'Linear "high-resolution" framebuffer'
|
||||
select 'Exit'
|
||||
select 'Exit'
|
||||
select 'Payload' menu
|
||||
select 'Add a Payload'
|
||||
choose 'BOOTBOOT'
|
||||
|
@ -50,6 +55,8 @@ $ make menuconfig
|
|||
select 'Exit'
|
||||
select 'Yes'
|
||||
```
|
||||
It is important to set the display to "linear framebuffer", because BOOTBOOT does not handle the legacy, non-portable VGA
|
||||
text mode. Sadly there's no way of configuring this in run-time with libpayload.
|
||||
|
||||
### Step 5 - Build coreboot
|
||||
|
||||
|
@ -59,11 +66,31 @@ $ make
|
|||
|
||||
### Step 6 - Test the newly compiled ROM in QEMU
|
||||
|
||||
For more information, read [coreboot docs](https://doc.coreboot.org/mainboard/emulation/qemu-i440fx.html).
|
||||
For more information, read the [coreboot docs](https://doc.coreboot.org/mainboard/emulation/qemu-i440fx.html). In the
|
||||
[images](https://gitlab.com/bztsrc/bootboot/tree/master/images) directory you can find a precompiled coreboot.rom binary.
|
||||
```sh
|
||||
$ qemu-system-x86_64 -bios $(COREBOOT)/build/coreboot.rom -drive file=$(BOOTBOOT)/images/disk-x86.img,format=raw -serial stdio
|
||||
```
|
||||
|
||||
Adding Initrd to ROM
|
||||
--------------------
|
||||
|
||||
To add an initrd into ROM, first you have to generate one. It can be an (optionally gzipped) tar, cpio, etc. archive. You can
|
||||
also create it using the [mkbootimg](https://gitlab.com/bztsrc/bootboot/tree/master/mkbootimg) utility:
|
||||
```sh
|
||||
$ ./mkbootimg myos.json initrd.bin
|
||||
```
|
||||
Then use the `cbfstool` utility in the coreboot repository to add the initrd image into the ROM image:
|
||||
```sh
|
||||
$ ./build/util/cbfstool/cbfstool $(COREBOOT)/build/coreboot.rom add -t raw -f $(BOOTBOOT)/initrd.bin -n bootboot/initrd
|
||||
```
|
||||
You can add a fallback environment configuration similarily (only used if environment cannot be loaded from the usual places):
|
||||
```sh
|
||||
$ ./build/util/cbfstool/cbfstool $(COREBOOT)/build/coreboot.rom add -t raw -f environment.txt -n bootboot/config
|
||||
```
|
||||
Obviously this can only work if libpayload was compiled with `CONFIG_LP_CBFS=y`. Without you can still place the initrd on
|
||||
a Flashmap partition named "INITRD" (however using the fmaptool and dealing with the fmd format is a rocket science).
|
||||
|
||||
Machine state
|
||||
-------------
|
||||
|
||||
|
@ -80,4 +107,5 @@ Limitations
|
|||
|
||||
- As it boots in protected mode, it only maps the first 4G of RAM.
|
||||
- The CMOS nvram does not store timezone, so always GMT+0 returned in bootboot.timezone.
|
||||
- Coreboot does not provide a way to set screen resolution, so "screen=" config option is skipped.
|
||||
- Only supports SHA-XOR-CBC, no AES
|
||||
|
|
1167
x86_64-cb/bootboot.c
1167
x86_64-cb/bootboot.c
File diff suppressed because it is too large
Load diff
290
x86_64-cb/fs.h
Normal file
290
x86_64-cb/fs.h
Normal file
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
* x86_64-cb/fs.h
|
||||
*
|
||||
* Copyright (C) 2017 - 2020 bzt (bztsrc@gitlab)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the BOOTBOOT Protocol package.
|
||||
* @brief Filesystem drivers for initial ramdisk.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* FS/Z initrd (OS/Z's native file system)
|
||||
*/
|
||||
file_t fsz_initrd(unsigned char *initrd_p, char *kernel)
|
||||
{
|
||||
file_t ret = { NULL, 0 };
|
||||
if(initrd_p==NULL || memcmp(initrd_p + 512,"FS/Z",4) || kernel==NULL){
|
||||
return ret;
|
||||
}
|
||||
unsigned char passphrase[256],chk[32],iv[32];
|
||||
unsigned int i,j,k,l,ss=1<<(*((uint16_t*)(initrd_p+520))+11);
|
||||
unsigned char *ent, *in=(initrd_p+*((uint64_t*)(initrd_p+560))*ss);
|
||||
SHA256_CTX ctx;
|
||||
DBG(" * FS/Z %s\n",kernel);
|
||||
//decrypt initrd
|
||||
if(*((uint32_t*)(initrd_p+708))!=0 && ((initrd_p[518]>>2)&7)!=0) {
|
||||
printf("BOOTBOOT-PANIC: Unsupported cipher\n");
|
||||
return ret;
|
||||
}
|
||||
while(*((uint32_t*)(initrd_p+708))!=0) {
|
||||
printf(" * Passphrase? ");
|
||||
l=ReadLine(passphrase,sizeof(passphrase));
|
||||
if(!l) {
|
||||
printf("\n");
|
||||
return ret;
|
||||
}
|
||||
if(*((uint32_t*)(initrd_p+708))!=crc32_calc((char*)passphrase,l)) {
|
||||
printf("\rBOOTBOOT-ERROR: Bad passphrase\n");
|
||||
continue;
|
||||
}
|
||||
printf("\r * Decrypting...\r");
|
||||
SHA256_Init(&ctx);
|
||||
SHA256_Update(&ctx,passphrase,l);
|
||||
SHA256_Update(&ctx,initrd_p+512,6);
|
||||
SHA256_Final(chk,&ctx);
|
||||
for(i=0;i<28;i++) initrd_p[i+680]^=chk[i];
|
||||
SHA256_Init(&ctx);
|
||||
SHA256_Update(&ctx,initrd_p+680,28);
|
||||
SHA256_Final(iv,&ctx);
|
||||
for(k=ss,j=1;j<*((uint32_t*)(initrd_p+528));j++) {
|
||||
memcpy(chk,iv,32);
|
||||
for(i=0;i<ss;i++) {
|
||||
if(i%32==0) {
|
||||
SHA256_Init(&ctx);
|
||||
SHA256_Update(&ctx,&chk,32);
|
||||
SHA256_Update(&ctx,&j,4);
|
||||
SHA256_Final(chk,&ctx);
|
||||
}
|
||||
initrd_p[k++]^=chk[i%32]^iv[i%32];
|
||||
}
|
||||
}
|
||||
memset(initrd_p+680,0,28+4);
|
||||
*((uint32_t*)(initrd_p+1020))=crc32_calc((char *)initrd_p+512,508);
|
||||
printf(" \r");
|
||||
}
|
||||
// Get the inode
|
||||
char *s,*e;
|
||||
s=e=kernel;
|
||||
i=0;
|
||||
again:
|
||||
while(*e!='/'&&*e!=0){e++;}
|
||||
if(*e=='/'){e++;}
|
||||
if(!memcmp(in,"FSIN",4)){
|
||||
//is it inlined?
|
||||
if(!memcmp(initrd_p[518]&1? in + 2048 : in + 1024,"FSDR",4)){
|
||||
ent=(initrd_p[518]&1? in + 2048 : in + 1024);
|
||||
} else if(!memcmp(initrd_p+*((uint64_t*)(in+448))*ss,"FSDR",4)){
|
||||
// go, get the sector pointed
|
||||
ent=(initrd_p+*((uint64_t*)(in+448))*ss);
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
//skip header
|
||||
unsigned char *hdr=ent; ent+=128;
|
||||
//iterate on directory entries
|
||||
int j=*((uint64_t*)(hdr+16));
|
||||
while(j-->0){
|
||||
if(!memcmp(ent + 17,s,e-s)) {
|
||||
if(*e==0) {
|
||||
i=*((uint64_t*)(ent+0));
|
||||
break;
|
||||
} else {
|
||||
s=e;
|
||||
in=(initrd_p+*((uint64_t*)(ent+0))*ss);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
ent+=128;
|
||||
}
|
||||
} else {
|
||||
i=0;
|
||||
}
|
||||
if(i!=0) {
|
||||
// fid -> inode ptr -> data ptr
|
||||
unsigned char *in=(initrd_p+i*ss);
|
||||
if(!memcmp(in,"FSIN",4)){
|
||||
ret.size=*((uint64_t*)(in+464));
|
||||
switch(in[488]) {
|
||||
case 0xFF:
|
||||
// inline data
|
||||
ret.ptr=(uint8_t*)(initrd_p+i*ss+(initrd_p[518]&1? 2048 : 1024));
|
||||
break;
|
||||
case 0x80:
|
||||
case 0x7F:
|
||||
// sector directory or list inlined
|
||||
ret.ptr=(uint8_t*)(initrd_p + *((uint64_t*)(initrd_p[518]&1? in + 2048 : in + 1024))*ss);
|
||||
break;
|
||||
case 0:
|
||||
// direct data
|
||||
ret.ptr=(uint8_t*)(initrd_p + *((uint64_t*)(in+448)) * ss);
|
||||
break;
|
||||
// sector directory (only one level supported here, and no holes in files)
|
||||
case 0x81:
|
||||
case 1:
|
||||
ret.ptr=(uint8_t*)(initrd_p + *((uint64_t*)(initrd_p + *((uint64_t*)(in+448))*ss)) * ss);
|
||||
break;
|
||||
default:
|
||||
ret.size=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* cpio archive
|
||||
*/
|
||||
file_t cpio_initrd(unsigned char *initrd_p, char *kernel)
|
||||
{
|
||||
unsigned char *ptr=initrd_p;
|
||||
int k;
|
||||
file_t ret = { NULL, 0 };
|
||||
if(initrd_p==NULL || kernel==NULL ||
|
||||
(memcmp(initrd_p,"070701",6) && memcmp(initrd_p,"070702",6) && memcmp(initrd_p,"070707",6)))
|
||||
return ret;
|
||||
DBG(" * cpio %s\n",kernel);
|
||||
k=strlen(kernel);
|
||||
// hpodc archive
|
||||
while(!memcmp(ptr,"070707",6)){
|
||||
int ns=octbin(ptr+8*6+11,6);
|
||||
int fs=octbin(ptr+8*6+11+6,11);
|
||||
if(!memcmp(ptr+9*6+2*11,kernel,k+1) ||
|
||||
(ptr[9*6+2*11] == '.' && ptr[9*6+2*11+1] == '/' && !memcmp(ptr+9*6+2*11+2,kernel,k+1))) {
|
||||
ret.size=fs;
|
||||
ret.ptr=(uint8_t*)(ptr+9*6+2*11+ns);
|
||||
return ret;
|
||||
}
|
||||
ptr+=(76+ns+fs);
|
||||
}
|
||||
// newc and crc archive
|
||||
while(!memcmp(ptr,"07070",5)){
|
||||
int fs=hexbin(ptr+8*6+6,8);
|
||||
int ns=hexbin(ptr+8*11+6,8);
|
||||
if(!memcmp(ptr+110,kernel,k+1) || (ptr[110] == '.' && ptr[111] == '/' && !memcmp(ptr+112,kernel,k+1))) {
|
||||
ret.size=fs;
|
||||
ret.ptr=(uint8_t*)(ptr+((110+ns+3)/4)*4);
|
||||
return ret;
|
||||
}
|
||||
ptr+=((110+ns+3)/4)*4 + ((fs+3)/4)*4;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ustar tarball archive
|
||||
*/
|
||||
file_t tar_initrd(unsigned char *initrd_p, char *kernel)
|
||||
{
|
||||
unsigned char *ptr=initrd_p;
|
||||
int k;
|
||||
file_t ret = { NULL, 0 };
|
||||
if(initrd_p==NULL || kernel==NULL || memcmp(initrd_p+257,"ustar",5))
|
||||
return ret;
|
||||
DBG(" * tar %s\n",kernel);
|
||||
k=strlen(kernel);
|
||||
while(!memcmp(ptr+257,"ustar",5)){
|
||||
int fs=octbin(ptr+0x7c,11);
|
||||
if(!memcmp(ptr,kernel,k+1) || (ptr[0] == '.' && ptr[1] == '/' && !memcmp(ptr+2,kernel,k+1))) {
|
||||
ret.size=fs;
|
||||
ret.ptr=(uint8_t*)(ptr+512);
|
||||
return ret;
|
||||
}
|
||||
ptr+=(((fs+511)/512)+1)*512;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple File System
|
||||
*/
|
||||
file_t sfs_initrd(unsigned char *initrd_p, char *kernel)
|
||||
{
|
||||
unsigned char *ptr, *end;
|
||||
int k,bs,ver;
|
||||
file_t ret = { NULL, 0 };
|
||||
if(initrd_p==NULL || kernel==NULL || (memcmp(initrd_p+0x1AC,"SFS",3) && memcmp(initrd_p+0x1A6,"SFS",3)))
|
||||
return ret;
|
||||
// 1.0 Brendan's version, 1.10 BenLunt's version
|
||||
ver=!memcmp(initrd_p+0x1A6,"SFS",3)?10:0;
|
||||
bs=1<<(7+(uint8_t)initrd_p[ver?0x1B6:0x1BC]);
|
||||
end=initrd_p + *((uint64_t *)&initrd_p[ver?0x1AA:0x1B0]) * bs; // base + total_number_of_blocks * blocksize
|
||||
// get index area
|
||||
ptr=end - *((uint64_t *)&initrd_p[ver?0x19E:0x1A4]); // end - size of index area
|
||||
// got a Starting Marker Entry?
|
||||
if(ptr[0]!=2)
|
||||
return ret;
|
||||
DBG(" * SFS 1.%s %s\n", ver?"10":"0",kernel);
|
||||
k=strlen(kernel);
|
||||
// iterate on index until we reach the end or Volume Identifier
|
||||
while(ptr<end && ptr[0]!=0x01){
|
||||
ptr+=64;
|
||||
// file entry?
|
||||
if(ptr[0]!=0x12)
|
||||
continue;
|
||||
// filename match?
|
||||
if(!memcmp(ptr+(ver?0x23:0x22),kernel,k+1)){
|
||||
ret.size=*((uint64_t*)&ptr[ver?0x1B:0x1A]); // file_length
|
||||
ret.ptr=initrd_p + *((uint64_t*)&ptr[ver?0x0B:0x0A]) * bs; // base + start_block * blocksize
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* James Molloy's initrd (for some reason it's popular among hobby OS developers)
|
||||
* http://www.jamesmolloy.co.uk/tutorial_html
|
||||
*/
|
||||
file_t jamesm_initrd(unsigned char *initrd_p, char *kernel)
|
||||
{
|
||||
unsigned char *ptr=initrd_p+4;
|
||||
int i,k,nf=*((int*)initrd_p);
|
||||
file_t ret = { NULL, 0 };
|
||||
// no real magic, so we assume initrd contains at least one file...
|
||||
if(initrd_p==NULL || kernel==NULL || initrd_p[2]!=0 || initrd_p[3]!=0 || initrd_p[4]!=0xBF)
|
||||
return ret;
|
||||
DBG(" * JamesM %s\n",kernel);
|
||||
k=strlen(kernel);
|
||||
for(i=0;i<nf && ptr[0]==0xBF;i++) {
|
||||
if(!memcmp(ptr+1,kernel,k+1)){
|
||||
ret.ptr=*((uint32_t*)(ptr+65)) + initrd_p;
|
||||
ret.size=*((uint32_t*)(ptr+69));
|
||||
}
|
||||
ptr+=73;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Static file system drivers registry
|
||||
*/
|
||||
file_t (*fsdrivers[]) (unsigned char *, char *) = {
|
||||
fsz_initrd,
|
||||
cpio_initrd,
|
||||
tar_initrd,
|
||||
sfs_initrd,
|
||||
jamesm_initrd,
|
||||
NULL
|
||||
};
|
|
@ -32,9 +32,7 @@ CONFIG_LP_BASE_ADDRESS=0x00100000
|
|||
#
|
||||
CONFIG_LP_LIBC=y
|
||||
# CONFIG_LP_CURSES is not set
|
||||
# CONFIG_LP_TINYCURSES is not set
|
||||
# CONFIG_LP_PDCURSES is not set
|
||||
# CONFIG_LP_CBFS is not set
|
||||
CONFIG_LP_CBFS=y
|
||||
# CONFIG_LP_LZMA is not set
|
||||
# CONFIG_LP_LZ4 is not set
|
||||
|
||||
|
@ -76,8 +74,8 @@ CONFIG_LP_NVRAM=y
|
|||
# CONFIG_LP_MOUSE_CURSOR is not set
|
||||
# CONFIG_LP_RTC_PORT_EXTENDED_VIA is not set
|
||||
# CONFIG_LP_SPEAKER is not set
|
||||
# CONFIG_LP_TIMER_RDTSC is not set
|
||||
CONFIG_LP_TIMER_NONE=y
|
||||
CONFIG_LP_TIMER_RDTSC=y
|
||||
# CONFIG_LP_TIMER_NONE is not set
|
||||
# CONFIG_LP_TIMER_MCT is not set
|
||||
# CONFIG_LP_TIMER_TEGRA_1US is not set
|
||||
# CONFIG_LP_TIMER_IPQ806X is not set
|
||||
|
@ -118,7 +116,7 @@ CONFIG_LP_USB_PCI=y
|
|||
CONFIG_LP_LITTLE_ENDIAN=y
|
||||
CONFIG_LP_IO_ADDRESS_SPACE=y
|
||||
CONFIG_LP_ARCH_SPECIFIC_OPTIONS=y
|
||||
# CONFIG_LP_ENABLE_APIC is not set
|
||||
CONFIG_LP_ENABLE_APIC=y
|
||||
# CONFIG_LP_IGNORE_UNKNOWN_INTERRUPTS is not set
|
||||
# CONFIG_LP_LOG_UNKNOWN_INTERRUPTS is not set
|
||||
CONFIG_LP_DIE_ON_UNKNOWN_INTERRUPT=y
|
||||
|
|
157
x86_64-cb/smp.S
Normal file
157
x86_64-cb/smp.S
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* x86_64-cb/smp.S
|
||||
*
|
||||
* Copyright (C) 2017 - 2020 bzt (bztsrc@gitlab)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the BOOTBOOT Protocol package.
|
||||
* @brief SMP and long mode initialization code.
|
||||
*
|
||||
*/
|
||||
|
||||
.globl ap_trampoline
|
||||
.globl bsp_init
|
||||
.extern lapic_ids
|
||||
|
||||
.text
|
||||
|
||||
/*****************************************************************************
|
||||
* things to do on the APs *
|
||||
*****************************************************************************/
|
||||
.align 128
|
||||
.code16
|
||||
/* this code will be relocated to 0x1000 - 0x1100 */
|
||||
ap_trampoline:
|
||||
cli
|
||||
cld
|
||||
ljmp $0, $0x1040
|
||||
.align 16
|
||||
// prot mode GDT
|
||||
_L1010_GDT_table:
|
||||
.long 0, 0
|
||||
.long 0x0000FFFF, 0x00CF9A00 // flat code
|
||||
.long 0x0000FFFF, 0x008F9200 // flat data
|
||||
.long 0x00000068, 0x00CF8900 // tss, not used but required by VB's vt-x
|
||||
_L1030_GDT_value:
|
||||
.word _L1030_GDT_value - _L1010_GDT_table - 1
|
||||
.long 0x1010
|
||||
.long 0, 0
|
||||
.align 64
|
||||
_L1040:
|
||||
xorw %ax, %ax
|
||||
movw %ax, %ds
|
||||
lgdtl 0x1030
|
||||
movl %cr0, %eax
|
||||
orl $1, %eax
|
||||
movl %eax, %cr0
|
||||
ljmp $8, $0x1060
|
||||
.align 32
|
||||
.code32
|
||||
_L1060:
|
||||
movw $16, %ax
|
||||
movw %ax, %ds
|
||||
// spinlock until BSP finishes
|
||||
1: pause
|
||||
cmpb $0, 0x1010
|
||||
jz 1b
|
||||
// jump back to non-relocated code segment
|
||||
jmp longmode_init
|
||||
.align 128
|
||||
ap_trampoline_end:
|
||||
|
||||
// long mode GDT (here it is aligned and out of execution flow)
|
||||
GDT_table:
|
||||
.long 0, 0
|
||||
.long 0x0000FFFF, 0x00209800 // flat code, ring 0
|
||||
.long 0x0000FFFF, 0x00809200 // flat data
|
||||
.long 0x00000068, 0x00008900 // tss, required by vt-x
|
||||
.long 0, 0
|
||||
GDT_value:
|
||||
.word GDT_value - GDT_table - 1
|
||||
.long GDT_table, 0, 0
|
||||
.word 0
|
||||
|
||||
/*****************************************************************************
|
||||
* things to do on BSP *
|
||||
*****************************************************************************/
|
||||
bsp_init:
|
||||
cli
|
||||
movb $0xFF, %al // disable PIC
|
||||
outb %al, $0x21
|
||||
outb %al, $0xA1
|
||||
inb $0x70, %al // disable NMI
|
||||
orb $0x80, %al
|
||||
outb %al, $0x70
|
||||
incb 0x1010 // release AP spin lock
|
||||
// fall into long mode initialization code
|
||||
|
||||
/*****************************************************************************
|
||||
* common code for all cores, enable long mode and start kernel *
|
||||
*****************************************************************************/
|
||||
longmode_init:
|
||||
movl $0x368, %eax // Set PAE, MCE, PGE; OSFXSR, OSXMMEXCPT (enable SSE)
|
||||
movl %eax, %cr4
|
||||
movl $0x4000, %eax
|
||||
movl %eax, %cr3
|
||||
movl $0x0C0000080, %ecx // EFR MSR
|
||||
rdmsr
|
||||
orl $0x100, %eax // enable long mode
|
||||
wrmsr
|
||||
|
||||
movl $0x0C0000011, %eax // clear EM, MP (enable SSE) and WP
|
||||
movl %eax, %cr0
|
||||
lgdt GDT_value
|
||||
ljmp $8, $bit64
|
||||
.code64
|
||||
bit64:
|
||||
movl $0x10, %eax // load long mode segments
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
// find our lapic id
|
||||
movl $1, %eax
|
||||
cpuid
|
||||
shrl $24, %ebx
|
||||
movl %ebx, %edx
|
||||
// get array index for it
|
||||
xorq %rbx, %rbx
|
||||
xorq %rsi, %rsi
|
||||
movl $lapic_ids, %esi
|
||||
movw 0x200C, %cx // bootboot.numcores
|
||||
1: lodsw
|
||||
cmpw %dx, %ax
|
||||
je 1f
|
||||
incw %bx
|
||||
decw %cx
|
||||
jnz 1b
|
||||
xorw %bx, %bx
|
||||
1: shlq $10, %rbx // 1k stack for each core
|
||||
|
||||
// set stack and call _start() in sys/core
|
||||
xorq %rsp, %rsp // sp = core_num * -1024
|
||||
subq %rbx, %rsp
|
||||
movl $entrypoint, %esi // GAS does not allow "jmp qword[entrypoint]"
|
||||
lodsq
|
||||
jmp *%rax
|
||||
hlt
|
110
x86_64-cb/tinf.h
Normal file
110
x86_64-cb/tinf.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* uzlib - tiny deflate/inflate library (deflate, gzip, zlib)
|
||||
*
|
||||
* Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
* All Rights Reserved
|
||||
* http://www.ibsensoftware.com/
|
||||
*
|
||||
* Copyright (c) 2014-2016 by Paul Sokolovsky
|
||||
*/
|
||||
|
||||
#ifndef TINF_H_INCLUDED
|
||||
#define TINF_H_INCLUDED
|
||||
|
||||
/* calling convention */
|
||||
#ifndef TINFCC
|
||||
#ifdef __WATCOMC__
|
||||
#define TINFCC __cdecl
|
||||
#else
|
||||
#define TINFCC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ok status, more data produced */
|
||||
#define TINF_OK 0
|
||||
/* end of compressed stream reached */
|
||||
#define TINF_DONE 1
|
||||
#define TINF_DATA_ERROR (-3)
|
||||
#define TINF_CHKSUM_ERROR (-4)
|
||||
#define TINF_DICT_ERROR (-5)
|
||||
|
||||
/* checksum types */
|
||||
#define TINF_CHKSUM_NONE 0
|
||||
#define TINF_CHKSUM_ADLER 1
|
||||
#define TINF_CHKSUM_CRC 2
|
||||
|
||||
/* data structures */
|
||||
|
||||
typedef struct {
|
||||
unsigned int table[16]; /* table of code length counts */
|
||||
unsigned int trans[288]; /* code -> symbol translation table */
|
||||
} TINF_TREE;
|
||||
|
||||
struct TINF_DATA;
|
||||
typedef struct TINF_DATA {
|
||||
TINF_TREE ltree; /* dynamic length/symbol tree */
|
||||
TINF_TREE dtree; /* dynamic distance tree */
|
||||
const unsigned char *source;
|
||||
/* If source above is NULL, this function will be used to read
|
||||
next byte from source stream */
|
||||
unsigned char (*readSource)(volatile struct TINF_DATA *data);
|
||||
|
||||
unsigned int tag;
|
||||
unsigned int bitcount;
|
||||
|
||||
/* Buffer start */
|
||||
unsigned char *destStart;
|
||||
/* Buffer total size */
|
||||
unsigned int destSize;
|
||||
/* Current pointer in buffer */
|
||||
unsigned char *dest;
|
||||
/* Remaining bytes in buffer */
|
||||
unsigned int destRemaining;
|
||||
|
||||
/* Accumulating checksum */
|
||||
unsigned int checksum;
|
||||
unsigned int checksum_type;
|
||||
|
||||
int btype;
|
||||
int bfinal;
|
||||
unsigned int curlen;
|
||||
int lzOff;
|
||||
} TINF_DATA;
|
||||
|
||||
#define TINF_PUT(d, c) \
|
||||
{ \
|
||||
*d->dest++ = c; \
|
||||
}
|
||||
|
||||
unsigned char TINFCC uzlib_get_byte(volatile TINF_DATA *d);
|
||||
|
||||
/* Decompression API */
|
||||
|
||||
void TINFCC uzlib_init(void);
|
||||
void TINFCC uzlib_uncompress_init(TINF_DATA *d, void *dict, unsigned int dictLen);
|
||||
int TINFCC uzlib_uncompress(volatile TINF_DATA *d);
|
||||
int TINFCC uzlib_uncompress_chksum(TINF_DATA *d);
|
||||
|
||||
int TINFCC uzlib_zlib_parse_header(TINF_DATA *d);
|
||||
int TINFCC uzlib_gzip_parse_header(TINF_DATA *d);
|
||||
|
||||
/* Compression API */
|
||||
|
||||
void TINFCC uzlib_compress(void *data, const uint8_t *src, unsigned slen);
|
||||
|
||||
/* Checksum API */
|
||||
|
||||
/* prev_sum is previous value for incremental computation, 1 initially */
|
||||
uint32_t TINFCC uzlib_adler32(const void *data, unsigned int length, uint32_t prev_sum);
|
||||
/* crc is previous value for incremental computation, 0xffffffff initially */
|
||||
uint32_t TINFCC uzlib_crc32(const void *data, unsigned int length, uint32_t crc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* TINF_H_INCLUDED */
|
477
x86_64-cb/tinflate.c
Normal file
477
x86_64-cb/tinflate.c
Normal file
|
@ -0,0 +1,477 @@
|
|||
/*
|
||||
* tinflate - tiny inflate
|
||||
*
|
||||
* Copyright (c) 2003 by Joergen Ibsen / Jibz
|
||||
* All Rights Reserved
|
||||
* http://www.ibsensoftware.com/
|
||||
*
|
||||
* Copyright (c) 2014-2016 by Paul Sokolovsky
|
||||
*
|
||||
* This software is provided 'as-is', without any express
|
||||
* or implied warranty. In no event will the authors be
|
||||
* held liable for any damages arising from the use of
|
||||
* this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software
|
||||
* for any purpose, including commercial applications,
|
||||
* and to alter it and redistribute it freely, subject to
|
||||
* the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be
|
||||
* misrepresented; you must not claim that you
|
||||
* wrote the original software. If you use this
|
||||
* software in a product, an acknowledgment in
|
||||
* the product documentation would be appreciated
|
||||
* but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked
|
||||
* as such, and must not be misrepresented as
|
||||
* being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from
|
||||
* any source distribution.
|
||||
*/
|
||||
|
||||
#include <libpayload-config.h>
|
||||
#include <libpayload.h>
|
||||
#include "tinf.h"
|
||||
|
||||
uint32_t tinf_get_le_uint32(TINF_DATA *d);
|
||||
uint32_t tinf_get_be_uint32(TINF_DATA *d);
|
||||
|
||||
/* --------------------------------------------------- *
|
||||
* -- uninitialized global data (static structures) -- *
|
||||
* --------------------------------------------------- */
|
||||
|
||||
#ifdef RUNTIME_BITS_TABLES
|
||||
|
||||
/* extra bits and base tables for length codes */
|
||||
unsigned char length_bits[30];
|
||||
unsigned short length_base[30];
|
||||
|
||||
/* extra bits and base tables for distance codes */
|
||||
unsigned char dist_bits[30];
|
||||
unsigned short dist_base[30];
|
||||
|
||||
#else
|
||||
|
||||
const unsigned char length_bits[30] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 4, 4, 4, 4,
|
||||
5, 5, 5, 5
|
||||
};
|
||||
const unsigned short length_base[30] = {
|
||||
3, 4, 5, 6, 7, 8, 9, 10,
|
||||
11, 13, 15, 17, 19, 23, 27, 31,
|
||||
35, 43, 51, 59, 67, 83, 99, 115,
|
||||
131, 163, 195, 227, 258
|
||||
};
|
||||
|
||||
const unsigned char dist_bits[30] = {
|
||||
0, 0, 0, 0, 1, 1, 2, 2,
|
||||
3, 3, 4, 4, 5, 5, 6, 6,
|
||||
7, 7, 8, 8, 9, 9, 10, 10,
|
||||
11, 11, 12, 12, 13, 13
|
||||
};
|
||||
const unsigned short dist_base[30] = {
|
||||
1, 2, 3, 4, 5, 7, 9, 13,
|
||||
17, 25, 33, 49, 65, 97, 129, 193,
|
||||
257, 385, 513, 769, 1025, 1537, 2049, 3073,
|
||||
4097, 6145, 8193, 12289, 16385, 24577
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* special ordering of code length codes */
|
||||
const unsigned char clcidx[] = {
|
||||
16, 17, 18, 0, 8, 7, 9, 6,
|
||||
10, 5, 11, 4, 12, 3, 13, 2,
|
||||
14, 1, 15
|
||||
};
|
||||
|
||||
/* ----------------------- *
|
||||
* -- utility functions -- *
|
||||
* ----------------------- */
|
||||
|
||||
#ifdef RUNTIME_BITS_TABLES
|
||||
/* build extra bits and base tables */
|
||||
static void tinf_build_bits_base(unsigned char *bits, unsigned short *base, int delta, int first)
|
||||
{
|
||||
int i, sum;
|
||||
|
||||
/* build bits table */
|
||||
for (i = 0; i < delta; ++i) bits[i] = 0;
|
||||
for (i = 0; i < 30 - delta; ++i) bits[i + delta] = i / delta;
|
||||
|
||||
/* build base table */
|
||||
for (sum = first, i = 0; i < 30; ++i)
|
||||
{
|
||||
base[i] = sum;
|
||||
sum += 1 << bits[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* build the fixed huffman trees */
|
||||
static void tinf_build_fixed_trees(volatile TINF_TREE *lt, volatile TINF_TREE *dt)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* build fixed length tree */
|
||||
for (i = 0; i < 7; ++i) lt->table[i] = 0;
|
||||
|
||||
lt->table[7] = 24;
|
||||
lt->table[8] = 152;
|
||||
lt->table[9] = 112;
|
||||
|
||||
for (i = 0; i < 24; ++i) lt->trans[i] = 256 + i;
|
||||
for (i = 0; i < 144; ++i) lt->trans[24 + i] = i;
|
||||
for (i = 0; i < 8; ++i) lt->trans[24 + 144 + i] = 280 + i;
|
||||
for (i = 0; i < 112; ++i) lt->trans[24 + 144 + 8 + i] = 144 + i;
|
||||
|
||||
/* build fixed distance tree */
|
||||
for (i = 0; i < 5; ++i) dt->table[i] = 0;
|
||||
|
||||
dt->table[5] = 32;
|
||||
|
||||
for (i = 0; i < 32; ++i) dt->trans[i] = i;
|
||||
}
|
||||
|
||||
/* given an array of code lengths, build a tree */
|
||||
static void tinf_build_tree(volatile TINF_TREE *t, const unsigned char *lengths, unsigned int num)
|
||||
{
|
||||
unsigned short offs[16];
|
||||
unsigned int i, sum;
|
||||
|
||||
/* clear code length count table */
|
||||
for (i = 0; i < 16; ++i) t->table[i] = 0;
|
||||
|
||||
/* scan symbol lengths, and sum code length counts */
|
||||
for (i = 0; i < num; ++i) t->table[lengths[i]]++;
|
||||
|
||||
t->table[0] = 0;
|
||||
|
||||
/* compute offset table for distribution sort */
|
||||
for (sum = 0, i = 0; i < 16; ++i)
|
||||
{
|
||||
offs[i] = sum;
|
||||
sum += t->table[i];
|
||||
}
|
||||
|
||||
/* create code->symbol translation table (symbols sorted by code) */
|
||||
for (i = 0; i < num; ++i)
|
||||
{
|
||||
if (lengths[i]) t->trans[offs[lengths[i]]++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------- *
|
||||
* -- decode functions -- *
|
||||
* ---------------------- */
|
||||
|
||||
unsigned char uzlib_get_byte(volatile TINF_DATA *d)
|
||||
{
|
||||
if (d->source) {
|
||||
return *d->source++;
|
||||
}
|
||||
return d->readSource(d);
|
||||
}
|
||||
|
||||
uint32_t tinf_get_le_uint32(TINF_DATA *d)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
int i;
|
||||
for (i = 4; i--;) {
|
||||
val = val >> 8 | uzlib_get_byte(d) << 24;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
uint32_t tinf_get_be_uint32(TINF_DATA *d)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
int i;
|
||||
for (i = 4; i--;) {
|
||||
val = val << 8 | uzlib_get_byte(d);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/* get one bit from source stream */
|
||||
static int tinf_getbit(volatile TINF_DATA *d)
|
||||
{
|
||||
unsigned int bit;
|
||||
|
||||
/* check if tag is empty */
|
||||
if (!d->bitcount--)
|
||||
{
|
||||
/* load next tag */
|
||||
d->tag = uzlib_get_byte(d);
|
||||
d->bitcount = 7;
|
||||
}
|
||||
|
||||
/* shift bit out of tag */
|
||||
bit = d->tag & 0x01;
|
||||
d->tag >>= 1;
|
||||
|
||||
return bit;
|
||||
}
|
||||
|
||||
/* read a num bit value from a stream and add base */
|
||||
static unsigned int tinf_read_bits(volatile TINF_DATA *d, int num, int base)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
|
||||
/* read num bits */
|
||||
if (num)
|
||||
{
|
||||
unsigned int limit = 1 << (num);
|
||||
unsigned int mask;
|
||||
|
||||
for (mask = 1; mask < limit; mask *= 2)
|
||||
if (tinf_getbit(d)) val += mask;
|
||||
}
|
||||
|
||||
return val + base;
|
||||
}
|
||||
|
||||
/* given a data stream and a tree, decode a symbol */
|
||||
static int tinf_decode_symbol(volatile TINF_DATA *d, volatile TINF_TREE *t)
|
||||
{
|
||||
int sum = 0, cur = 0, len = 0;
|
||||
|
||||
/* get more bits while code value is above sum */
|
||||
do {
|
||||
|
||||
cur = 2*cur + tinf_getbit(d);
|
||||
|
||||
++len;
|
||||
|
||||
sum += t->table[len];
|
||||
cur -= t->table[len];
|
||||
|
||||
} while (cur >= 0);
|
||||
|
||||
return t->trans[sum + cur];
|
||||
}
|
||||
|
||||
/* given a data stream, decode dynamic trees from it */
|
||||
static void tinf_decode_trees(volatile TINF_DATA *d, volatile TINF_TREE *lt, volatile TINF_TREE *dt)
|
||||
{
|
||||
unsigned char lengths[288+32];
|
||||
unsigned int hlit, hdist, hclen;
|
||||
unsigned int i, num, length;
|
||||
|
||||
/* get 5 bits HLIT (257-286) */
|
||||
hlit = tinf_read_bits(d, 5, 257);
|
||||
|
||||
/* get 5 bits HDIST (1-32) */
|
||||
hdist = tinf_read_bits(d, 5, 1);
|
||||
|
||||
/* get 4 bits HCLEN (4-19) */
|
||||
hclen = tinf_read_bits(d, 4, 4);
|
||||
|
||||
for (i = 0; i < 19; ++i) lengths[i] = 0;
|
||||
|
||||
/* read code lengths for code length alphabet */
|
||||
for (i = 0; i < hclen; ++i)
|
||||
{
|
||||
/* get 3 bits code length (0-7) */
|
||||
unsigned int clen = tinf_read_bits(d, 3, 0);
|
||||
|
||||
lengths[clcidx[i]] = clen;
|
||||
}
|
||||
|
||||
/* build code length tree, temporarily use length tree */
|
||||
tinf_build_tree(lt, lengths, 19);
|
||||
|
||||
/* decode code lengths for the dynamic trees */
|
||||
for (num = 0; num < hlit + hdist; )
|
||||
{
|
||||
int sym = tinf_decode_symbol(d, lt);
|
||||
|
||||
switch (sym)
|
||||
{
|
||||
case 16:
|
||||
/* copy previous code length 3-6 times (read 2 bits) */
|
||||
{
|
||||
unsigned char prev = lengths[num - 1];
|
||||
for (length = tinf_read_bits(d, 2, 3); length; --length)
|
||||
{
|
||||
lengths[num++] = prev;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 17:
|
||||
/* repeat code length 0 for 3-10 times (read 3 bits) */
|
||||
for (length = tinf_read_bits(d, 3, 3); length; --length)
|
||||
{
|
||||
lengths[num++] = 0;
|
||||
}
|
||||
break;
|
||||
case 18:
|
||||
/* repeat code length 0 for 11-138 times (read 7 bits) */
|
||||
for (length = tinf_read_bits(d, 7, 11); length; --length)
|
||||
{
|
||||
lengths[num++] = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* values 0-15 represent the actual code lengths */
|
||||
lengths[num++] = sym;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* build dynamic trees */
|
||||
tinf_build_tree(lt, lengths, hlit);
|
||||
tinf_build_tree(dt, lengths + hlit, hdist);
|
||||
}
|
||||
|
||||
/* ----------------------------- *
|
||||
* -- block inflate functions -- *
|
||||
* ----------------------------- */
|
||||
|
||||
/* given a stream and two trees, inflate a block of data */
|
||||
static int tinf_inflate_block_data(volatile TINF_DATA *d, volatile TINF_TREE *lt, volatile TINF_TREE *dt)
|
||||
{
|
||||
if (d->curlen == 0) {
|
||||
unsigned int offs;
|
||||
int dist;
|
||||
int sym = tinf_decode_symbol(d, lt);
|
||||
//printf("huff sym: %02x\n", sym);
|
||||
|
||||
/* literal byte */
|
||||
if (sym < 256) {
|
||||
TINF_PUT(d, sym);
|
||||
return TINF_OK;
|
||||
}
|
||||
|
||||
/* end of block */
|
||||
if (sym == 256) {
|
||||
return TINF_DONE;
|
||||
}
|
||||
|
||||
/* substring from sliding dictionary */
|
||||
sym -= 257;
|
||||
/* possibly get more bits from length code */
|
||||
d->curlen = tinf_read_bits(d, length_bits[sym], length_base[sym]);
|
||||
|
||||
dist = tinf_decode_symbol(d, dt);
|
||||
/* possibly get more bits from distance code */
|
||||
offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]);
|
||||
d->lzOff = -offs;
|
||||
}
|
||||
|
||||
/* copy next byte from dict substring */
|
||||
d->dest[0] = d->dest[d->lzOff];
|
||||
d->dest++;
|
||||
d->curlen--;
|
||||
return TINF_OK;
|
||||
}
|
||||
|
||||
/* inflate an uncompressed block of data */
|
||||
static int tinf_inflate_uncompressed_block(volatile TINF_DATA *d)
|
||||
{
|
||||
if (d->curlen == 0) {
|
||||
unsigned int length, invlength;
|
||||
|
||||
/* get length */
|
||||
length = uzlib_get_byte(d) + 256 * uzlib_get_byte(d);
|
||||
/* get one's complement of length */
|
||||
invlength = uzlib_get_byte(d) + 256 * uzlib_get_byte(d);
|
||||
/* check length */
|
||||
if (length != (~invlength & 0x0000ffff)) return TINF_DATA_ERROR;
|
||||
|
||||
/* increment length to properly return TINF_DONE below, without
|
||||
producing data at the same time */
|
||||
d->curlen = length + 1;
|
||||
|
||||
/* make sure we start next block on a byte boundary */
|
||||
d->bitcount = 0;
|
||||
}
|
||||
|
||||
if (--d->curlen == 0) {
|
||||
return TINF_DONE;
|
||||
}
|
||||
|
||||
unsigned char c = uzlib_get_byte(d);
|
||||
TINF_PUT(d, c);
|
||||
return TINF_OK;
|
||||
}
|
||||
|
||||
/* ---------------------- *
|
||||
* -- public functions -- *
|
||||
* ---------------------- */
|
||||
|
||||
/* initialize global (static) data */
|
||||
void uzlib_init(void)
|
||||
{
|
||||
#ifdef RUNTIME_BITS_TABLES
|
||||
/* build extra bits and base tables */
|
||||
tinf_build_bits_base(length_bits, length_base, 4, 3);
|
||||
tinf_build_bits_base(dist_bits, dist_base, 2, 1);
|
||||
|
||||
/* fix a special case */
|
||||
length_bits[28] = 0;
|
||||
length_base[28] = 258;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* inflate next byte of compressed stream */
|
||||
int uzlib_uncompress(volatile TINF_DATA *d)
|
||||
{
|
||||
do {
|
||||
int res;
|
||||
|
||||
/* start a new block */
|
||||
if (d->btype == -1) {
|
||||
next_blk:
|
||||
/* read final block flag */
|
||||
d->bfinal = tinf_getbit(d);
|
||||
/* read block type (2 bits) */
|
||||
d->btype = tinf_read_bits(d, 2, 0);
|
||||
|
||||
//printf("Started new block: type=%d final=%d\n", d->btype, d->bfinal);
|
||||
|
||||
if (d->btype == 1) {
|
||||
/* build fixed huffman trees */
|
||||
tinf_build_fixed_trees(&d->ltree, &d->dtree);
|
||||
} else if (d->btype == 2) {
|
||||
/* decode trees from stream */
|
||||
tinf_decode_trees(d, &d->ltree, &d->dtree);
|
||||
}
|
||||
}
|
||||
|
||||
/* process current block */
|
||||
switch (d->btype)
|
||||
{
|
||||
case 0:
|
||||
/* decompress uncompressed block */
|
||||
res = tinf_inflate_uncompressed_block(d);
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
/* decompress block with fixed/dyanamic huffman trees */
|
||||
/* trees were decoded previously, so it's the same routine for both */
|
||||
res = tinf_inflate_block_data(d, &d->ltree, &d->dtree);
|
||||
break;
|
||||
default:
|
||||
return TINF_DATA_ERROR;
|
||||
}
|
||||
|
||||
if (res == TINF_DONE && !d->bfinal) {
|
||||
/* the block has ended (without producing more data), but we
|
||||
can't return without data, so start procesing next block */
|
||||
goto next_blk;
|
||||
}
|
||||
|
||||
if (res != TINF_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
} while (--d->destSize);
|
||||
|
||||
return TINF_OK;
|
||||
}
|
|
@ -1083,7 +1083,7 @@ GetLFB()
|
|||
nativeMode = selectedMode;
|
||||
}
|
||||
// get framebuffer properties
|
||||
bootboot->fb_ptr=(void*)gop->Mode->FrameBufferBase;
|
||||
bootboot->fb_ptr=(uint64_t)gop->Mode->FrameBufferBase;
|
||||
bootboot->fb_size=gop->Mode->FrameBufferSize;
|
||||
bootboot->fb_scanline=4*gop->Mode->Info->PixelsPerScanLine;
|
||||
bootboot->fb_width=gop->Mode->Info->HorizontalResolution;
|
||||
|
@ -1744,7 +1744,7 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
if (paging == NULL) {
|
||||
return report(EFI_OUT_OF_RESOURCES,L"AllocatePages");
|
||||
}
|
||||
ZeroMem((void*)paging,37*PAGESIZE);
|
||||
ZeroMem((void*)paging,(37+(bootboot->numcores+3)/4)*PAGESIZE);
|
||||
DBG(L" * Pagetables PML4 @%lx\n",paging);
|
||||
//PML4
|
||||
paging[0]=(UINT64)((UINT8 *)paging+PAGESIZE)+3; // pointer to 2M PDPE (16G RAM identity mapped)
|
||||
|
@ -1766,7 +1766,7 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
//4k PDE
|
||||
j = (fb_addr>>(9+12)) & 0x1FF;
|
||||
for(i=0;j+i<511 && i<63;i++)
|
||||
paging[22*512+j+i]=(UINT64)(((UINT8 *)(bootboot->fb_ptr)+(i<<21))+0x83); // map framebuffer
|
||||
paging[22*512+j+i]=(UINT64)((bootboot->fb_ptr+(i<<21))+0x83); // map framebuffer
|
||||
paging[22*512+511]=(UINT64)((UINT8 *)paging+23*PAGESIZE+3);
|
||||
//4k PT
|
||||
//dynamically map these. Main struct, environment string and code segment
|
||||
|
@ -1844,7 +1844,7 @@ get_memory_map:
|
|||
for(j=y=0;y<bootboot->fb_height;y++) {
|
||||
i=j;
|
||||
for(x=0;x<bootboot->fb_width;x+=2,i+=8)
|
||||
*((uint64_t*)((uint64_t)bootboot->fb_ptr + i))=0;
|
||||
*((uint64_t*)(bootboot->fb_ptr + i))=0;
|
||||
j+=bootboot->fb_scanline;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue