Delta Boot Protocol
Overview
The DB protocol defines:
- DB Request Header — Embedded in the kernel binary, tells the bootloader what's needed
- DB Boot Info — Passed to the kernel at boot, contains system information as tags
┌──────────────────────────────────────────────────────────────┐
│ KERNEL BINARY │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ DB Request Header (magic + version + flags) │ │
│ │ Request Tags: what the kernel wants from bootloader │ │
│ └────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
│
▼ bootloader reads & prepares
┌──────────────────────────────────────────────────────────────┐
│ DB BOOT INFO │
│ Passed to kernel entry point (pointer in arch-defined reg) │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Info Header │ │
│ ├────────────────────────────────────────────────────────┤ │
│ │ Tag: Memory Map │ │
│ │ Tag: Framebuffer │ │
│ │ Tag: Command Line │ │
│ │ Tag: ... │ │
│ │ Tag: End │ │
│ └────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
Data Types
All multi-byte integers are little-endian=
| Type | Size | Description |
|---|---|---|
u8 |
1 byte | Unsigned 8-bit |
u16 |
2 bytes | Unsigned 16-bit LE |
u32 |
4 bytes | Unsigned 32-bit LE |
u64 |
8 bytes | Unsigned 64-bit LE |
Part 1: DB Request Header
The kernel embeds this header to identify itself as DB-compliant and request features.
Location
The bootloader scans the first 32 KiB of the kernel binary for the magic number, Header must be 8-byte aligned.
Structure
struct db_request_header {
u32 magic; // 0x44420001 ('D' 'B' 0x00 0x01)
u32 checksum; // CRC32 of header + tags (with this field as 0)
u16 version; // Protocol version (0x0001 for v0.1)
u16 header_size; // Size of this header + all request tags
u32 flags; // Request flags (see below)
u32 entry_point; // Offset (not address!) of kernel entry point
// Relative to start of loaded kernel image
// Use 0xFFFFFFFF if bootloader should use format-specific entry
};
// Followed by request tags (until header_size is reached)
Magic breakdown: 0x44420001
- 0x44 = 'D'
- 0x42 = 'B'
- 0x00 = null separator
- 0x01 = format version
Checksum
The checksum field contains a CRC32 (polynomial 0xEDB88320)
computed over the entire header including request tags, with the checksum field itself
treated as zero during computation.
To compute:
1. Set checksum to 0
2. Calculate CRC32 over bytes [0, header_size)
3. Store result in checksum
To verify:
1. Save checksum value
2. Set checksum to 0
3. Calculate CRC32 over bytes [0, header_size)
4. Compare with saved value
Request Flags
| Bit | Name | Description |
|---|---|---|
| 0 | DB_REQ_FRAMEBUFFER |
Kernel requests framebuffer info |
| 1 | DB_REQ_MEMORY_MAP |
Kernel requests memory map (should always be set) |
| 2 | DB_REQ_MODULES |
Kernel supports loaded modules |
| 3 | DB_REQ_ACPI |
Kernel requests ACPI RSDP pointer |
| 4 | DB_REQ_CMDLINE |
Kernel accepts command line |
| 5 | DB_REQ_SMP |
Kernel requests SMP info (CPU count, etc.) |
| 6 | DB_REQ_INITRD |
Kernel requests initial ramdisk |
| 7 | DB_REQ_HAS_TAGS |
Request tags follow the header |
| 8-31 | Reserved | Must be zero |
Flags and Tags Precedence
- Flag set, no tag: Bootloader provides the feature with default values
- Flag set, tag present: Bootloader uses tag values (tag refines the request)
- Flag not set, tag present: Tag is ignored (flag must be set to enable feature)
Part 1b: Request Tags
Request tags allow the kernel to specify detailed requirements beyond simple flags.
They immediately follow the request header and are included in header_size.
Request Tag Structure
struct db_request_tag {
u16 type; // Request tag type
u16 flags; // Tag-specific flags
u32 size; // Total size of this tag (including header)
// Tag-specific data follows
};
Alignment: Each request tag starts at a 4-byte aligned offset from header start
Request Tag Types
| Type | Name | Description |
|---|---|---|
| 0x0000 | DB_RTAG_END |
End of request tag list |
| 0x0001 | DB_RTAG_FRAMEBUFFER_PREF |
Preferred framebuffer settings |
| 0x0002 | DB_RTAG_MIN_MEMORY |
Minimum memory requirement |
| 0x0003 | DB_RTAG_LOAD_ADDRESS |
Preferred/required load address |
| 0x0004 | DB_RTAG_STACK_SIZE |
Requested initial stack size |
| 0x0005 | DB_RTAG_ARCH_FEATURES |
Architecture-specific feature requests |
DB_RTAG_FRAMEBUFFER_PREF (0x0001)
Specify preferred framebuffer resolution and pixel format.
struct db_rtag_framebuffer_pref {
u16 type; // 0x0001
u16 flags; // Bit 0: required (fail if unavailable)
u32 size; // 28
u32 min_width; // Minimum acceptable width (0 = any)
u32 min_height; // Minimum acceptable height (0 = any)
u32 preferred_width; // Preferred width (0 = any)
u32 preferred_height; // Preferred height (0 = any)
u8 min_bpp; // Minimum bits per pixel (0 = any)
u8 preferred_bpp; // Preferred bpp (0 = any)
u8 padding[2];
};
DB_RTAG_MIN_MEMORY (0x0002)
Specify minimum RAM requirement.
struct db_rtag_min_memory {
u16 type; // 0x0002
u16 flags; // 0
u32 size; // 16
u64 min_bytes; // Minimum usable RAM required
};
DB_RTAG_LOAD_ADDRESS (0x0003)
Request a specific load address (hint or requirement).
struct db_rtag_load_address {
u16 type; // 0x0003
u16 flags; // Bit 0: required (fail if unavailable)
u32 size; // 24
u64 preferred_addr; // Preferred physical load address
u64 alignment; // Required alignment (must be power of 2)
};
DB_RTAG_STACK_SIZE (0x0004)
Request initial kernel stack size.
struct db_rtag_stack_size {
u16 type; // 0x0004
u16 flags; // 0
u32 size; // 16
u64 stack_size; // Requested stack size in bytes (0 = bootloader default)
};
Part 2: DB Boot Info
Prepared by the bootloader and passed to the kernel.
Passing Convention
The bootloader passes a pointer to db_boot_info in an architecture-defined register:
| Architecture | Register | Notes |
|---|---|---|
| x86 (32-bit) | EBX |
Physical address |
| x86_64 | RDI |
Physical address (first arg) |
| ARM32 | R0 |
Physical address |
| AArch64 | X0 |
Physical address |
| RISC-V | A0 |
Physical address |
Info Header Structure
struct db_boot_info {
u32 magic; // 0x44424F4B ('D' 'B' 'O' 'K' — "DB OK")
u32 total_size; // Total size of boot info including all tags
u32 version; // Protocol version
u32 reserved; // Must be zero
};
// Immediately followed by tags
Part 3: Tags
Tags are variable-length structures that follow the header.
Tag Structure
struct db_tag {
u16 type; // Tag type identifier
u16 flags; // Tag-specific flags
u32 size; // Total size of this tag (including header)
// Tag-specific data follows
};
Alignment: Each tag starts at an 8-byte aligned address.
Padding: Bootloader inserts padding bytes (value 0) between tags as needed.
Tag Types
| Type | Name | Description |
|---|---|---|
| 0x0000 | DB_TAG_END |
End of tag list |
| 0x0001 | DB_TAG_CMDLINE |
Command line string |
| 0x0002 | DB_TAG_MEMORY_MAP |
System memory map |
| 0x0003 | DB_TAG_FRAMEBUFFER |
Framebuffer information |
| 0x0004 | DB_TAG_MODULES |
Loaded modules (generic) |
| 0x0005 | DB_TAG_ACPI_RSDP |
ACPI RSDP pointer |
| 0x0006 | DB_TAG_SMP |
SMP/CPU information |
| 0x0007 | DB_TAG_BOOT_TIME |
Boot timestamp |
| 0x0008 | DB_TAG_BOOTLOADER |
Bootloader name/version |
| 0x0009 | DB_TAG_KERNEL_FILE |
Original kernel file info |
| 0x000A | DB_TAG_EFI_SYSTEM_TABLE |
EFI System Table pointer (if UEFI) |
| 0x000B | DB_TAG_INITRD |
Initial ramdisk (initrd/initramfs) |
| 0x000C | DB_TAG_KERNEL_PHYS |
Physical memory footprint of kernel |
| 0x8000+ | Vendor-specific | Reserved for custom extensions |
Tag Definitions
DB_TAG_END (0x0000)
Marks the end of the tag list. Required.
struct db_tag_end {
u16 type; // 0x0000
u16 flags; // 0
u32 size; // 8
};
DB_TAG_CMDLINE (0x0001)
Null-terminated command line string.
struct db_tag_cmdline {
u16 type; // 0x0001
u16 flags; // 0
u32 size; // 8 + string length + 1 (null terminator)
char cmdline[]; // Null-terminated UTF-8 string
};
DB_TAG_MEMORY_MAP (0x0002)
Describes physical memory layout.
struct db_tag_memory_map {
u16 type; // 0x0002
u16 flags; // 0
u32 size; // Total tag size
u32 entry_size; // Size of each entry (for forward compat)
u32 entry_count; // Number of entries
struct db_mmap_entry entries[];
};
struct db_mmap_entry {
u64 base; // Physical base address
u64 length; // Length in bytes
u32 type; // Memory type (see below)
u32 attributes; // Additional attributes
};
Memory Types:
| Value | Name | Description |
|---|---|---|
| 0 | DB_MEM_RESERVED |
Reserved, do not use |
| 1 | DB_MEM_USABLE |
Free RAM, available for use |
| 2 | DB_MEM_ACPI_RECLAIMABLE |
ACPI tables, reclaimable |
| 3 | DB_MEM_ACPI_NVS |
ACPI Non-Volatile Storage |
| 4 | DB_MEM_BAD |
Bad memory, do not use |
| 5 | DB_MEM_BOOTLOADER |
Used by bootloader, reclaimable |
| 6 | DB_MEM_KERNEL |
Kernel image |
| 7 | DB_MEM_FRAMEBUFFER |
Framebuffer memory |
| 8 | DB_MEM_INITRD |
Initial ramdisk, reclaimable |
| 9 | DB_MEM_MODULES |
Loaded modules |
DB_TAG_FRAMEBUFFER (0x0003)
Framebuffer information for graphical output.
struct db_tag_framebuffer {
u16 type; // 0x0003
u16 flags; // 0
u32 size; // Tag size
u64 address; // Physical address of framebuffer
u32 width; // Width in pixels
u32 height; // Height in pixels
u32 pitch; // Bytes per scanline
u8 bpp; // Bits per pixel
u8 red_shift; // Red component bit position
u8 red_size; // Red component bit size
u8 green_shift;
u8 green_size;
u8 blue_shift;
u8 blue_size;
u8 reserved_shift;
u8 reserved_size;
u8 padding[3]; // Alignment padding
};
DB_TAG_MODULES (0x0004)
Loaded boot modules (initramfs, drivers, etc.).
struct db_tag_modules {
u16 type; // 0x0004
u16 flags; // 0
u32 size; // Total tag size
u32 module_count; // Number of modules
u32 reserved;
struct db_module modules[];
};
struct db_module {
u64 start; // Physical start address
u64 end; // Physical end address (exclusive)
u32 name_offset; // Offset to null-terminated name string (from tag start)
u32 cmdline_offset; // Offset to null-terminated cmdline (from tag start)
};
// Module names and cmdlines stored as strings after the module array
DB_TAG_INITRD (0x000B)
Initial ramdisk (initrd or initramfs) This is the primary way to load a initial filesystem for early boot.
struct db_tag_initrd {
u16 type; // 0x000B
u16 flags; // 0
u32 size; // Tag size
u64 start; // Physical start address of initrd
u64 length; // Size in bytes
};
Notes:
- The bootloader loads the initrd file into contiguous physical memory
- The kernel is responsible for parsing the format (cpio, ext2, etc.)
- Memory region is marked as DB_MEM_INITRD in the memory map (reclaimable after use)
DB_TAG_KERNEL_PHYS (0x000C)
Provides the exact physical memory footprint of the loaded kernel. This is used by the kernel to reserve its own physical pages in the memory manager.
struct db_tag_kernel_phys {
u16 type; // 0x000C
u16 flags; // 0
u32 size; // Tag size (24)
u64 phys_base; // Physical start address of kernel
u64 phys_length; // Total length in bytes
};
DB_TAG_ACPI_RSDP (0x0005)
ACPI Root System Description Pointer.
struct db_tag_acpi_rsdp {
u16 type; // 0x0005
u16 flags; // Bit 0: set if XSDP (ACPI 2.0+)
u32 size; // Tag size
u64 rsdp_address; // Physical address of RSDP/XSDP
};
DB_TAG_SMP (0x0006)
Symmetric Multi Processing information.
struct db_tag_smp {
u16 type; // 0x0006
u16 flags; // 0
u32 size; // Tag size
u32 cpu_count; // Number of CPUs
u32 bsp_id; // Bootstrap processor ID
struct db_cpu cpus[];
};
struct db_cpu {
u32 id; // CPU/APIC ID (arch-specific)
u32 flags; // Bit 0: enabled, Bit 1: is BSP
};
DB_TAG_BOOTLOADER (0x0008)
Bootloader identification.
struct db_tag_bootloader {
u16 type; // 0x0008
u16 flags; // 0
u32 size; // Tag size
char name[]; // Null-terminated bootloader name/version
};
Minimal Kernel Example (Pseudocode)
// Entry point receives db_boot_info pointer
void kernel_main(struct db_boot_info* info) {
// Verify magic
if (info->magic != 0x44424F4B) {
panic("Not booted via DB protocol");
}
// Iterate tags
struct db_tag* tag = (void*)info + sizeof(*info);
while (tag->type != DB_TAG_END) {
switch (tag->type) {
case DB_TAG_MEMORY_MAP:
parse_memory_map((struct db_tag_memory_map*)tag);
break;
case DB_TAG_FRAMEBUFFER:
init_framebuffer((struct db_tag_framebuffer*)tag);
break;
//... handle other tags
}
// Advance to next tag (8-byte aligned)
tag = (void*)tag + ((tag->size + 7) & ~7);
}
}
Bootloader Requirements
A DB-compliant bootloader must:
- Locate the DB Request Header in the kernel binary (first 32 KiB, 8-byte aligned)
- Verify the magic (
0x44420001) - Load the kernel into memory at an appropriate address (bootloader's choice)
- Prepare DB Boot Info with requested tags based on request flags
- Set up machine state:
- Interrupts disabled
- Paging enabled with identity mapping (virtual = physical)
- A20 line enabled (if x86)
- Pass boot info pointer in the architecture-defined register
- Jump to kernel entry point
Load Address
The bootloader chooses where to load the kernel in physical memory. The kernel must be
position-independent or linked to expect this. The kernel can determine its load address
from the memory map (look for DB_MEM_KERNEL regions).