freeloader/notes.md

212 lines
5.7 KiB
Markdown

# Loader notes
## Modinfo
Loader must provide modinfo to kernel, a TLV structure
* Dump from normal FreeBSD with `sysctl debug.dump_modinfo`
* Tag is `MODINFO_*` or `MODINFO_METADATA | MODINFOMD_*`
* Tag and length are 4 bytes native endian
* Value is padded to align to `sizeof(size_t)`
* Strings are null-terminated
* Encodes multiple modules in sequence, separated by `MODINFO_NAME` string
### Fields
* `MODINFO_NAME`: string with path to file if available
* `MODINFO_TYPE`: string with type, like `elf kernel`
* `MODINFO_ADDR`: usize with base virtual address of object
* `MODINFO_SIZE`: usize with size of object, for elf based on end of final load section
* `MODINFOMD_EFI_MAP`: UEFI memory map, as comes from `GetMemoryMap`
* `MODINFOMD_EFI_FB`: Some structure describing UEFI framebuffer
* `MODINFOMD_KEYBUF`: `struct keybuf` object with cached keys, don't really need it
* `MODINFOMD_FW_HANDLE`: physical address of RuntimeServices system table
* `MODINFOMD_MODULEP`: Base physical address of TLV structure, only seems to matter for x86\_64 Xen
* `MODINFOMD_KERNEND`: Last physical address of kernel, should be free after
* `MODINFOMD_HOWTO`: u32 with a bunch of bitflags that start with `RB_` in `sys/sys/reboot.h`
* `MODINFOMD_ELFHDR`: copy of the elf header
* `MODINFOMD_DYNAMIC`: base virtual address of `PT_DYNAMIC` segment
* `MODINFOMD_SSYM`: start virtual address of symtab/strtab
* symtab is section with `SHT_SYMTAB`, strtab is linked section
* Both have length prepended (as usize) and are aligned to usize
* `MODINFOMD_ESYM`: end virtual address of symbols
* `MODINFOMD_SHDR`: the section header table
## Kernel
Kernel must be loaded into memory at offset divisible by 2 MiB
* yes, the loader zeroes bss
## Architecture specific
Tons of arch-specific restrictions
### `x86_64`
* Pointers are passed as 32-bit, must be within the first 4G
* First 4G of virtual memory must be identity mapped
* Kernel virtual address must also be mapped to kernel (normally `0xffff_ffff_8000_0000`)
## Sample kernel
modinfo:
```
0xffffffff8282b000:
type: (0x01) MODINFO_NAME
len: 20
value: /boot/kernel/kernel
0xffffffff8282b020:
type: (0x02) MODINFO_TYPE
len: 11
value: elf kernel
0xffffffff8282b038:
type: (0x03) MODINFO_ADDR
len: 8
value: 0xffffffff80200000
0xffffffff8282b048:
type: (0x04) MODINFO_SIZE
len: 8
value: 32731368
0xffffffff8282b058:
type: (0x9004) MODINFO_METADATA | MODINFOMD_EFI_MAP
len: 6080
value: buffer contents omitted
0xffffffff8282c820:
type: (0x9005) MODINFO_METADATA | MODINFOMD_EFI_FB
len: 48
value: 0x0000000084000000
0xffffffff8282c858:
type: (0x800d) MODINFO_METADATA | MODINFOMD_KEYBUF
len: 33028
value: buffer contents omitted
0xffffffff82834968:
type: (0x800c) MODINFO_METADATA | MODINFOMD_FW_HANDLE
len: 8
value: buffer contents omitted
0xffffffff82834978:
type: (0x9006) MODINFO_METADATA | MODINFOMD_MODULEP
len: 8
value:
0xffffffff82834988:
type: (0x8008) MODINFO_METADATA | MODINFOMD_KERNEND
len: 8
value: 0x0000000002837000
0xffffffff82834998:
type: (0x8006) MODINFO_METADATA | MODINFOMD_ENVP
len: 8
value: 0x000000000282a000
0xffffffff828349a8:
type: (0x8007) MODINFO_METADATA | MODINFOMD_HOWTO
len: 4
value: 0x20000000
0xffffffff828349b8:
type: (0x8002) MODINFO_METADATA | MODINFOMD_ELFHDR
len: 64
value: buffer contents omitted
0xffffffff82834a00:
type: (0x8005) MODINFO_METADATA | MODINFOMD_DYNAMIC
len: 8
value: 0xffffffff81600000
0xffffffff82834a10:
type: (0x8004) MODINFO_METADATA | MODINFOMD_ESYM
len: 8
value: 0xffffffff821370e8
0xffffffff82834a20:
type: (0x8003) MODINFO_METADATA | MODINFOMD_SSYM
len: 8
value: 0xffffffff81e00000
0xffffffff82834a30:
type: (0x8009) MODINFO_METADATA | MODINFOMD_SHDR
len: 3904
value: buffer contents omitted
0xffffffff82835978:
type: (0x01) MODINFO_NAME
len: 20
value: /boot/kernel/zfs.ko
0xffffffff82835998:
type: (0x02) MODINFO_TYPE
len: 15
value: elf obj module
0xffffffff828359b0:
type: (0x03) MODINFO_ADDR
len: 8
value: 0xffffffff82138000
0xffffffff828359c0:
type: (0x04) MODINFO_SIZE
len: 8
value: 6084104
0xffffffff828359d0:
type: (0x8002) MODINFO_METADATA | MODINFOMD_ELFHDR
len: 64
value: buffer contents omitted
0xffffffff82835a18:
type: (0x8009) MODINFO_METADATA | MODINFOMD_SHDR
len: 1984
value: buffer contents omitted
0xffffffff828361e0:
type: (0x01) MODINFO_NAME
len: 26
value: /boot/kernel/cryptodev.ko
0xffffffff82836208:
type: (0x02) MODINFO_TYPE
len: 15
value: elf obj module
0xffffffff82836220:
type: (0x03) MODINFO_ADDR
len: 8
value: 0xffffffff82706000
0xffffffff82836230:
type: (0x04) MODINFO_SIZE
len: 8
value: 30680
0xffffffff82836240:
type: (0x8002) MODINFO_METADATA | MODINFOMD_ELFHDR
len: 64
value: buffer contents omitted
0xffffffff82836288:
type: (0x8009) MODINFO_METADATA | MODINFOMD_SHDR
len: 1856
value: buffer contents omitted
0xffffffff828369d0:
type: (0x01) MODINFO_NAME
len: 12
value: /etc/hostid
0xffffffff828369e8:
type: (0x02) MODINFO_TYPE
len: 9
value: hostuuid
0xffffffff82836a00:
type: (0x03) MODINFO_ADDR
len: 8
value: 0xffffffff8270d7d8
0xffffffff82836a10:
type: (0x04) MODINFO_SIZE
len: 8
value: 37
0xffffffff82836a20:
type: (0x01) MODINFO_NAME
len: 14
value: /boot/entropy
0xffffffff82836a38:
type: (0x02) MODINFO_TYPE
len: 19
value: boot_entropy_cache
0xffffffff82836a58:
type: (0x03) MODINFO_ADDR
len: 8
value: 0xffffffff8270d7fd
0xffffffff82836a68:
type: (0x04) MODINFO_SIZE
len: 8
value: 4096
0xffffffff82836a78:
type: (0x01) MODINFO_NAME
len: 6
value: TSLOG
0xffffffff82836a88:
type: (0x02) MODINFO_TYPE
len: 11
value: TSLOG data
0xffffffff82836aa0:
type: (0x03) MODINFO_ADDR
len: 8
value: 0xffffffff8270e7fd
0xffffffff82836ab0:
type: (0x04) MODINFO_SIZE
len: 8
value: 1159497
```