mirror of
https://gitlab.com/bztsrc/bootboot.git
synced 2023-02-13 20:54:32 -05:00
Added protocol level 2 to reference implementations
This commit is contained in:
parent
69ae4d7f22
commit
3fa776a803
24 changed files with 386 additions and 215 deletions
48
OLVASSEL.md
48
OLVASSEL.md
|
|
@ -5,19 +5,19 @@ Előre lefordított binárisok mellékelve, egyből használhatók.
|
|||
|
||||
1. *x86_64-efi* a preferált indítási mód x86_64-en.
|
||||
Szabvány GNU eszköztár plusz néhány fájl a gnuefi-ből (mellékelve).
|
||||
[bootboot.efi](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.efi) (94k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.rom) (94k)
|
||||
[bootboot.efi](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.efi) (95k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.rom) (96k)
|
||||
|
||||
2. *x86_64-bios* BIOS, Multiboot (GRUB), El Torito (CDROM), bővítő ROM és Linux boot kompatíbilis, RÉGI betöltő.
|
||||
Ha újra akarod fordítani, szükséged lesz a fasm-ra (nincs mellékelve).
|
||||
[boot.bin](https://gitlab.com/bztsrc/bootboot/raw/master/boot.bin) (512 bájt, egyszerre MBR, VBR és CDROM indító szektor), [bootboot.bin](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.bin) (11k, a boot.bin tölti be, valamint BBS bővítő ROM és Multiboot kompatíbilis is)
|
||||
|
||||
3. *aarch64-rpi* ARMv8 betöltő Raspberry Pi 3-hoz, 4-hez
|
||||
[bootboot.img](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.img) (32k)
|
||||
[bootboot.img](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.img) (34k)
|
||||
|
||||
4. *mykernel* egy példa BOOTBOOT [kompatíbilis kernel](https://gitlab.com/bztsrc/bootboot/tree/master/mykernel) C-ben írva, ami vonalakat húz meg színes dobozokat rajzol
|
||||
|
||||
Vedd figyelembe, hogy a referencia implementációk nem támogatják a teljes 2-es protokollt (kivéve az UEFI változatot),
|
||||
csak statikus memórialeképezéseket kezelnek, ami az 1-es protokoll szintnek felel meg.
|
||||
Vedd figyelembe, hogy nem minden referencia implementáció támogatja a teljes 2-es protokollt, az x86_64-bios csak statikus
|
||||
memórialeképezéseket kezel, ami az 1-es protokoll szintnek felel meg.
|
||||
|
||||
Gyors kipróbáláshoz találsz bootolható képfájlokat az [images](https://gitlab.com/bztsrc/bootboot/tree/master/images) mappában.
|
||||
|
||||
|
|
@ -48,6 +48,12 @@ Megjegyzés: a BOOTBOOT nem egy boot menedzser, hanem egy boot protokoll. Ha int
|
|||
azt a BOOTBOOT kompatíbilis betöltő *elé* kell integrálnod. Például a GRUB lánctöltheti a boot.bin-t (vagy Multiboot
|
||||
"kernel"-ként a bootboot.bin-t és modulként a memórialemezt) vagy a bootboot.efi hozzáadható az UEFI Boot menedzser menüjéhez.
|
||||
|
||||
Támogasd a fejlesztést adománnyal
|
||||
---------------------------------
|
||||
|
||||
Ha tetszik, vagy hasznosnak találod, szívesen fogadok akármekkora adományt:<br>
|
||||
<a href="bitcoin:3G9vcV91S19fHMoBcmSksUpaxGPR5MUGCk"><img src="https://gitlab.com/bztsrc/bootboot/raw/master/donate.png"><br>BTC 3G9vcV91S19fHMoBcmSksUpaxGPR5MUGCk</a>
|
||||
|
||||
Licensz
|
||||
-------
|
||||
|
||||
|
|
@ -123,7 +129,7 @@ Betöltés menete
|
|||
---------------
|
||||
|
||||
1. a förmver megkeresi a betöltőt, betölti és elindítja.
|
||||
2. a betöltő inicializálja a hardvert (64 bites mód, képernyőfelbontás, memória térkép stb.)
|
||||
2. a betöltő inicializálja a hardvert (64 bites többmagos mód, képernyőfelbontás, memória térkép stb.)
|
||||
3. aztán betölti a környezeti fájlt és az initrd-t (valószínűleg a boot partícióról vagy ROM-ból).
|
||||
4. sorra meghívja a fájl rendszer meghajtókat, hogy betöltse a kernelt az initrd-ről.
|
||||
5. ha egyik meghajtó sem járt szerencsével, akkor megkeresi az első futtathatót az initrd-ben.
|
||||
|
|
@ -152,12 +158,12 @@ a 2-es szintű betöltők a futtatható által definiált szimbólumokat haszná
|
|||
|
||||
A RAM (egészen 16G-ig) egy-az-egyben le van képezve a pozitív címtartományban. A soros vonali konzol 115200 baudra,
|
||||
8 adatbittel, paritás nélkül és 1 stopbitre van felkonfigurálva. Megszakítások le vannak tiltva, a kód pedig felügyeleti
|
||||
szinten (0-ás gyűrű / EL1) fut.
|
||||
szinten (0-ás gyűrűn / EL1-n) fut.
|
||||
|
||||
A képernyű megfelelő felbontásra van állítva 32 bites picelekkel, az `fb` szimbólum által jelölt, negatív címre leképezve.
|
||||
A képernyű megfelelő felbontásra van állítva 32 bites pixelekkel, az `fb` szimbólum által jelölt, negatív címre leképezve.
|
||||
Az 1-es szintű betöltők korlátozzák a képernyő méretét valahol 4096 x 4096 pixelnél (függ a szkensortól és a képaránytól is).
|
||||
Ez több, mint elég az [Ultra HD 4K](https://en.wikipedia.org/wiki/4K_resolution) (3840 x 2160) felbontáshoz. A 2-es szintű
|
||||
betöltők akárhoz képesek kezelni az fb szimbólumot, ezért rájuk nem vonatkozik ez a megszorítás.
|
||||
betöltők akárhova képesek leképezni az fb szimbólumot -1G és -2M között, ezért rájuk nem vonatkozik ez a megszorítás.
|
||||
|
||||
A fő információs [bootboot struktúra](https://gitlab.com/bztsrc/bootboot/blob/master/bootboot.h) a `bootboot` szimbólumra
|
||||
van leképezve. Ez áll egy fix 128 bájtos fejlécből, amit egy változó hosszúságú, de fix méretű rekordok követnek. Az initrd
|
||||
|
|
@ -165,12 +171,13 @@ van leképezve. Ez áll egy fix 128 bájtos fejlécből, amit egy változó hoss
|
|||
*initrd_size* mezői mutatnak rá. A framebuffer fizikai címe az *fb_ptr* mezőben található. Az *indulási rendszer idő* és
|
||||
a platform független *memóriatérkép* szintén itt található.
|
||||
|
||||
A konfigurációs sztring (vagy parancssor, ha úgy tetszik) az `environment` szimbólumra van leképezve.
|
||||
A konfigurációs sztring (vagy parancssor, "command line" ha úgy tetszik) az `environment` szimbólumra van leképezve.
|
||||
|
||||
A kernel kód szegmense az ELF fejléc `p_vaddr` vagy a PE fejléc `code_base` mezői alapján kerülnek leképezésre (csak 2-es
|
||||
szint). Az 1-es szintű betöltők mindig -2M-re töltik a kernelt, ezzel limitálva a teljes méretét 2M-re, beleértve a
|
||||
konfigurációt, adatot, inicializálatlan adatterületet és a vermet. Ennek több, mint elégnek kell lennie bármilyen mikrokernel
|
||||
számára. Az inicialiyálatlan adatterület a text szegmens után jön, felfelé növekszik, és a betöltő kinullázza.
|
||||
konfigurációt, adatot, inicializálatlan adatterületet és a vermet. A 2. szint limitje 16M az adat, kód és bss szegmensre.
|
||||
Ennek több, mint elégnek kell lennie bármilyen mikrokernel számára. Az inicializálatlan adatterület a text szegmens után jön,
|
||||
felfelé növekszik, és a betöltő kinullázza.
|
||||
|
||||
A társprocesszor (lebegőpontos számtás) be van kapcsolva, és ha a Szimmetrikus Többmagos Feldolgozás (SMP) támogatott, akkor
|
||||
minden CPU mag ugyanazt a kernel kódot hajtja végre egyszerre.
|
||||
|
|
@ -411,7 +418,14 @@ BOOTBOOT-PANIC: Kernel is not a valid executable
|
|||
A megadott kernel fájlt megtalálta ugyan az initrd-n valamelyik fájl rendszer meghajtó, de az nem ELF64 se PE32+ formátumú,
|
||||
vagy nem az adott architáktúrára van fordítva, vagy nincs benne betölthető szegmens definíció a negatív címtartományban
|
||||
megadva (lásd linker szkript). Ezt a hibát a 2-es szintű betöltők is kiírhatják, ha az `mmio`, `fb`, `bootboot` vagy
|
||||
`environment` szimbólumok címei nincsenek a negatív címtartományban.
|
||||
`environment` szimbólumok címei nincsenek a negatív címtartományban (-1G és 0 között), vagy nincsenek lapcímhatárra igazítva.
|
||||
Az x86_64-en az fb szimbólumnak, míg AArch64-on az mmio szimbólumnak 2M igazítottnak is kell lennie.
|
||||
|
||||
```
|
||||
BOOTBOOT-PANIC: Kernel is too big
|
||||
```
|
||||
|
||||
A kernel nagyobb, 16 megabájt.
|
||||
|
||||
```
|
||||
BOOTBOOT-PANIC: GOP failed, no framebuffer
|
||||
|
|
@ -428,14 +442,16 @@ BOOTBOOT-PANIC: Unsupported cipher
|
|||
```
|
||||
|
||||
Ezt akkor írja ki, ha az initrd olyan titkosítást használ, amit a betöltő nem ismer. Megoldás: újra kell generálni az
|
||||
initrd-t SHA-XOR-CBC-vel, amit minden betöltő implementációnak támogatnia kell (megjegyzés: a titikosítás csak FS/Z
|
||||
esetén támogatott).
|
||||
initrd-t SHA-XOR-CBC-vel, amit minden betöltő implementációnak támogatnia kell (megjegyzés: a titkosítás csak FS/Z
|
||||
lemezkép esetén támogatott).
|
||||
|
||||
Ez minden, remélem hasznososnak találod!
|
||||
|
||||
Hozzájárulások
|
||||
--------------
|
||||
|
||||
Szeretnék külön köszönetet mondani [Valentin Anger](https://gitlab.com/SyrupThinker)-nek, amiért alaposan letesztelte a
|
||||
kódot számtalan igazi vason is.
|
||||
Szeretnék külön köszönetet mondani [Valentin Anger](https://gitlab.com/SyrupThinker)nek, amiért alaposan letesztelte a
|
||||
kódot számtalan igazi vason is. Továbbá [Vinay Chandrá](https://gitlab.com/vinaychandra)nak, amiért addig nem hagyott
|
||||
békén, míg a 2. szintű protokoll be nem került a refenrencia implementációkba, és amiért tesztelte és kiegészítette
|
||||
Rust minta kernellel a projektet.
|
||||
|
||||
|
|
|
|||
39
README.md
39
README.md
|
|
@ -5,19 +5,19 @@ I provide pre-compiled images ready for use.
|
|||
|
||||
1. *x86_64-efi* the preferred way of booting on x86_64 architecture.
|
||||
Standard GNU toolchain and a few files from gnuefi (included).
|
||||
[bootboot.efi](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.efi) (94k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.rom) (94k)
|
||||
[bootboot.efi](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.efi) (95k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.rom) (96k)
|
||||
|
||||
2. *x86_64-bios* BIOS, Multiboot (GRUB), El Torito (CDROM), Expansion ROM and Linux boot compatible, OBSOLETE loader.
|
||||
If you want to recompile this, you'll need fasm (not included).
|
||||
[boot.bin](https://gitlab.com/bztsrc/bootboot/raw/master/boot.bin) (512 bytes, works as MBR, VBR and CDROM boot record too), [bootboot.bin](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.bin) (11k, loaded by boot.bin, also BBS Expansion ROM and Multiboot compliant)
|
||||
|
||||
3. *aarch64-rpi* ARMv8 boot loader for Raspberry Pi 3, 4
|
||||
[bootboot.img](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.img) (32k)
|
||||
[bootboot.img](https://gitlab.com/bztsrc/bootboot/raw/master/bootboot.img) (34k)
|
||||
|
||||
4. *mykernel* an example BOOTBOOT [compatible kernel](https://gitlab.com/bztsrc/bootboot/tree/master/mykernel) in C which draws lines and boxes
|
||||
|
||||
Please note that the reference implementations do not support the full protocol at level 2 (except the UEFI version),
|
||||
they only handle static mappings which makes them level 1 loaders.
|
||||
Please note that not all the reference implementations do support the full protocol at level 2, x86_64-bios only handles
|
||||
static mappings which makes it a level 1 loader.
|
||||
|
||||
For quick test, you can find example bootable disk [images](https://gitlab.com/bztsrc/bootboot/tree/master/images) too.
|
||||
|
||||
|
|
@ -49,6 +49,12 @@ Note: BOOTBOOT is not a boot manager, it's a boot loader protocol. If you want a
|
|||
integrate that *before* a BOOTBOOT compatible loader is called. Like GRUB chainloading boot.bin (or loading bootboot.bin as a
|
||||
multiboot "kernel" and initrd as a module) or adding bootboot.efi to UEFI Boot Manager's menu for example.
|
||||
|
||||
Support the Development by Donation
|
||||
-----------------------------------
|
||||
|
||||
If you like it or find it useful, your donation of any amount will be very much appreciated:<br>
|
||||
<a href="bitcoin:3G9vcV91S19fHMoBcmSksUpaxGPR5MUGCk"><img src="https://gitlab.com/bztsrc/bootboot/raw/master/donate.png"><br>BTC 3G9vcV91S19fHMoBcmSksUpaxGPR5MUGCk</a>
|
||||
|
||||
Licence
|
||||
-------
|
||||
|
||||
|
|
@ -124,7 +130,7 @@ Boot process
|
|||
------------
|
||||
|
||||
1. the firmware locates the loader, loads it and passes control to it.
|
||||
2. the loader initializes hardware (64 bit mode, screen resolution, memory map etc.)
|
||||
2. the loader initializes hardware (64 bit multicore mode, screen resolution, memory map etc.)
|
||||
3. then loads environment file and initrd file (probably from the boot partition or from ROM).
|
||||
4. iterates on file system drivers, and loads kernel file from initrd.
|
||||
5. if file system is not recognized, scans for the first executable in the initrd.
|
||||
|
|
@ -156,8 +162,8 @@ The RAM (up to 16G) is identity mapped in the positive address range. Serial con
|
|||
|
||||
The screen is properly set up with a 32 bit packed pixel linear framebuffer, mapped at the negative address defined by
|
||||
the `fb` symbol. Level 1 loaders limit the framebuffer size somewhere around 4096 x 4096 pixels (depends on scanline size
|
||||
and aspect ratio too). That's more than enough for [Ultra HD 4K](https://en.wikipedia.org/wiki/4K_resolution)
|
||||
(3840 x 2160). Level 2 loaders can place the fb anywhere in memory therefore they do not have such a limitation.
|
||||
and aspect ratio too). That's more than enough for [Ultra HD 4K](https://en.wikipedia.org/wiki/4K_resolution) (3840 x 2160).
|
||||
Level 2 loaders can place the fb anywhere in memory from -1G to -2M, therefore they do not have such a limitation.
|
||||
|
||||
The main information [bootboot structure](https://gitlab.com/bztsrc/bootboot/blob/master/bootboot.h) is mapped
|
||||
at `bootboot` symbol. It consist of a fixed 128 bytes long header followed by various number of fixed
|
||||
|
|
@ -168,9 +174,9 @@ the *fb_ptr* field. The *boot time* and a platform independent *memory map* are
|
|||
The configuration string (or command line if you like) is mapped at `environment` symbol.
|
||||
|
||||
Kernel's code segment is mapped at ELF header's `p_vaddr` or PE header's `code_base` (level 2 only). Level 1 loaders
|
||||
load kernels at -2M, therefore limiting the kernel's size in 2M, including configuration, data, bss and stack. That
|
||||
must be more than enough for all micro-kernels. Bss segment is after the text segment, growing upwards, and it's zerod-out
|
||||
by the loader.
|
||||
load kernels at -2M, therefore limiting the kernel's size in 2M, including configuration, data, bss and stack. Level 2
|
||||
loaders has a limit of 16M for code, data and bss segment. That must be more than enough for all micro-kernels. Bss
|
||||
segment is after the text segment, growing upwards, and it's zerod-out by the loader.
|
||||
|
||||
Co-processor enabled, and if Symmetric Multi Processing supported, all cores are running the same kernel code at once.
|
||||
|
||||
|
|
@ -413,7 +419,14 @@ BOOTBOOT-PANIC: Kernel is not a valid executable
|
|||
The file that was specified as kernel could be loaded by fs drivers, but it's not an ELF64 or PE32+,
|
||||
does not match the architecture, or does not have any program header with a loadable segment (p_vaddr or core_base)
|
||||
in the negative range (see linker script). This error is also shown by level 2 loaders if the address of `mmio`, `fb`,
|
||||
`bootboot` and `environment` symbols are not in the negative range.
|
||||
`bootboot` and `environment` symbols are not in the negative range (-1G to 0) or if they are not page aligned.
|
||||
On x86_64 the fb symbol, and for AArch64 the mmio symbol must be 2M aligned too.
|
||||
|
||||
```
|
||||
BOOTBOOT-PANIC: Kernel is too big
|
||||
```
|
||||
|
||||
The kernel is bigger than 16 megabytes.
|
||||
|
||||
```
|
||||
BOOTBOOT-PANIC: GOP failed, no framebuffer
|
||||
|
|
@ -439,5 +452,5 @@ Contributors
|
|||
------------
|
||||
|
||||
I'd like to say special thanks to [Valentin Anger](https://gitlab.com/SyrupThinker) for throughfully testing this
|
||||
code on many different real hardware.
|
||||
|
||||
code on many different real hardware. Also to [Vinay Chandra](https://gitlab.com/vinaychandra) for pushing me to add
|
||||
level 2 protocol to the reference implementations and for testing and providing a Rust kernel example for the project.
|
||||
|
|
|
|||
|
|
@ -28,11 +28,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#define DEBUG 1
|
||||
//#define SD_DEBUG DEBUG
|
||||
//#define INITRD_DEBUG DEBUG
|
||||
//#define EXEC_DEBUG DEBUG
|
||||
//#define MEM_DEBUG DEBUG
|
||||
#define BBDEBUG 1
|
||||
//#define SD_DEBUG BBDEBUG
|
||||
//#define INITRD_DEBUG BBDEBUG
|
||||
//#define EXEC_DEBUG BBDEBUG
|
||||
//#define MEM_DEBUG BBDEBUG
|
||||
|
||||
#define CONSOLE UART0
|
||||
|
||||
|
|
@ -43,16 +43,13 @@
|
|||
|
||||
/* get BOOTBOOT structure */
|
||||
#include "../bootboot.h"
|
||||
// comment out this include if you don't want FS/Z support
|
||||
//#include "../../osZ/include/osZ/fsZ.h"
|
||||
|
||||
|
||||
/* aligned buffers */
|
||||
volatile uint32_t __attribute__((aligned(16))) mbox[36];
|
||||
/* we place these manually in linker script, gcc would otherwise waste lots of memory */
|
||||
volatile uint8_t __attribute__((aligned(PAGESIZE))) __bootboot[PAGESIZE];
|
||||
volatile uint8_t __attribute__((aligned(PAGESIZE))) __environment[PAGESIZE];
|
||||
volatile uint8_t __attribute__((aligned(PAGESIZE))) __paging[23*PAGESIZE];
|
||||
volatile uint8_t __attribute__((aligned(PAGESIZE))) __paging[50*PAGESIZE];
|
||||
volatile uint8_t __attribute__((aligned(PAGESIZE))) __corestack[PAGESIZE];
|
||||
#define __diskbuf __paging
|
||||
extern volatile uint8_t _data;
|
||||
|
|
@ -103,6 +100,30 @@ typedef struct
|
|||
uint64_t p_align; /* Segment alignment */
|
||||
} Elf64_Phdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t sh_name; /* Section name (string tbl index) */
|
||||
uint32_t sh_type; /* Section type */
|
||||
uint64_t sh_flags; /* Section flags */
|
||||
uint64_t sh_addr; /* Section virtual addr at execution */
|
||||
uint64_t sh_offset; /* Section file offset */
|
||||
uint64_t sh_size; /* Section size in bytes */
|
||||
uint32_t sh_link; /* Link to another section */
|
||||
uint32_t sh_info; /* Additional section information */
|
||||
uint64_t sh_addralign; /* Section alignment */
|
||||
uint64_t sh_entsize; /* Entry size if section holds table */
|
||||
} Elf64_Shdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t st_name; /* Symbol name (string tbl index) */
|
||||
uint8_t st_info; /* Symbol type and binding */
|
||||
uint8_t st_other; /* Symbol visibility */
|
||||
uint16_t st_shndx; /* Section index */
|
||||
uint64_t st_value; /* Symbol value */
|
||||
uint64_t st_size; /* Symbol size */
|
||||
} Elf64_Sym;
|
||||
|
||||
/*** PE32+ defines and structs ***/
|
||||
#define MZ_MAGIC 0x5a4d /* "MZ" */
|
||||
#define PE_MAGIC 0x00004550 /* "PE\0\0" */
|
||||
|
|
@ -121,7 +142,7 @@ typedef struct {
|
|||
uint16_t sections; /* number of sections */
|
||||
uint32_t timestamp; /* time_t */
|
||||
uint32_t sym_table; /* symbol table offset */
|
||||
uint32_t symbols; /* number of symbols */
|
||||
uint32_t numsym; /* number of symbols */
|
||||
uint16_t opt_hdr_size; /* size of optional header */
|
||||
uint16_t flags; /* flags */
|
||||
uint16_t file_type; /* file type, PE32PLUS magic */
|
||||
|
|
@ -134,6 +155,15 @@ typedef struct {
|
|||
int32_t code_base; /* relative code addr in ram */
|
||||
} pe_hdr;
|
||||
|
||||
typedef struct {
|
||||
uint32_t iszero; /* if this is not zero, then iszero+nameoffs gives UTF-8 string */
|
||||
uint32_t nameoffs;
|
||||
int32_t value; /* value of the symbol */
|
||||
uint16_t section; /* section it belongs to */
|
||||
uint16_t type; /* symbol type */
|
||||
uint8_t storclass; /* storage class */
|
||||
uint8_t auxsyms; /* number of pe_sym records following */
|
||||
} pe_sym;
|
||||
|
||||
/*** Raspberry Pi specific defines ***/
|
||||
static uint64_t mmio_base;
|
||||
|
|
@ -316,7 +346,7 @@ int oct2bin(unsigned char *s, int n){ int r=0;while(n-->0){r<<=3;r+=*s++-'0';} r
|
|||
int hex2bin(unsigned char *s, int n){ int r=0;while(n-->0){r<<=4;
|
||||
if(*s>='0' && *s<='9')r+=*s-'0';else if(*s>='A'&&*s<='F')r+=*s-'A'+10;s++;} return r; }
|
||||
|
||||
#if DEBUG
|
||||
#if BBDEBUG
|
||||
#define DBG(s) puts(s)
|
||||
#else
|
||||
#define DBG(s)
|
||||
|
|
@ -744,6 +774,11 @@ file_t env; // environment file descriptor
|
|||
file_t initrd; // initrd file descriptor
|
||||
file_t core; // kernel file descriptor
|
||||
BOOTBOOT *bootboot; // the BOOTBOOT structure
|
||||
uint64_t mm_addr = BOOTBOOT_MMIO; // virtual addresses
|
||||
uint64_t fb_addr = BOOTBOOT_FB;
|
||||
uint64_t bb_addr = BOOTBOOT_INFO;
|
||||
uint64_t env_addr= BOOTBOOT_ENV;
|
||||
uint64_t core_addr=BOOTBOOT_CORE;
|
||||
|
||||
// default environment variables. M$ states that 1024x768 must be supported
|
||||
int reqwidth = 1024, reqheight = 768;
|
||||
|
|
@ -756,7 +791,6 @@ char *cfgname="sys/config";
|
|||
uint64_t entrypoint=0, bss=0, *paging, reg, pa;
|
||||
uint8_t bsp_done=0;
|
||||
|
||||
#ifdef _FS_Z_H_
|
||||
/**
|
||||
* SHA-256
|
||||
*/
|
||||
|
|
@ -903,7 +937,6 @@ int ReadLine(unsigned char *buf, int l)
|
|||
}
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
// get filesystem drivers for initrd
|
||||
#include "fs.h"
|
||||
|
|
@ -1054,6 +1087,27 @@ void putc(char c)
|
|||
*/
|
||||
void puts(char *s) { while(*s) putc(*s++); }
|
||||
|
||||
/**
|
||||
* Add a mapping to paging tables
|
||||
*/
|
||||
int freep = 37;
|
||||
void MapPage(uint64_t virt, uint64_t phys)
|
||||
{
|
||||
int i,j;
|
||||
j = (virt>>(9+12)) & 0x1FF;
|
||||
if(!paging[4*512 + j] || (paging[4*512 + j] & (2<<2))) {
|
||||
if(freep == 50) return;
|
||||
paging[4*512 + j]=(uint64_t)((uint8_t *)paging+freep*PAGESIZE)|0b11|(3<<8)|(1<<10);
|
||||
freep++;
|
||||
}
|
||||
i = (paging[4*512 + j] - (uint64_t)((uint8_t *)paging)) >> 12;
|
||||
j = (virt>>(12)) & 0x1FF;
|
||||
paging[i*512 + j] = phys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse FS0:\BOOTBOOT\CONFIG or /sys/config
|
||||
*/
|
||||
void ParseEnvironment(uint8_t *env)
|
||||
{
|
||||
uint8_t *end=env+PAGESIZE;
|
||||
|
|
@ -1107,7 +1161,7 @@ void ParseEnvironment(uint8_t *env)
|
|||
int bootboot_main(uint64_t hcl)
|
||||
{
|
||||
uint8_t *pe,bkp=0;
|
||||
uint32_t np,sp,r,mp;
|
||||
uint32_t np,sp,r,mp,j;
|
||||
efipart_t *part;
|
||||
volatile bpb_t *bpb;
|
||||
MMapEnt *mmap;
|
||||
|
|
@ -1172,7 +1226,7 @@ int bootboot_main(uint64_t hcl)
|
|||
bootboot = (BOOTBOOT*)&__bootboot;
|
||||
memset(bootboot,0,PAGESIZE);
|
||||
memcpy((void*)&bootboot->magic,BOOTBOOT_MAGIC,4);
|
||||
bootboot->protocol = PROTOCOL_STATIC | LOADER_RPI;
|
||||
bootboot->protocol = PROTOCOL_DYNAMIC | LOADER_RPI;
|
||||
bootboot->size = 128;
|
||||
bootboot->numcores = 4;
|
||||
bootboot->arch.aarch64.mmio_ptr = mmio_base;
|
||||
|
|
@ -1490,14 +1544,52 @@ gzerr: puts("BOOTBOOT-PANIC: Unable to uncompress\n");
|
|||
}
|
||||
phdr=(Elf64_Phdr *)((uint8_t *)phdr+ehdr->e_phentsize);
|
||||
}
|
||||
if(ehdr->e_shoff > 0) {
|
||||
Elf64_Shdr *shdr=(Elf64_Shdr *)((uint8_t *)ehdr + ehdr->e_shoff), *sym_sh = NULL, *str_sh = NULL;
|
||||
Elf64_Shdr *strt=(Elf64_Shdr *)((uint8_t *)shdr+(uint64_t)ehdr->e_shstrndx*(uint64_t)ehdr->e_shentsize);
|
||||
Elf64_Sym *sym = NULL, *s;
|
||||
char *strtable = (char *)ehdr + strt->sh_offset;
|
||||
uint32_t strsz = 0, syment = 0, i;
|
||||
for(i = 0; i < ehdr->e_shnum; i++){
|
||||
/* checking shdr->sh_type is not enough, there can be multiple SHT_STRTAB records... */
|
||||
if(!memcmp(strtable + shdr->sh_name, ".symtab", 8)) sym_sh = shdr;
|
||||
if(!memcmp(strtable + shdr->sh_name, ".strtab", 8)) str_sh = shdr;
|
||||
shdr = (Elf64_Shdr *)((uint8_t *)shdr + ehdr->e_shentsize);
|
||||
}
|
||||
if(str_sh && sym_sh) {
|
||||
strtable = (char *)ehdr + str_sh->sh_offset; strsz = str_sh->sh_size;
|
||||
sym = (Elf64_Sym *)((uint8_t*)ehdr + sym_sh->sh_offset); syment = sym_sh->sh_entsize;
|
||||
if(str_sh->sh_offset && strsz > 0 && sym_sh->sh_offset && syment > 0)
|
||||
for(s = sym, i = 0; i<(strtable-(char*)sym)/syment && s->st_name < strsz; i++, s++) {
|
||||
if(!memcmp(strtable + s->st_name, "bootboot", 9)) bb_addr = s->st_value;
|
||||
if(!memcmp(strtable + s->st_name, "environment", 12)) env_addr = s->st_value;
|
||||
if(!memcmp(strtable + s->st_name, "mmio", 4)) mm_addr = s->st_value;
|
||||
if(!memcmp(strtable + s->st_name, "fb", 3)) fb_addr = s->st_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
if(((mz_hdr*)(core.ptr))->magic==MZ_MAGIC && ((mz_hdr*)(core.ptr))->peaddr<65536 && pehdr->magic == PE_MAGIC &&
|
||||
pehdr->machine == IMAGE_FILE_MACHINE_ARM64 && pehdr->file_type == PE_OPT_MAGIC_PE32PLUS &&
|
||||
(int64_t)pehdr->code_base>>48==0xffff) {
|
||||
(pehdr->code_base & 0xC0000000)) {
|
||||
DBG(" * Parsing PE32+\n");
|
||||
core.size = (pehdr->entry_point-pehdr->code_base) + pehdr->text_size + pehdr->data_size;
|
||||
bss = pehdr->bss_size;
|
||||
entrypoint = (int64_t)pehdr->entry_point;
|
||||
if(pehdr->sym_table > 0 && pehdr->numsym > 0) {
|
||||
pe_sym *s;
|
||||
char *strtable = (char *)pehdr + pehdr->sym_table + pehdr->numsym * 18 + 4, *name;
|
||||
uint32_t i;
|
||||
for(i = 0; i < pehdr->numsym; i++) {
|
||||
s = (pe_sym*)((uint8_t *)pehdr + pehdr->sym_table + i * 18);
|
||||
name = !s->iszero ? (char*)&s->iszero : strtable + s->nameoffs;
|
||||
if(!memcmp(name, "bootboot", 9)) bb_addr = (int64_t)s->value;
|
||||
if(!memcmp(name, "environment", 12)) env_addr = (int64_t)s->value;
|
||||
if(!memcmp(name, "mmio", 4)) mm_addr = (int64_t)s->value;
|
||||
if(!memcmp(name, "fb", 3)) fb_addr = (int64_t)s->value;
|
||||
i += s->auxsyms;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#if EXEC_DEBUG
|
||||
|
|
@ -1508,8 +1600,14 @@ gzerr: puts("BOOTBOOT-PANIC: Unable to uncompress\n");
|
|||
uart_putc('\n');
|
||||
uart_dump((void*)core.ptr,4);
|
||||
#endif
|
||||
if(core.size<2 || entrypoint==0) {
|
||||
puts("BOOTBOOT-PANIC: Kernel is not a valid executable\n");
|
||||
if(core.ptr==NULL || core.size<2 || entrypoint==0 || (core_addr&(PAGESIZE-1)) || (bb_addr>>30)!=0x3FFFFFFFF ||
|
||||
(bb_addr & (PAGESIZE-1)) || (env_addr>>30)!=0x3FFFFFFFF || (env_addr&(PAGESIZE-1)) || (fb_addr>>30)!=0x3FFFFFFFF ||
|
||||
(fb_addr&(1024*1024*2-1))) {
|
||||
puts("BOOTBOOT-PANIC: Kernel is not a valid executable\n");
|
||||
goto error;
|
||||
}
|
||||
if(core.size+bss > 16*1024*1024) {
|
||||
puts("BOOTBOOT-PANIC: Kernel is too big");
|
||||
goto error;
|
||||
}
|
||||
// create core segment
|
||||
|
|
@ -1606,19 +1704,19 @@ viderr:
|
|||
puts("BOOTBOOT-PANIC: VideoCore error, no framebuffer\n");
|
||||
goto error;
|
||||
}
|
||||
/* clear the screen */
|
||||
int offs = 0, line;
|
||||
for(ky=0;ky<bootboot->fb_height;ky++) {
|
||||
line=offs;
|
||||
for(kx=0;kx<bootboot->fb_width;kx+=2,line+=8)
|
||||
*((uint64_t*)((uint64_t)bootboot->fb_ptr + line))=0;
|
||||
offs+=bootboot->fb_scanline;
|
||||
}
|
||||
}
|
||||
/* clear the screen */
|
||||
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;
|
||||
j+=bootboot->fb_scanline;
|
||||
}
|
||||
kx=ky=0; color=0xFFDD33;
|
||||
|
||||
/* create MMU translation tables in __paging */
|
||||
paging=(uint64_t*)&__paging;
|
||||
memset(paging, 0, 50*PAGESIZE);
|
||||
// TTBR0, identity L1
|
||||
paging[0]=(uint64_t)((uint8_t*)&__paging+2*PAGESIZE)|0b11|(3<<8)|(1<<10); //AF=1,Block=1,Present=1, SH=3 ISH, RO
|
||||
// identity L2
|
||||
|
|
@ -1635,24 +1733,28 @@ viderr:
|
|||
paging[512+511]=(uint64_t)((uint8_t*)&__paging+4*PAGESIZE)|0b11|(3<<8)|(1<<10); //AF=1,Block=1,Present=1
|
||||
// core L2
|
||||
// map MMIO in kernel space
|
||||
for(r=0;r<32;r++)
|
||||
paging[4*512+448+r]=(uint64_t)(mmio_base+((uint64_t)r<<21))|0b01|(2<<8)|(1<<10)|(1<<2)|(1L<<54); //OSH, Attr=1, NX
|
||||
j = (mm_addr>>(9+12)) & 0x1FF;
|
||||
for(r=0;j+r < 511 && r<32;r++)
|
||||
paging[4*512+j+r]=(uint64_t)(mmio_base+((uint64_t)r<<21))|0b01|(2<<8)|(1<<10)|(1<<2)|(1L<<54); //OSH, Attr=1, NX
|
||||
// map framebuffer
|
||||
for(r=0;r<16;r++)
|
||||
paging[4*512+480+r]=(uint64_t)((uint8_t*)&__paging+(6+r)*PAGESIZE)|0b11|(2<<8)|(1<<10)|(2<<2)|(1L<<54); //OSH, Attr=2
|
||||
paging[4*512+511]=(uint64_t)((uint8_t*)&__paging+5*PAGESIZE)|0b11|(3<<8)|(1<<10);// pointer to core L3
|
||||
j = (fb_addr>>(9+12)) & 0x1FF;
|
||||
for(r=0;j+r < 511 && r<31;r++)
|
||||
paging[4*512+j+r]=(uint64_t)((uint8_t*)&__paging+(5+r)*PAGESIZE)|0b11|(2<<8)|(1<<10)|(2<<2)|(1L<<54); //OSH, Attr=2
|
||||
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
|
||||
// core L3
|
||||
paging[5*512+0]=(uint64_t)((uint8_t*)&__bootboot)|0b11|(3<<8)|(1<<10)|(1L<<54); // p, b, AF, ISH
|
||||
paging[5*512+1]=(uint64_t)((uint8_t*)&__environment)|0b11|(3<<8)|(1<<10)|(1L<<54);
|
||||
// dynamically map these. Main struct, environment string and code segment
|
||||
for(r=0;r<(core.size/PAGESIZE);r++)
|
||||
paging[5*512+2+r]=(uint64_t)((uint8_t *)core.ptr+(uint64_t)r*PAGESIZE)|0b11|(3<<8)|(1<<10);
|
||||
MapPage(core_addr+r*PAGESIZE,(uint64_t)((uint8_t *)core.ptr+(uint64_t)r*PAGESIZE)|0b11|(3<<8)|(1<<10));
|
||||
MapPage(bb_addr,(uint64_t)((uint8_t*)&__bootboot)|0b11|(3<<8)|(1<<10)|(1L<<54)); // p, b, AF, ISH
|
||||
MapPage(env_addr,(uint64_t)((uint8_t*)&__environment)|0b11|(3<<8)|(1<<10)|(1L<<54));
|
||||
// stack at the top of the memory
|
||||
paging[36*512+511]=(uint64_t)((uint8_t*)&__corestack)|0b11|(3<<8)|(1<<10)|(1L<<54); // core stacks (1k each)
|
||||
#if MEM_DEBUG
|
||||
reg=r;
|
||||
#endif
|
||||
paging[5*512+511]=(uint64_t)((uint8_t*)&__corestack)|0b11|(3<<8)|(1<<10)|(1L<<54); // core stacks (1k each)
|
||||
// core L3 (lfb)
|
||||
for(r=0;r<16*512;r++)
|
||||
paging[6*512+r]=(uint64_t)((uint8_t*)bootboot->fb_ptr+r*PAGESIZE)|0b11|(2<<8)|(1<<10)|(2<<2)|(1L<<54); // map framebuffer
|
||||
|
||||
#if MEM_DEBUG
|
||||
/* dump page translation tables */
|
||||
|
|
@ -1697,7 +1799,19 @@ viderr:
|
|||
for(r=508;r<512;r++) { uart_hex(paging[5*512+r],8); uart_putc(' '); }
|
||||
uart_puts("\n\n");
|
||||
#endif
|
||||
#if DEBUG
|
||||
#if BBDEBUG
|
||||
uart_puts(" * mmio ");
|
||||
uart_hex(mm_addr,8);
|
||||
uart_putc('\n');
|
||||
uart_puts(" * fb ");
|
||||
uart_hex(fb_addr,8);
|
||||
uart_putc('\n');
|
||||
uart_puts(" * bootboot ");
|
||||
uart_hex(bb_addr,8);
|
||||
uart_putc('\n');
|
||||
uart_puts(" * environment ");
|
||||
uart_hex(env_addr,8);
|
||||
uart_putc('\n');
|
||||
uart_puts(" * Entry point ");
|
||||
uart_hex(entrypoint,8);
|
||||
uart_putc('\n');
|
||||
|
|
|
|||
|
|
@ -28,51 +28,48 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef _FS_Z_H_
|
||||
/**
|
||||
* FS/Z initrd (OS/Z's native file system)
|
||||
*/
|
||||
file_t fsz_initrd(unsigned char *initrd_p, char *kernel)
|
||||
{
|
||||
FSZ_SuperBlock *sb = (FSZ_SuperBlock *)initrd_p;
|
||||
file_t ret = { NULL, 0 };
|
||||
if(initrd_p==NULL || memcmp(sb->magic,FSZ_MAGIC,4) || kernel==NULL){
|
||||
if(initrd_p==NULL || memcmp(initrd_p + 512,"FS/Z",4) || kernel==NULL){
|
||||
return ret;
|
||||
}
|
||||
unsigned char passphrase[256],chk[32],iv[32];
|
||||
int i,j,k,l,ss=1<<(sb->logsec+11);
|
||||
FSZ_DirEnt *ent;
|
||||
FSZ_Inode *in=(FSZ_Inode *)(initrd_p+sb->rootdirfid*ss);
|
||||
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 ");
|
||||
DBG(kernel);
|
||||
DBG("\n");
|
||||
//decrypt initrd
|
||||
if(sb->enchash!=0 && FSZ_SB_EALG(sb->flags)!=0) {
|
||||
if(*((uint32_t*)(initrd_p+708))!=0 && ((initrd_p[518]>>2)&7)!=0) {
|
||||
puts("BOOTBOOT-PANIC: Unsupported cipher\n");
|
||||
return ret;
|
||||
}
|
||||
while(sb->enchash!=0) {
|
||||
while(*((uint32_t*)(initrd_p+708))!=0) {
|
||||
puts(" * Passphrase? ");
|
||||
l=ReadLine(passphrase,sizeof(passphrase));
|
||||
if(!l) {
|
||||
puts("\n");
|
||||
return ret;
|
||||
}
|
||||
if(sb->enchash!=crc32_calc((char*)passphrase,l)) {
|
||||
if(*((uint32_t*)(initrd_p+708))!=crc32_calc((char*)passphrase,l)) {
|
||||
puts("\rBOOTBOOT-ERROR: Bad passphrase\n");
|
||||
continue;
|
||||
}
|
||||
puts("\r * Decrypting...\r");
|
||||
SHA256_Init(&ctx);
|
||||
SHA256_Update(&ctx,passphrase,l);
|
||||
SHA256_Update(&ctx,&sb->magic,6);
|
||||
SHA256_Update(&ctx,initrd_p+512,6);
|
||||
SHA256_Final(chk,&ctx);
|
||||
for(i=0;i<sizeof(sb->encrypt);i++) sb->encrypt[i]^=chk[i];
|
||||
for(i=0;i<28;i++) initrd_p[i+680]^=chk[i];
|
||||
SHA256_Init(&ctx);
|
||||
SHA256_Update(&ctx,&sb->encrypt,sizeof(sb->encrypt));
|
||||
SHA256_Update(&ctx,initrd_p+680,28);
|
||||
SHA256_Final(iv,&ctx);
|
||||
for(k=ss,j=1;j<sb->numsec;j++) {
|
||||
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) {
|
||||
|
|
@ -84,8 +81,8 @@ file_t fsz_initrd(unsigned char *initrd_p, char *kernel)
|
|||
initrd_p[k++]^=chk[i%32]^iv[i%32];
|
||||
}
|
||||
}
|
||||
memset(sb->encrypt,0,sizeof(sb->encrypt)+4);
|
||||
sb->checksum=crc32_calc((char *)sb->magic,508);
|
||||
memset(initrd_p+680,0,28+4);
|
||||
*((uint32_t*)(initrd_p+1020))=crc32_calc((char *)initrd_p+512,508);
|
||||
puts(" \r");
|
||||
}
|
||||
// Get the inode
|
||||
|
|
@ -95,60 +92,59 @@ file_t fsz_initrd(unsigned char *initrd_p, char *kernel)
|
|||
again:
|
||||
while(*e!='/'&&*e!=0){e++;}
|
||||
if(*e=='/'){e++;}
|
||||
if(!memcmp(in->magic,FSZ_IN_MAGIC,4)){
|
||||
if(!memcmp(in,"FSIN",4)){
|
||||
//is it inlined?
|
||||
if(!memcmp(sb->flags&FSZ_SB_FLAG_BIGINODE? in->data.big.inlinedata : in->data.small.inlinedata,FSZ_DIR_MAGIC,4)){
|
||||
ent=(FSZ_DirEnt *)(sb->flags&FSZ_SB_FLAG_BIGINODE? in->data.big.inlinedata : in->data.small.inlinedata);
|
||||
} else if(!memcmp(initrd_p+in->sec*ss,FSZ_DIR_MAGIC,4)){
|
||||
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=(FSZ_DirEnt *)(initrd_p+in->sec*ss);
|
||||
ent=(initrd_p+*((uint64_t*)(in+448))*ss);
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
//skip header
|
||||
FSZ_DirEntHeader *hdr=(FSZ_DirEntHeader *)ent; ent++;
|
||||
unsigned char *hdr=ent; ent+=128;
|
||||
//iterate on directory entries
|
||||
int j=hdr->numentries;
|
||||
int j=*((uint64_t*)(hdr+16));
|
||||
while(j-->0){
|
||||
if(!memcmp(ent->name,s,e-s)) {
|
||||
if(!memcmp(ent + 17,s,e-s)) {
|
||||
if(*e==0) {
|
||||
i=ent->fid;
|
||||
i=*((uint64_t*)(ent+0));
|
||||
break;
|
||||
} else {
|
||||
s=e;
|
||||
in=(FSZ_Inode *)(initrd_p+ent->fid*ss);
|
||||
in=(initrd_p+*((uint64_t*)(ent+0))*ss);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
ent++;
|
||||
ent+=128;
|
||||
}
|
||||
} else {
|
||||
i=0;
|
||||
}
|
||||
if(i!=0) {
|
||||
// fid -> inode ptr -> data ptr
|
||||
FSZ_Inode *in=(FSZ_Inode *)(initrd_p+i*ss);
|
||||
if(!memcmp(in->magic,FSZ_IN_MAGIC,4)){
|
||||
ret.size=in->size;
|
||||
switch(FSZ_FLAG_TRANSLATION(in->flags)) {
|
||||
case FSZ_IN_FLAG_INLINE:
|
||||
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+1024);
|
||||
ret.ptr=(uint8_t*)(initrd_p+i*ss+(initrd_p[518]&1? 2048 : 1024));
|
||||
break;
|
||||
case FSZ_IN_FLAG_SECLIST:
|
||||
case FSZ_IN_FLAG_SDINLINE:
|
||||
case 0x80:
|
||||
case 0x7F:
|
||||
// sector directory or list inlined
|
||||
ret.ptr=(uint8_t*)(initrd_p + *(sb->flags&FSZ_SB_FLAG_BIGINODE?
|
||||
(uint64_t*)&in->data.big.inlinedata : (uint64_t*)&in->data.small.inlinedata) * ss);
|
||||
ret.ptr=(uint8_t*)(initrd_p + *((uint64_t*)(initrd_p[518]&1? in + 2048 : in + 1024))*ss);
|
||||
break;
|
||||
case FSZ_IN_FLAG_DIRECT:
|
||||
case 0:
|
||||
// direct data
|
||||
ret.ptr=(uint8_t*)(initrd_p + in->sec * ss);
|
||||
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 FSZ_IN_FLAG_SECLIST0:
|
||||
case FSZ_IN_FLAG_SD:
|
||||
ret.ptr=(uint8_t*)(initrd_p + (unsigned int)(((FSZ_SectorList *)(initrd_p+in->sec*ss))->sec) * ss);
|
||||
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;
|
||||
|
|
@ -158,7 +154,6 @@ again:
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* cpio archive
|
||||
|
|
@ -297,9 +292,7 @@ file_t jamesm_initrd(unsigned char *initrd_p, char *kernel)
|
|||
* Static file system drivers registry
|
||||
*/
|
||||
file_t (*fsdrivers[]) (unsigned char *, char *) = {
|
||||
#ifdef _FS_Z_H_
|
||||
fsz_initrd,
|
||||
#endif
|
||||
cpio_initrd,
|
||||
tar_initrd,
|
||||
sfs_initrd,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ SECTIONS
|
|||
__environment = .;
|
||||
. += 4096;
|
||||
__paging = .;
|
||||
. += (23*4096);
|
||||
. += (50*4096);
|
||||
__corestack = .;
|
||||
. += 4096;
|
||||
__bss_end = .;
|
||||
|
|
|
|||
BIN
bootboot.bin
BIN
bootboot.bin
Binary file not shown.
BIN
bootboot.efi
BIN
bootboot.efi
Binary file not shown.
|
|
@ -37,6 +37,13 @@ extern "C" {
|
|||
|
||||
#define BOOTBOOT_MAGIC "BOOT"
|
||||
|
||||
/* default virtual addresses for level 0 and 1 static loaders */
|
||||
#define BOOTBOOT_MMIO 0xfffffffff8000000 /* memory mapped IO virtual address */
|
||||
#define BOOTBOOT_FB 0xfffffffffc000000 /* frame buffer virtual address */
|
||||
#define BOOTBOOT_INFO 0xffffffffffe00000 /* bootboot struct virtual address */
|
||||
#define BOOTBOOT_ENV 0xffffffffffe01000 /* environment string virtual address */
|
||||
#define BOOTBOOT_CORE 0xffffffffffe02000 /* core loadable segment start */
|
||||
|
||||
/* minimum protocol level:
|
||||
* hardcoded kernel name, static kernel memory addresses */
|
||||
#define PROTOCOL_MINIMAL 0
|
||||
|
|
|
|||
BIN
bootboot.img
BIN
bootboot.img
Binary file not shown.
BIN
bootboot.rom
BIN
bootboot.rom
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
donate.png
Normal file
BIN
donate.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 491 B |
|
|
@ -15,8 +15,8 @@ Fordítás
|
|||
|
||||
Nézz bele a Makefile-ba, az elején fogsz látni konfigurálható változókat.
|
||||
|
||||
- DISKSIZE: a teljes generálnadó lemezkép mérete megabájtban
|
||||
- BOOTSIZE: a rendszerbetöltő partíció mérete megabájtban
|
||||
- DISKSIZE: a teljes generálandó lemezkép mérete Megabájtban
|
||||
- BOOTSIZE: a rendszerbetöltő partíció mérete Megabájtban
|
||||
- BOOTTYPE: a rendszerbetöltő partíció FAT típusa, 16 vagy 32 (12 már nem támogatott)
|
||||
- PLATFORM: vagy "x86" vagy "rpi", ez választja ki, melyik lemezképet generálja
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ Executing `make all` will create the following files:
|
|||
- disk-(PLATFORM).img: a hybrid disk image with GPT partitions
|
||||
|
||||
The disk-x86.img is a special hybrid image, which can be renamed to disk-x86.iso and then burnt to a CDROM; it can also be
|
||||
booted from an USB stick in a BIOS machine as well as an UEFI machine.
|
||||
booted from an USB stick in a BIOS machine as well as in an UEFI machine.
|
||||
|
||||
The disk-rpi.img can be written to an SDCard (Class 10) and booted on a Raspberry Pi 3 and 4.
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -28,7 +28,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
mmio = 0xfffffffff8000000;
|
||||
mmio = 0xfffffffff8000000; /* these are configurable for level 2 loaders */
|
||||
fb = 0xfffffffffc000000;
|
||||
PHDRS
|
||||
{
|
||||
|
|
|
|||
|
|
@ -53,8 +53,10 @@
|
|||
;*
|
||||
;* At first big enough free hole, initrd. Usually at 1Mbyte.
|
||||
;*
|
||||
;* WARNING: supports BOOTBOOT Protocol level 1 only (static mappings)
|
||||
;*
|
||||
|
||||
DEBUG equ 1
|
||||
BBDEBUG equ 1
|
||||
|
||||
;get Core boot parameter block
|
||||
include "bootboot.inc"
|
||||
|
|
@ -102,14 +104,14 @@ macro prot_readsector
|
|||
|
||||
macro DBG msg
|
||||
{
|
||||
if DEBUG eq 1
|
||||
if BBDEBUG eq 1
|
||||
real_print msg
|
||||
end if
|
||||
}
|
||||
|
||||
macro DBG32 msg
|
||||
{
|
||||
if DEBUG eq 1
|
||||
if BBDEBUG eq 1
|
||||
prot_realmode
|
||||
real_print msg
|
||||
real_protmode
|
||||
|
|
@ -1035,7 +1037,7 @@ protmode_start:
|
|||
.getgpt: xor eax, eax
|
||||
xor edi, edi
|
||||
prot_readsector
|
||||
if DEBUG eq 1
|
||||
if BBDEBUG eq 1
|
||||
cmp byte [iscdrom], 0
|
||||
jz @f
|
||||
DBG32 dbg_cdrom
|
||||
|
|
@ -1671,7 +1673,13 @@ end if
|
|||
;ebx=ptr to core segment, ecx=segment size, edx=bss size
|
||||
.mkcore: or ecx, ecx
|
||||
jz .badcore
|
||||
mov edi, dword [bootboot.initrd_ptr]
|
||||
mov eax, ecx
|
||||
add eax, edx
|
||||
cmp eax, 2*1024*1024 - 256*1024 - 2*4096; 2M minus stack for 256 cores minus bootboot and environment
|
||||
jl @f
|
||||
mov esi, bigcore
|
||||
jmp prot_diefunc
|
||||
@@: mov edi, dword [bootboot.initrd_ptr]
|
||||
add edi, dword [bootboot.initrd_size]
|
||||
mov dword [core_ptr], edi
|
||||
mov dword [core_len], ecx
|
||||
|
|
@ -2200,7 +2208,6 @@ longmode_init:
|
|||
include "tinf.inc"
|
||||
|
||||
;encryption support for FS/Z
|
||||
if FSZ_SUPPORT eq 1
|
||||
; --- SHA-256 ---
|
||||
sha_init: xor eax, eax
|
||||
mov dword [sha_l], eax
|
||||
|
|
@ -2462,7 +2469,6 @@ crc32_calc: xor edx, edx
|
|||
dec cx
|
||||
jnz .next
|
||||
.end: ret
|
||||
end if
|
||||
|
||||
;*********************************************************************
|
||||
;* Data *
|
||||
|
|
@ -2483,7 +2489,6 @@ GDT_value: dw $-GDT_table
|
|||
dd GDT_table
|
||||
dd 0,0
|
||||
;lookup tables for initrd encryption
|
||||
if FSZ_SUPPORT eq 1
|
||||
dw 0
|
||||
crclkp: dd 000000000h, 0F26B8303h, 0E13B70F7h, 01350F3F4h, 0C79A971Fh, 035F1141Ch, 026A1E7E8h, 0D4CA64EBh
|
||||
dd 08AD958CFh, 078B2DBCCh, 06BE22838h, 09989AB3Bh, 04D43CFD0h, 0BF284CD3h, 0AC78BF27h, 05E133C24h
|
||||
|
|
@ -2526,7 +2531,6 @@ sha256_k: dd 0428a2f98h, 071374491h, 0b5c0fbcfh, 0e9b5dba5h, 03956c25
|
|||
dd 0a2bfe8a1h, 0a81a664bh, 0c24b8b70h, 0c76c51a3h, 0d192e819h, 0d6990624h, 0f40e3585h, 0106aa070h
|
||||
dd 019a4c116h, 01e376c08h, 02748774ch, 034b0bcb5h, 0391c0cb3h, 04ed8aa4ah, 05b9cca4fh, 0682e6ff3h
|
||||
dd 0748f82eeh, 078a5636fh, 084c87814h, 08cc70208h, 090befffah, 0a4506cebh, 0bef9a3f7h, 0c67178f2h
|
||||
end if
|
||||
idt16: dw 3FFh
|
||||
dq 0
|
||||
lbapacket: ;lba packet for BIOS
|
||||
|
|
@ -2553,7 +2557,7 @@ iscdrom: db 0
|
|||
bsp_done: ;flag to indicate APs can run
|
||||
fattype: db 0
|
||||
bkp: dd ' '
|
||||
if DEBUG eq 1
|
||||
if BBDEBUG eq 1
|
||||
dbg_cpu db " * Detecting CPU",10,13,0
|
||||
dbg_A20 db " * Enabling A20",10,13,0
|
||||
dbg_mem db " * E820 Memory Map",10,13,0
|
||||
|
|
@ -2587,6 +2591,7 @@ nord: db "Initrd not found",0
|
|||
nolib: db "/sys not found in initrd",0
|
||||
nocore: db "Kernel not found in initrd",0
|
||||
badcore: db "Kernel is not a valid executable",0
|
||||
bigcore: db "Kernel is too big",0
|
||||
novbe: db "VESA VBE error, no framebuffer",0
|
||||
nogzip: db "Unable to uncompress",0
|
||||
notcdsect: db "Not 2048 sector aligned",0
|
||||
|
|
@ -2644,7 +2649,6 @@ hdist: dw ?
|
|||
hclen: dw ?
|
||||
tinf_bss_end:
|
||||
|
||||
if FSZ_SUPPORT eq 1
|
||||
virtual at tinf_bss_start
|
||||
pass: db 256 dup ?
|
||||
sha_d: db 64 dup ?
|
||||
|
|
@ -2667,7 +2671,6 @@ iv: db 32 dup ?
|
|||
pl: dd ?
|
||||
_i: dd ?
|
||||
end virtual
|
||||
end if
|
||||
|
||||
;-----------bound check-------------
|
||||
;fasm will generate an error if the code
|
||||
|
|
|
|||
|
|
@ -37,6 +37,13 @@ bootboot = 8000h
|
|||
; this define is in the 18th line of bootboot.h
|
||||
bootboot_MAGIC equ 'BOOT'
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; minimum protocol level:
|
||||
; hardcoded kernel name, static kernel memory addresses
|
||||
PROTOCOL_MINIMAL equ 0
|
||||
|
|
|
|||
|
|
@ -27,24 +27,19 @@
|
|||
;* @brief Filesystem drivers for initial ramdisk.
|
||||
;*
|
||||
|
||||
FSZ_SUPPORT equ 1
|
||||
|
||||
;*********************************************************************
|
||||
;* File System Drivers *
|
||||
;*********************************************************************
|
||||
|
||||
USE32
|
||||
fsdrivers:
|
||||
if FSZ_SUPPORT eq 1
|
||||
dw fsz_initrd
|
||||
end if
|
||||
dw cpio_initrd
|
||||
dw tar_initrd
|
||||
dw sfs_initrd
|
||||
dw jamesm_initrd
|
||||
dw 0
|
||||
|
||||
if FSZ_SUPPORT eq 1
|
||||
; ----------- FS/Z ----------
|
||||
; Find the kernel on initrd (only supports 4096 logical sector sizes)
|
||||
; IN: esi: initrd pointer, ecx: initrd end, edi: kernel filename
|
||||
|
|
@ -329,7 +324,6 @@ fsz_initrd:
|
|||
mov esi, dword [bootboot.initrd_ptr]
|
||||
add esi, eax
|
||||
ret
|
||||
end if
|
||||
|
||||
; ----------- cpio ----------
|
||||
; Find the kernel on initrd
|
||||
|
|
|
|||
|
|
@ -28,8 +28,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
// DEBUG already defined in efidebug.h
|
||||
|
||||
#define BBDEBUG 1
|
||||
//#define GOP_DEBUG BBDEBUG
|
||||
|
||||
|
|
@ -48,8 +46,6 @@
|
|||
// get BOOTBOOT specific stuff
|
||||
#include "../bootboot.h"
|
||||
#include "tinf.h"
|
||||
// comment out this include if you don't want FS/Z support
|
||||
//#include "../../osZ/include/osZ/fsZ.h"
|
||||
|
||||
/*** ELF64 defines and structs ***/
|
||||
#define ELFMAG "\177ELF"
|
||||
|
|
@ -302,9 +298,11 @@ file_t core; // kernel file descriptor
|
|||
BOOTBOOT *bootboot; // the BOOTBOOT structure
|
||||
UINT64 *paging; // paging table for MMU
|
||||
UINT64 entrypoint; // kernel entry point
|
||||
UINT64 fb_addr = 0xfffffffffc000000; // frame buffer virtual address
|
||||
UINT64 bb_addr = 0xffffffffffe00000; // bootboot struct virtual address
|
||||
UINT64 env_addr= 0xffffffffffe01000; // environment string virtual address
|
||||
UINT64 fb_addr = BOOTBOOT_FB; // virtual addresses
|
||||
UINT64 bb_addr = BOOTBOOT_INFO;
|
||||
UINT64 env_addr= BOOTBOOT_ENV;
|
||||
UINT64 core_addr=BOOTBOOT_CORE;
|
||||
|
||||
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
|
||||
EFI_FILE_HANDLE RootDir;
|
||||
EFI_FILE_PROTOCOL *Root;
|
||||
|
|
@ -318,7 +316,6 @@ char *kernelname="sys/core";
|
|||
// alternative environment name
|
||||
char *cfgname="sys/config";
|
||||
|
||||
#ifdef _FS_Z_H_
|
||||
/**
|
||||
* SHA-256
|
||||
*/
|
||||
|
|
@ -850,7 +847,6 @@ int ReadLine(unsigned char *buf, int l)
|
|||
}
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* function to convert ascii to number
|
||||
|
|
@ -922,6 +918,24 @@ int hex2bin(unsigned char *str, int size)
|
|||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a mapping to paging tables
|
||||
*/
|
||||
int freep = 24;
|
||||
void MapPage(UINT64 virt, UINT64 phys)
|
||||
{
|
||||
int i,j;
|
||||
j = (virt>>(9+12)) & 0x1FF;
|
||||
if(!paging[22*512 + j] || (paging[22*512 + j] & 0xFF) == 0x83) {
|
||||
if(freep == 37) return;
|
||||
paging[22*512 + j]=(UINT64)((UINT8 *)paging+freep*PAGESIZE+3);
|
||||
freep++;
|
||||
}
|
||||
i = (paging[22*512 + j] - (UINT64)((UINT8 *)paging)) >> 12;
|
||||
j = (virt>>(12)) & 0x1FF;
|
||||
paging[i*512 + j] = phys | 1;
|
||||
}
|
||||
|
||||
// get filesystem drivers for initrd
|
||||
#include "fs.h"
|
||||
|
||||
|
|
@ -1157,7 +1171,7 @@ LoadCore()
|
|||
}
|
||||
// if every driver failed, try brute force, scan for the first elf or pe executable
|
||||
if(core.ptr==NULL) {
|
||||
DBG(L" * Autodetecting kernel%s\n","");
|
||||
DBG(L" * Autodetecting kernel%s\n",L"");
|
||||
i=initrd.size;
|
||||
core.ptr=initrd.ptr;
|
||||
while(i-->0) {
|
||||
|
|
@ -1194,6 +1208,7 @@ LoadCore()
|
|||
core.size = phdr->p_filesz + (ehdr->e_type==3?0x4000:0);
|
||||
ptr = (UINT8*)ehdr + phdr->p_offset;
|
||||
bss = phdr->p_memsz - core.size;
|
||||
core_addr = phdr->p_vaddr;
|
||||
entrypoint = ehdr->e_entry;
|
||||
break;
|
||||
}
|
||||
|
|
@ -1230,6 +1245,7 @@ LoadCore()
|
|||
core.size = (pehdr->entry_point-pehdr->code_base) + pehdr->text_size + pehdr->data_size;
|
||||
ptr = core.ptr;
|
||||
bss = pehdr->bss_size;
|
||||
core_addr = (INT64)pehdr->code_base;
|
||||
entrypoint = (INT64)pehdr->entry_point;
|
||||
if(pehdr->sym_table > 0 && pehdr->numsym > 0) {
|
||||
pe_sym *s;
|
||||
|
|
@ -1244,9 +1260,12 @@ LoadCore()
|
|||
}
|
||||
}
|
||||
}
|
||||
if(ptr==NULL || core.size<2 || entrypoint==0 || (bb_addr>>30)!=0x3FFFFFFFF || (env_addr>>30)!=0x3FFFFFFFF ||
|
||||
(fb_addr>>30)!=0x3FFFFFFFF || (fb_addr & ~(1024*1024*2-1)))
|
||||
if(ptr==NULL || core.size<2 || entrypoint==0 || (core_addr&(PAGESIZE-1)) || (bb_addr>>30)!=0x3FFFFFFFF ||
|
||||
(bb_addr & (PAGESIZE-1)) || (env_addr>>30)!=0x3FFFFFFFF || (env_addr&(PAGESIZE-1)) || (fb_addr>>30)!=0x3FFFFFFFF ||
|
||||
(fb_addr&(1024*1024*2-1)))
|
||||
return report(EFI_LOAD_ERROR,L"Kernel is not a valid executable");
|
||||
if(core.size+bss > 16*1024*1024)
|
||||
return report(EFI_LOAD_ERROR,L"Kernel is too big");
|
||||
// create core segment
|
||||
uefi_call_wrapper(BS->AllocatePages, 4, 0, 2,
|
||||
(core.size + bss + PAGESIZE-1)/PAGESIZE, (EFI_PHYSICAL_ADDRESS*)&core.ptr);
|
||||
|
|
@ -1330,7 +1349,7 @@ efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
|||
EFI_MP_SERVICES_PROTOCOL *mp;
|
||||
UINT8 pibuffer[100];
|
||||
EFI_PROCESSOR_INFORMATION *pibuf=(EFI_PROCESSOR_INFORMATION*)pibuffer;
|
||||
UINTN bsp_num=0, i, j=0, handle_size=0,memory_map_size=0, map_key=0, desc_size=0;
|
||||
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;
|
||||
UINT64 lba_s=0,lba_e=0,sysptr;
|
||||
MMapEnt *mmapent, *last=NULL;
|
||||
|
|
@ -1718,44 +1737,48 @@ gzerr: return report(EFI_COMPROMISED_DATA,L"Unable to uncompress");
|
|||
}
|
||||
|
||||
// create page tables
|
||||
uefi_call_wrapper(BS->AllocatePages, 4, 0, 2, 23+(bootboot->numcores+3)/4, (EFI_PHYSICAL_ADDRESS*)&paging);
|
||||
uefi_call_wrapper(BS->AllocatePages, 4, 0, 2, 37+(bootboot->numcores+3)/4, (EFI_PHYSICAL_ADDRESS*)&paging);
|
||||
if (paging == NULL) {
|
||||
return report(EFI_OUT_OF_RESOURCES,L"AllocatePages");
|
||||
}
|
||||
ZeroMem((void*)paging,23*PAGESIZE);
|
||||
ZeroMem((void*)paging,37*PAGESIZE);
|
||||
DBG(L" * Pagetables PML4 @%lx\n",paging);
|
||||
//PML4
|
||||
paging[0]=(UINT64)((UINT8 *)paging+4*PAGESIZE)+3; // pointer to 2M PDPE (16G RAM identity mapped)
|
||||
paging[511]=(UINT64)((UINT8 *)paging+PAGESIZE)+3; // pointer to 4k PDPE (core mapped at -2M)
|
||||
//4k PDPE
|
||||
paging[512+511]=(UINT64)((UINT8 *)paging+2*PAGESIZE+3);
|
||||
//4k PDE
|
||||
for(i=0;i<31;i++)
|
||||
paging[2*512+480+i]=(UINT64)(((UINT8 *)(bootboot->fb_ptr)+(i<<21))+0x83); //map framebuffer
|
||||
paging[2*512+511]=(UINT64)((UINT8 *)paging+3*PAGESIZE+3);
|
||||
//4k PT
|
||||
paging[3*512+0]=(UINT64)(bootboot)+1;
|
||||
paging[3*512+1]=(UINT64)(env.ptr)+1;
|
||||
for(i=0;i<(core.size/PAGESIZE);i++)
|
||||
paging[3*512+2+i]=(UINT64)((UINT8 *)core.ptr+i*PAGESIZE+3);
|
||||
for(i=0; i<(UINTN)((bootboot->numcores+3)/4); i++)
|
||||
paging[3*512+511-i]=(UINT64)((UINT8 *)paging+(23+i)*PAGESIZE+3); // core stacks
|
||||
paging[0]=(UINT64)((UINT8 *)paging+PAGESIZE)+3; // pointer to 2M PDPE (16G RAM identity mapped)
|
||||
paging[511]=(UINT64)((UINT8 *)paging+20*PAGESIZE)+3; // pointer to 4k PDPE (core mapped at -2M)
|
||||
//identity mapping
|
||||
//2M PDPE
|
||||
for(i=0;i<16;i++)
|
||||
paging[4*512+i]=(UINT64)((UINT8 *)paging+(7+i)*PAGESIZE+3);
|
||||
paging[512+i]=(UINT64)((UINT8 *)paging+(3+i)*PAGESIZE+3);
|
||||
//first 2M mapped per page
|
||||
paging[7*512]=(UINT64)((UINT8 *)paging+5*PAGESIZE+3);
|
||||
paging[3*512]=(UINT64)((UINT8 *)paging+2*PAGESIZE+3);
|
||||
for(i=0;i<512;i++)
|
||||
paging[5*512+i]=(UINT64)(i*PAGESIZE+3);
|
||||
paging[2*512+i]=(UINT64)(i*PAGESIZE+3);
|
||||
//2M PDE
|
||||
for(i=1;i<512*16;i++)
|
||||
paging[7*512+i]=(UINT64)((i<<21)+0x83);
|
||||
paging[3*512+i]=(UINT64)((i<<21)+0x83);
|
||||
//kernel mapping
|
||||
//4k PDPE
|
||||
paging[20*512+511]=(UINT64)((UINT8 *)paging+22*PAGESIZE+3);
|
||||
//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+511]=(UINT64)((UINT8 *)paging+23*PAGESIZE+3);
|
||||
//4k PT
|
||||
//dynamically map these. Main struct, environment string and code segment
|
||||
for(i=0;i<(core.size/PAGESIZE);i++)
|
||||
MapPage(core_addr + i*PAGESIZE, (UINT64)((UINT8 *)core.ptr+i*PAGESIZE+3));
|
||||
MapPage(bb_addr, (UINT64)(bootboot)+1);
|
||||
MapPage(env_addr, (UINT64)(env.ptr)+1);
|
||||
// stack at the top of the memory
|
||||
for(i=0; i<(UINTN)((bootboot->numcores+3)/4); i++)
|
||||
paging[23*512+511-i]=(UINT64)((UINT8 *)paging+(37+i)*PAGESIZE+3); // core stacks
|
||||
|
||||
// Get memory map
|
||||
int cnt=3;
|
||||
get_memory_map:
|
||||
DBG(L" * Memory Map @%lx %d bytes #%d\n",memory_map, memory_map_size, 4-cnt);
|
||||
DBG(L" * Memory Map @%lx %d bytes try #%d\n",memory_map, memory_map_size, 4-cnt);
|
||||
mmapent=(MMapEnt *)&(bootboot->mmap);
|
||||
status = uefi_call_wrapper(BS->GetMemoryMap, 5,
|
||||
&memory_map_size, memory_map, &map_key, &desc_size, &desc_version);
|
||||
|
|
@ -1814,6 +1837,14 @@ get_memory_map:
|
|||
return report(status,L"ExitBootServices");
|
||||
}
|
||||
|
||||
// clear the screen
|
||||
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;
|
||||
j+=bootboot->fb_scanline;
|
||||
}
|
||||
|
||||
// release AP spinlock
|
||||
bsp_done = 1;
|
||||
bootboot_startcore((VOID*)bsp_num);
|
||||
|
|
|
|||
|
|
@ -28,51 +28,48 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef _FS_Z_H_
|
||||
/**
|
||||
* FS/Z initrd (OS/Z's native file system)
|
||||
*/
|
||||
file_t fsz_initrd(unsigned char *initrd_p, char *kernel)
|
||||
{
|
||||
FSZ_SuperBlock *sb = (FSZ_SuperBlock *)initrd_p;
|
||||
file_t ret = { NULL, 0 };
|
||||
if(initrd_p==NULL || CompareMem(sb->magic,FSZ_MAGIC,4) || kernel==NULL){
|
||||
if(initrd_p==NULL || CompareMem(initrd_p + 512,"FS/Z",4) || kernel==NULL){
|
||||
return ret;
|
||||
}
|
||||
unsigned char passphrase[256],chk[32],iv[32];
|
||||
UINT64 i,j,k,l,ss=1<<(sb->logsec+11);
|
||||
FSZ_DirEnt *ent;
|
||||
FSZ_Inode *in=(FSZ_Inode *)(initrd_p+sb->rootdirfid*ss);
|
||||
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(L" * FS/Z %s\n",a2u(kernel));
|
||||
//decrypt initrd
|
||||
while(sb->enchash!=0) {
|
||||
while(*((uint32_t*)(initrd_p+708))!=0) {
|
||||
Print(L" * Passphrase? ");
|
||||
l=ReadLine(passphrase,sizeof(passphrase));
|
||||
if(!l) {
|
||||
Print(L"\n");
|
||||
return ret;
|
||||
}
|
||||
if(sb->enchash!=crc32_calc((char*)passphrase,l)) {
|
||||
if(*((uint32_t*)(initrd_p+708))!=crc32_calc((char*)passphrase,l)) {
|
||||
Print(L"\rBOOTBOOT-ERROR: Bad passphrase\n");
|
||||
continue;
|
||||
}
|
||||
Print(L"\r * Decrypting...\r");
|
||||
SHA256_Init(&ctx);
|
||||
SHA256_Update(&ctx,passphrase,l);
|
||||
SHA256_Update(&ctx,&sb->magic,6);
|
||||
SHA256_Update(&ctx,initrd_p+512,6);
|
||||
SHA256_Final(chk,&ctx);
|
||||
for(i=0;i<sizeof(sb->encrypt);i++) sb->encrypt[i]^=chk[i];
|
||||
for(i=0;i<28;i++) initrd_p[i+680]^=chk[i];
|
||||
SHA256_Init(&ctx);
|
||||
SHA256_Update(&ctx,&sb->encrypt,sizeof(sb->encrypt));
|
||||
SHA256_Update(&ctx,initrd_p+680,28);
|
||||
SHA256_Final(iv,&ctx);
|
||||
if(sb->flags&FSZ_SB_EALG_AESCBC) {
|
||||
if(((initrd_p[518]>>2)&7)==1) {
|
||||
aes_init(iv);
|
||||
for(k=ss,j=1;j<sb->numsec;k+=ss,j++) {
|
||||
for(k=ss,j=1;j<*((uint32_t*)(initrd_p+528));k+=ss,j++) {
|
||||
aes_dec(initrd_p+k,ss);
|
||||
}
|
||||
} else {
|
||||
for(k=ss,j=1;j<sb->numsec;j++) {
|
||||
for(k=ss,j=1;j<*((uint32_t*)(initrd_p+528));j++) {
|
||||
CopyMem(chk,iv,32);
|
||||
for(i=0;i<ss;i++) {
|
||||
if(i%32==0) {
|
||||
|
|
@ -85,8 +82,8 @@ file_t fsz_initrd(unsigned char *initrd_p, char *kernel)
|
|||
}
|
||||
}
|
||||
}
|
||||
ZeroMem(sb->encrypt,sizeof(sb->encrypt)+4);
|
||||
sb->checksum=crc32_calc((char *)sb->magic,508);
|
||||
ZeroMem(initrd_p+680,28+4);
|
||||
*((uint32_t*)(initrd_p+1020))=crc32_calc((char *)initrd_p+512,508);
|
||||
Print(L" \r");
|
||||
}
|
||||
// Get the inode
|
||||
|
|
@ -96,60 +93,59 @@ file_t fsz_initrd(unsigned char *initrd_p, char *kernel)
|
|||
again:
|
||||
while(*e!='/'&&*e!=0){e++;}
|
||||
if(*e=='/'){e++;}
|
||||
if(!CompareMem(in->magic,FSZ_IN_MAGIC,4)){
|
||||
if(!CompareMem(in,"FSIN",4)){
|
||||
//is it inlined?
|
||||
if(!CompareMem(sb->flags&FSZ_SB_FLAG_BIGINODE? in->data.big.inlinedata : in->data.small.inlinedata,FSZ_DIR_MAGIC,4)){
|
||||
ent=(FSZ_DirEnt *)(sb->flags&FSZ_SB_FLAG_BIGINODE? in->data.big.inlinedata : in->data.small.inlinedata);
|
||||
} else if(!CompareMem(initrd_p+in->sec*ss,FSZ_DIR_MAGIC,4)){
|
||||
if(!CompareMem(initrd_p[518]&1? in + 2048 : in + 1024,"FSDR",4)){
|
||||
ent=(initrd_p[518]&1? in + 2048 : in + 1024);
|
||||
} else if(!CompareMem(initrd_p+*((uint64_t*)(in+448))*ss,"FSDR",4)){
|
||||
// go, get the sector pointed
|
||||
ent=(FSZ_DirEnt *)(initrd_p+in->sec*ss);
|
||||
ent=(initrd_p+*((uint64_t*)(in+448))*ss);
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
//skip header
|
||||
FSZ_DirEntHeader *hdr=(FSZ_DirEntHeader *)ent; ent++;
|
||||
unsigned char *hdr=ent; ent+=128;
|
||||
//iterate on directory entries
|
||||
int j=hdr->numentries;
|
||||
int j=*((uint64_t*)(hdr+16));
|
||||
while(j-->0){
|
||||
if(!CompareMem(ent->name,s,e-s)) {
|
||||
if(!CompareMem(ent + 17,s,e-s)) {
|
||||
if(*e==0) {
|
||||
i=ent->fid;
|
||||
i=*((uint64_t*)(ent+0));
|
||||
break;
|
||||
} else {
|
||||
s=e;
|
||||
in=(FSZ_Inode *)(initrd_p+ent->fid*ss);
|
||||
in=(initrd_p+*((uint64_t*)(ent+0))*ss);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
ent++;
|
||||
ent+=128;
|
||||
}
|
||||
} else {
|
||||
i=0;
|
||||
}
|
||||
if(i!=0) {
|
||||
// fid -> inode ptr -> data ptr
|
||||
FSZ_Inode *in=(FSZ_Inode *)(initrd_p+i*ss);
|
||||
if(!CompareMem(in->magic,FSZ_IN_MAGIC,4)){
|
||||
ret.size=in->size;
|
||||
switch(FSZ_FLAG_TRANSLATION(in->flags)) {
|
||||
case FSZ_IN_FLAG_INLINE:
|
||||
unsigned char *in=(initrd_p+i*ss);
|
||||
if(!CompareMem(in,"FSIN",4)){
|
||||
ret.size=*((uint64_t*)(in+464));
|
||||
switch(in[488]) {
|
||||
case 0xFF:
|
||||
// inline data
|
||||
ret.ptr=(UINT8*)(initrd_p+i*ss+1024);
|
||||
ret.ptr=(uint8_t*)(initrd_p+i*ss+(initrd_p[518]&1? 2048 : 1024));
|
||||
break;
|
||||
case FSZ_IN_FLAG_SECLIST:
|
||||
case FSZ_IN_FLAG_SDINLINE:
|
||||
case 0x80:
|
||||
case 0x7F:
|
||||
// sector directory or list inlined
|
||||
ret.ptr=(UINT8*)(initrd_p + *(sb->flags&FSZ_SB_FLAG_BIGINODE?
|
||||
(UINT64*)&in->data.big.inlinedata : (UINT64*)&in->data.small.inlinedata) * ss);
|
||||
ret.ptr=(uint8_t*)(initrd_p + *((uint64_t*)(initrd_p[518]&1? in + 2048 : in + 1024))*ss);
|
||||
break;
|
||||
case FSZ_IN_FLAG_DIRECT:
|
||||
case 0:
|
||||
// direct data
|
||||
ret.ptr=(UINT8*)(initrd_p + in->sec * ss);
|
||||
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 FSZ_IN_FLAG_SECLIST0:
|
||||
case FSZ_IN_FLAG_SD:
|
||||
ret.ptr=(UINT8*)(initrd_p + (unsigned int)(((FSZ_SectorList *)(initrd_p+in->sec*ss))->sec) * ss);
|
||||
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;
|
||||
|
|
@ -159,7 +155,6 @@ again:
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* cpio archive
|
||||
|
|
@ -289,9 +284,7 @@ file_t jamesm_initrd(unsigned char *initrd_p, char *kernel)
|
|||
* Static file system drivers registry
|
||||
*/
|
||||
file_t (*fsdrivers[]) (unsigned char *, char *) = {
|
||||
#ifdef _FS_Z_H_
|
||||
fsz_initrd,
|
||||
#endif
|
||||
cpio_initrd,
|
||||
tar_initrd,
|
||||
sfs_initrd,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue