freeloader/notes.md

5.6 KiB

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 modinfo, probably
  • 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