4.9 KiB
Shelter boot contract
Introduction
The Shelter boot contract is the list of steps necessary in order to successfully boot Shelter.
Prerequisites
We assume the following:
- you understand the concept of pages table pool, Shelter boot configuration and Shelter memory map
- you have a bootloader capable of mapping things into into pages table pool
- your bootloader is capable of generating Shelter boot configuration and Shelter memory map
- your bootloader is capable of allocating or call the UEFI firmware to allocates pages to copy data into them
- your bootloader is capable of parsing VYX executable
- your bootloader is capable of accessing the content of the Shelter VYX executable and keycard binary While this documentation is redacted like a tutorial, this isn't a tutorial nor intended to be understand as one.
Step 1: allocate pages
Your bootloader should be allocating 4KB physical pages ranges and store their physical start address for the following elements with the following type if you use the AllocatePages from the EFI firmware:
- pages for
.textsection should beEfiLoaderCodetype - pages for
.data,.rodata,.bsssections should beEfiLoaderDatatype - pages for stack should be
EfiLoaderCoetype. The standard amount of stack pages is 64 - page(s) for keycard should be
EfiLoaderCodetype. Keycard should fit into one page, but you are free to allocate more if you want - page(s) for Shelter boot configuration, memory map and pages table pool should be
EfiLoaderCode. Shelter boot configuration should fit into one page, but you are free to allocate more if you want - pages for Shelter logging ring should be
EfiLoaderCodetype
Note: even if the logging ring size specified in the configuration is less than 4 pages, at least 4 pages should be allocated, because the kernel logs some things before loading the boot configuration that specify that log in ring buffer is disabled
Step 2: prepare pages
The following steps should be completed before mapping the pages:
- zeroing the
.bsssection pages range - zeroing the stack pages range
- zeroing the entire memory map pages range
- zeroing the entire logging ring buffer
- copying the content of the
.text,.dataand.rodatasection inside their respectives pages range - copying the content of Keycard inside his pages range
- copying the content of the boot configuration inside his pages range
Step 3: mapping pages
The prerequisites to this step is having a PTP-compatible page mapping function. A working implementation can be found in the Blastproof/src/libs/src/vyx.c file.
The following pages ranges will be mapped at the following virtual address in the following order:
- the pages table pool pages range should be mapped first at the virtual address computed like this
text_base + text_size + data_size + rodata_size + bss_size + 0x200000wheretext_baseis the base VA of the.textsection and the differents sizes are the size of each section, padded to the nearest 4096 bytes (normally it's already the case in the VYX executable header). It should be mapped in read-write with no execution permissions - the
.textsection should be mapped at the VA indicated bytext_base, with execution but read-only permissions - the
.datasection should be mapped at the VA indicated bytext_base + text_size, with no execution and read write permissions - the
.rodatasection should be mapped at the VA indicated bytext_base + text_size + data_sizewith no execution and read-only permissions - the
.bsssection should be mapped at the VA indicated bytext_base + text_size + data_size + rodata_size, with no execution and read-write permissions - the 64 pages of the stack should be mapped at the VA indicated by
stack_base, with no execution and read-write permissions - Keycard pages ranges should be identity mapped to the same virtual address as his physical address, with execution but read-only permissions
- Shelter boot configuration pages should be mapped at VA
0x00180000, with no execution and read-write permissions - memory map pages should be mapped at VA
0x00190000, with no execution and read-only permissions - logging ring pages should be mapped at VA
0xFFFFFFFFF0000000, with no execution and read-write permissions
Step 4: completing configuration
The boot configuration should be completed with the PTP physical and virtual address as well as the level of the counter allocator of the PTP. Don't forget to update the boot configuration already copied inside the boot configuration pages range.
Step 5: generating memory map
After obtaining the EFI memory map, the memory map should be generated inside her dedicated pages range. The complete syntax of the Shelter memory map can be found here.
Step 6: jump
Once all of this is done, the bootloader can exit the EFI boot services, prepare the register and jump to Keycard. The details about completing the registers is provided here.