From 9363b8c4db0b497da2eef93f0eaaa6d6b650362f Mon Sep 17 00:00:00 2001 From: mintsuki Date: Fri, 15 Jan 2021 04:17:49 +0100 Subject: [PATCH] misc: stivale specifications moved to stivale/stivale --- STIVALE.md | 249 +------------------------ STIVALE2.md | 523 +--------------------------------------------------- 2 files changed, 2 insertions(+), 770 deletions(-) diff --git a/STIVALE.md b/STIVALE.md index 5784604b..59f91385 100644 --- a/STIVALE.md +++ b/STIVALE.md @@ -1,248 +1 @@ -# stivale boot protocol specification - -The stivale boot protocol aims to be a *simple* to implement protocol which -provides the kernel with most of the features one may need in a *modern* -x86_64 context (although 32-bit x86 is also supported). - -## General information - -In order to have a stivale compliant kernel, one must have a kernel executable -in the `elf64` or `elf32` format and have a `.stivalehdr` section (described below). -Other executable formats are not supported. - -stivale will recognise whether the ELF file is 32-bit or 64-bit and load the kernel -into the appropriate CPU mode. - -stivale natively supports (only for 64-bit kernels) and encourages higher half kernels. -The kernel can load itself at `0xffffffff80000000` (as defined in the linker script) -and the bootloader will take care of everything, no AT linker script directives needed. - -If the kernel loads itself in the lower half, the bootloader will not perform the -higher half relocation. - -*Note: In order to maintain compatibility with Limine and other stivale-compliant* -*bootloaders it is strongly advised never to load the kernel or any of its* -*sections below the 1 MiB physical memory mark. This may work with some stivale* -*loaders, but it WILL NOT work with Limine and it's explicitly discouraged.* - -## Kernel entry machine state - -### 64-bit kernel - -`rip` will be the entry point as defined in the ELF file, unless the `entry_point` -field in the stivale header is set to a non-0 value, in which case, it is set to -the value of `entry_point`. - -At entry, the bootloader will have setup paging mappings as such: - -``` - Base Physical Address - Size -> Virtual address - 0x0000000000000000 - 4 GiB plus any additional memory map entry -> 0x0000000000000000 - 0x0000000000000000 - 4 GiB plus any additional memory map entry -> 0xffff800000000000 (4-level paging only) - 0x0000000000000000 - 4 GiB plus any additional memory map entry -> 0xff00000000000000 (5-level paging only) - 0x0000000000000000 - 0x80000000 -> 0xffffffff80000000 -``` - -If the kernel is dynamic and not statically linked, the bootloader will relocate it, -potentially performing KASLR (as specified by the config). - -The kernel should NOT modify the bootloader page tables, and it should only use them -to bootstrap its own virtual memory manager and its own page tables. - -At entry all segment registers are loaded as 64 bit code/data segments, limits and -bases are ignored since this is Long Mode. - -DO NOT reload segment registers or rely on the provided GDT. The kernel MUST load -its own GDT as soon as possible and not rely on the bootloader's. - -The IDT is in an undefined state. Kernel must load its own. - -IF flag, VM flag, and direction flag are cleared on entry. Other flags undefined. - -PG is enabled (`cr0`), PE is enabled (`cr0`), PAE is enabled (`cr4`), -LME is enabled (`EFER`). -If stivale header flag bit 1 is set, then, if available, 5-level paging is enabled -(LA57 bit in `cr4`). - -The A20 gate is enabled. - -PIC/APIC IRQs are all masked. - -`rsp` is set to the requested stack as per stivale header. If the requested value is -non-null, an invalid return address of 0 is pushed to the stack before jumping -to the kernel. - -`rdi` will point to the stivale structure (described below). - -All other general purpose registers are set to 0. - -### 32-bit kernel - -`eip` will be the entry point as defined in the ELF file, unless the `entry_point` -field in the stivale header is set to a non-0 value, in which case, it is set to -the value of `entry_point`. - -At entry all segment registers are loaded as 32 bit code/data segments. -All segment bases are `0x00000000` and all limits are `0xffffffff`. - -DO NOT reload segment registers or rely on the provided GDT. The kernel MUST load -its own GDT as soon as possible and not rely on the bootloader's. - -The IDT is in an undefined state. Kernel must load its own. - -IF flag, VM flag, and direction flag are cleared on entry. Other flags undefined. - -PE is enabled (`cr0`). - -The A20 gate is enabled. - -PIC/APIC IRQs are all masked. - -`esp` is set to the requested stack as per stivale header. An invalid return address -of 0 is pushed to the stack before jumping to the kernel. - -A pointer to the stivale structure (described below) is pushed onto this stack -before the entry point is called. - -All other general purpose registers are set to 0. - -## Bootloader-reserved memory - -In order for stivale to function, it needs to reserve memory areas for either internal -usage (such as page tables, GDT), or for kernel interfacing (such as returned -structures). - -stivale ensures that none of these areas are found in any of the sections -marked as "usable" or "kernel/modules" in the memory map. - -The location of these areas may vary and it is implementation specific; -these areas may be in any non-usable memory map section (except kernel/modules), -or in unmarked memory. - -The OS must make sure to be done consuming bootloader information and services -before switching to its own address space, as unmarked memory areas in use by -the bootloader may become unavailable. - -Once the OS is done needing the bootloader, memory map areas marked as "bootloader -reclaimable" may be used as usable memory. These areas are guaranteed to be -4096-byte aligned (both base and length), and they are guaranteed to not overlap -other sections of the memory map. - -## stivale header (.stivalehdr) - -The kernel executable shall have a section `.stivalehdr` which will contain -the header that the bootloader will parse. - -Said header looks like this: -```c -struct stivale_header { - uint64_t stack; // This is the stack address which will be in ESP/RSP - // when the kernel is loaded. - // It can only be set to NULL for 64-bit kernels. 32-bit - // kernels are mandated to provide a vaild stack. - // 64-bit and 32-bit valid stacks must be at least 256 bytes - // in usable space and must be 16 byte aligned addresses. - - uint16_t flags; // Flags - // bit 0 0 = text mode, 1 = graphics framebuffer mode - // bit 1 0 = 4-level paging, 1 = use 5-level paging (if - // available) - // Ignored if booting a 32-bit kernel. - // bit 2 Formerly used to indicate whether to enable KASLR, - // this flag is now reserved as KASLR is enabled in the - // bootloader configuration instead. Presently - // reserved and unused. - // All other bits are undefined and must be 0. - - uint16_t framebuffer_width; // These 3 values are parsed if a graphics mode - uint16_t framebuffer_height; // is requested. If all values are set to 0 - uint16_t framebuffer_bpp; // then the bootloader will pick the best possible - // video mode automatically (recommended). - uint64_t entry_point; // If not 0, this field will be jumped to at entry - // instead of the ELF entry point. -} __attribute__((packed)); -``` - -## stivale structure - -The stivale structure returned by the bootloader looks like this: -```c -struct stivale_struct { - uint64_t cmdline; // Pointer to a null-terminated cmdline - uint64_t memory_map_addr; // Pointer to the memory map (entries described below) - uint64_t memory_map_entries; // Count of memory map entries - uint64_t framebuffer_addr; // Address of the framebuffer and related info - uint16_t framebuffer_pitch; - uint16_t framebuffer_width; - uint16_t framebuffer_height; - uint16_t framebuffer_bpp; - uint64_t rsdp; // Pointer to the ACPI RSDP structure - uint64_t module_count; // Count of modules that stivale loaded according to config - uint64_t modules; // Pointer to the first entry in the linked list of modules (described below) - uint64_t epoch; // UNIX epoch at boot, read from system RTC - uint64_t flags; // Flags - // bit 0: 1 if booted with BIOS, 0 if booted with UEFI - // bit 1: 1 if extended colour information passed, 0 if not - // All other bits are undefined and set to 0. - // Extended colour information follows, only access if bit 1 of flags is set. - uint8_t fb_memory_model; // Memory model: 1=RGB, all other values undefined - uint8_t fb_red_mask_size; // RGB mask sizes and left shifts - uint8_t fb_red_mask_shift; - uint8_t fb_green_mask_size; - uint8_t fb_green_mask_shift; - uint8_t fb_blue_mask_size; - uint8_t fb_blue_mask_shift; -} __attribute__((packed)); -``` - -## Memory map entry - -```c -struct mmap_entry { - uint64_t base; // Base of the memory section - uint64_t length; // Length of the section - uint32_t type; // Type (described below) - uint32_t unused; -} __attribute__((packed)); -``` - -`type` is an enumeration that can have the following values: - -``` -1 - Usable RAM -2 - Reserved -3 - ACPI reclaimable -4 - ACPI NVS -5 - Bad memory -10 - Kernel/Modules -0x1000 - Bootloader Reclaimable -``` - -All other values are undefined. - -The kernel and modules loaded **are not** marked as usable memory. They are marked -as Kernel/Modules (type 10). - -The entries are guaranteed to be sorted by base address, lowest to highest. - -Usable and bootloader reclaimable entries are guaranteed to be 4096 byte aligned for both base and length. - -Usable and bootloader reclaimable entries are guaranteed not to overlap with any other entry. - -To the contrary, all non-usable entries (including kernel/modules) are not guaranteed any alignment, nor -is it guaranteed that they do not overlap other entries (except usable and bootloader reclaimable entries). - -## Modules - -The `modules` variable points to the first entry of the linked list of module -structures. -A module structure looks like this: -```c -struct stivale_module { - uint64_t begin; // Address where the module is loaded - uint64_t end; // End address of the module - char string[128]; // String passed to the module (by config file) - uint64_t next; // Pointer to the next module (if any), check module_count - // in the stivale_struct -} __attribute__((packed)); -``` +stivale documentation has been moved to https://github.com/stivale/stivale/blob/master/STIVALE.md diff --git a/STIVALE2.md b/STIVALE2.md index 4575a204..de7f1e09 100644 --- a/STIVALE2.md +++ b/STIVALE2.md @@ -1,522 +1 @@ -# stivale2 boot protocol specification - -The stivale2 boot protocol is an improved version of the stivale protocol which -provides the kernel with most of the features one may need in a *modern* -x86_64 context (although 32-bit x86 is also supported). - -## General information - -In order to have a stivale2 compliant kernel, one must have a kernel executable -in the `elf64` or `elf32` format and have a `.stivale2hdr` section (described below). -Other executable formats are not supported. - -stivale2 will recognise whether the ELF file is 32-bit or 64-bit and load the kernel -into the appropriate CPU mode. - -stivale2 natively supports (only for 64-bit kernels) and encourages higher half kernels. -The kernel can load itself at `0xffffffff80000000` or higher (as defined in the linker script) -and the bootloader will take care of everything, no AT linker script directives needed. - -If the kernel loads itself in the lower half, the bootloader will not perform the -higher half relocation. - -*Note: In order to maintain compatibility with Limine and other stivale2-compliant* -*bootloaders it is strongly advised never to load the kernel or any of its* -*sections below the 1 MiB physical memory mark. This may work with some stivale2* -*loaders, but it WILL NOT work with Limine and it's explicitly discouraged.* - -## Kernel entry machine state - -### 64-bit kernel - -`rip` will be the entry point as defined in the ELF file, unless the `entry_point` -field in the stivale2 header is set to a non-0 value, in which case, it is set to -the value of `entry_point`. - -At entry, the bootloader will have setup paging mappings as such: - -``` - Base Physical Address - Size -> Virtual address - 0x0000000000000000 - 4 GiB plus any additional memory map entry -> 0x0000000000000000 - 0x0000000000000000 - 4 GiB plus any additional memory map entry -> 0xffff800000000000 (4-level paging only) - 0x0000000000000000 - 4 GiB plus any additional memory map entry -> 0xff00000000000000 (5-level paging only) - 0x0000000000000000 - 0x80000000 -> 0xffffffff80000000 -``` - -If the kernel is dynamic and not statically linked, the bootloader will relocate it, -potentially performing KASLR (as specified by the config). - -The kernel should NOT modify the bootloader page tables, and it should only use them -to bootstrap its own virtual memory manager and its own page tables. - -At entry all segment registers are loaded as 64 bit code/data segments, limits and -bases are ignored since this is Long Mode. - -DO NOT reload segment registers or rely on the provided GDT. The kernel MUST load -its own GDT as soon as possible and not rely on the bootloader's. - -The IDT is in an undefined state. Kernel must load its own. - -IF flag, VM flag, and direction flag are cleared on entry. Other flags undefined. - -PG is enabled (`cr0`), PE is enabled (`cr0`), PAE is enabled (`cr4`), -LME is enabled (`EFER`). -If the stivale2 header tag for 5-level paging is present, then, if available, -5-level paging is enabled (LA57 bit in `cr4`). - -The A20 gate is enabled. - -PIC/APIC IRQs are all masked. - -`rsp` is set to the requested stack as per stivale2 header. If the requested value is -non-null, an invalid return address of 0 is pushed to the stack before jumping -to the kernel. - -`rdi` will point to the stivale2 structure (described below). - -All other general purpose registers are set to 0. - -### 32-bit kernel - -`eip` will be the entry point as defined in the ELF file, unless the `entry_point` -field in the stivale2 header is set to a non-0 value, in which case, it is set to -the value of `entry_point`. - -At entry all segment registers are loaded as 32 bit code/data segments. -All segment bases are `0x00000000` and all limits are `0xffffffff`. - -DO NOT reload segment registers or rely on the provided GDT. The kernel MUST load -its own GDT as soon as possible and not rely on the bootloader's. - -The IDT is in an undefined state. Kernel must load its own. - -IF flag, VM flag, and direction flag are cleared on entry. Other flags undefined. - -PE is enabled (`cr0`). - -The A20 gate is enabled. - -PIC/APIC IRQs are all masked. - -`esp` is set to the requested stack as per stivale2 header. An invalid return address -of 0 is pushed to the stack before jumping to the kernel. - -A pointer to the stivale2 structure (described below) is pushed onto this stack -before the entry point is called. - -All other general purpose registers are set to 0. - -## Bootloader-reserved memory - -In order for stivale2 to function, it needs to reserve memory areas for either internal -usage (such as page tables, GDT, SMP), or for kernel interfacing (such as returned -structures). - -stivale2 ensures that none of these areas are found in any of the sections -marked as "usable" or "kernel/modules" in the memory map. - -The location of these areas may vary and it is implementation specific; -these areas may be in any non-usable memory map section (except kernel/modules), -or in unmarked memory. - -The OS must make sure to be done consuming bootloader information and services -before switching to its own address space, as unmarked memory areas in use by -the bootloader may become unavailable. - -Once the OS is done needing the bootloader, memory map areas marked as "bootloader -reclaimable" may be used as usable memory. These areas are guaranteed to be -4096-byte aligned (both base and length), and they are guaranteed to not overlap -other sections of the memory map. - -## stivale2 header (.stivale2hdr) - -The kernel executable shall have a section `.stivale2hdr` which will contain -the header that the bootloader will parse. - -Said header looks like this: -```c -struct stivale2_header { - uint64_t entry_point; // If not 0, this address will be jumped to as the - // entry point of the kernel. - // If set to 0, the ELF entry point will be used - // instead. - - uint64_t stack; // This is the stack address which will be in ESP/RSP - // when the kernel is loaded. - // It can only be set to NULL for 64-bit kernels. 32-bit - // kernels are mandated to provide a vaild stack. - // 64-bit and 32-bit valid stacks must be at least 256 bytes - // in usable space and must be 16 byte aligned addresses. - - uint64_t flags; // Bit 0: Formerly used to indicate whether to enable - // KASLR, this flag is now reserved as KASLR - // is enabled in the bootloader configuration - // instead. Presently reserved and unused. - // All other bits are undefined and must be 0. - - uint64_t tags; // Pointer to the first of the linked list of tags. - // see "stivale2 header tags" section. - // NULL = no tags. -} __attribute__((packed)); -``` - -### stivale2 header tags - -The stivale2 header uses a mechanism to avoid having protocol versioning, but -rather, feature-specific support detection. - -The kernel executable provides the bootloader with a linked list of structures, -the first of which is pointed to by the `tags` entry of the stivale2 header. - -The bootloader is free to ignore kernel tags that it does not recognise. -The kernel should make sure that the bootloader has properly interpreted the -provided tags, either by checking returned tags or by other means. - -Each tag shall contain these 2 fields: -```c -struct stivale2_hdr_tag { - uint64_t identifier; - uint64_t next; -} __attribute__((packed)); - -``` - -The `identifier` field identifies what feature the tag is requesting from the -bootloader. - -The `next` field points to another tag in the linked list. A NULL value determines -the end of the linked list. - -Tag structures can have more than just these 2 members, but these 2 members MUST -appear at the beginning of any given tag. - -Tags can have no extra members and just serve as "flags" to enable some behaviour -that does not require extra parameters. - -#### Framebuffer header tag - -This tag asks the stivale2-compliant bootloader to initialise a graphical framebuffer -video mode. -Omitting this tag will make the bootloader default to a CGA-compatible text mode, -if supported. - -```c -struct stivale2_header_tag_framebuffer { - uint64_t identifier; // Identifier: 0x3ecc1bc43d0f7971 - uint64_t next; - uint16_t framebuffer_width; // If all values are set to 0 - uint16_t framebuffer_height; // then the bootloader will pick the best possible - uint16_t framebuffer_bpp; // video mode automatically. -} __attribute__((packed)); -``` - -#### Framebuffer MTRR write-combining header tag - -The presence of this tag tells the bootloader to, in case a framebuffer was -requested, make that framebuffer's caching type write-combining using x86's -MTRR model specific registers. This caching type helps speed up framebuffer writes -on real hardware. - -It is recommended to use this tag in conjunction with the SMP tag in order to -let the bootloader make the MTRR settings uniform across all CPUs. - -If no framebuffer was requested, this tag has no effect. - -Identifier: `0x4c7bb07731282e00` - -This tag does not have extra members. - -#### 5-level paging header tag - -The presence of this tag enables support for 5-level paging, if available. - -Identifier: `0x932f477032007e8f` - -This tag does not have extra members. - -#### SMP header tag - -The presence of this tag enables support for booting up application processors. - -```c -struct stivale2_header_tag_smp { - uint64_t identifier; // Identifier: 0x1ab015085f3273df - uint64_t next; - uint64_t flags; // Flags: - // bit 0: 0 = use xAPIC, 1 = use x2APIC (if available) - // All other bits are undefined and must be 0. -} __attribute__((packed)); -``` - -## stivale2 structure - -The stivale2 structure returned by the bootloader looks like this: -```c -struct stivale2_struct { - char bootloader_brand[64]; // Bootloader null-terminated brand string - char bootloader_version[64]; // Bootloader null-terminated version string - - uint64_t tags; // Pointer to the first of the linked list of tags. - // see "stivale2 structure tags" section. - // NULL = no tags. -} __attribute__((packed)); -``` - -### stivale2 structure tags - -These tags work *very* similarly to the header tags, with the main difference being -that these tags are returned to the kernel by the bootloader, instead. - -See "stivale2 header tags". - -The kernel is responsible for parsing the tags and the identifiers, and interpreting -the tags that it supports, while handling in a graceful manner the tags it does not -recognise. - -#### Command line structure tag - -This tag reports to the kernel the command line string that was passed to it by -the bootloader. - -```c -struct stivale2_struct_tag_cmdline { - uint64_t identifier; // Identifier: 0xe5e76a1b4597a781 - uint64_t next; - uint64_t cmdline; // Pointer to a null-terminated cmdline -} __attribute__((packed)); -``` - -#### Memory map structure tag - -This tag reports to the kernel the memory map built by the bootloader. - -```c -struct stivale2_struct_tag_memmap { - uint64_t identifier; // Identifier: 0x2187f79e8612de07 - uint64_t next; - uint64_t entries; // Count of memory map entries - struct stivale2_mmap_entry memmap[]; // Array of memory map entries -} __attribute__((packed)); -``` - -###### Memory map entry - -```c -struct stivale2_mmap_entry { - uint64_t base; // Base of the memory section - uint64_t length; // Length of the section - enum stivale2_mmap_type type; // Type (described below) - uint32_t unused; -} __attribute__((packed)); -``` - -`type` is an enumeration that can have the following values: - -``` -enum stivale2_mmap_type : uint32_t { - USABLE = 1, - RESERVED = 2, - ACPI_RECLAIMABLE = 3, - ACPI_NVS = 4, - BAD_MEMORY = 5, - BOOTLOADER_RECLAIMABLE = 0x1000, - KERNEL_AND_MODULES = 0x1001 -}; -``` - -All other values are undefined. - -The kernel and modules loaded **are not** marked as usable memory. They are marked -as Kernel/Modules (type 0x1001). - -The entries are guaranteed to be sorted by base address, lowest to highest. - -Usable and bootloader reclaimable entries are guaranteed to be 4096 byte aligned for both base and length. - -Usable and bootloader reclaimable entries are guaranteed not to overlap with any other entry. - -To the contrary, all non-usable entries (including kernel/modules) are not guaranteed any alignment, nor -is it guaranteed that they do not overlap other entries (except usable and bootloader reclaimable entries). - -#### Framebuffer structure tag - -This tag reports to the kernel the currently set up framebuffer details, if any. - -```c -struct stivale2_struct_tag_framebuffer { - uint64_t identifier; // Identifier: 0x506461d2950408fa - uint64_t next; - uint64_t framebuffer_addr; // Address of the framebuffer and related info - uint16_t framebuffer_width; // Width and height in pixels - uint16_t framebuffer_height; - uint16_t framebuffer_pitch; // Pitch in bytes - uint16_t framebuffer_bpp; // Bits per pixel - uint8_t memory_model; // Memory model: 1=RGB, all other values undefined - uint8_t red_mask_size; // RGB mask sizes and left shifts - uint8_t red_mask_shift; - uint8_t green_mask_size; - uint8_t green_mask_shift; - uint8_t blue_mask_size; - uint8_t blue_mask_shift; -} __attribute__((packed)); -``` - -#### Framebuffer MTRR write-combining structure tag - -This tag exists if MTRR write-combining for the framebuffer was requested and -successfully enabled. - -Identifier: `0x6bc1a78ebe871172` - -This tag does not have extra members. - -#### Modules structure tag - -This tag lists modules that the bootloader loaded alongside the kernel, if any. - -```c -struct stivale2_struct_tag_modules { - uint64_t identifier; // Identifier: 0x4b6fe466aade04ce - uint64_t next; - uint64_t module_count; // Count of loaded modules - struct stivale2_module modules[]; // Array of module descriptors -} __attribute__((packed)); -``` - -```c -struct stivale2_module { - uint64_t begin; // Address where the module is loaded - uint64_t end; // End address of the module - char string[128]; // 0-terminated string passed to the module -} __attribute__((packed)); -``` - -#### RSDP structure tag - -This tag reports to the kernel the location of the ACPI RSDP structure in memory. - -```c -struct stivale2_struct_tag_rsdp { - uint64_t identifier; // Identifier: 0x9e1786930a375e78 - uint64_t next; - uint64_t rsdp; // Pointer to the ACPI RSDP structure -} __attribute__((packed)); -``` - -#### Epoch structure tag - -This tag reports to the kernel the current UNIX epoch, as per RTC. - -```c -struct stivale2_struct_tag_epoch { - uint64_t identifier; // Identifier: 0x566a7bed888e1407 - uint64_t next; - uint64_t epoch; // UNIX epoch at boot, read from system RTC -} __attribute__((packed)); -``` - -#### Firmware structure tag - -This tag reports to the kernel info about the firmware. - -```c -struct stivale2_struct_tag_firmware { - uint64_t identifier; // Identifier: 0x359d837855e3858c - uint64_t next; - uint64_t flags; // Bit 0: 0 = UEFI, 1 = BIOS -} __attribute__((packed)); -``` - -#### SMP structure tag - -This tag reports to the kernel info about a multiprocessor environment. - -```c -struct stivale2_struct_tag_smp { - uint64_t identifier; // Identifier: 0x34d1d96339647025 - uint64_t next; - uint64_t flags; // Flags: - // bit 0: Set if x2APIC was requested and it - // was supported and enabled. - // All other bits are undefined and set to 0. - uint32_t bsp_lapic_id; // LAPIC ID of the BSP (bootstrap processor). - uint32_t unused; // Reserved for future use. - uint64_t cpu_count; // Total number of logical CPUs (including BSP) - struct stivale2_smp_info smp_info[]; // Array of smp_info structs, one per - // logical processor, including BSP. -} __attribute__((packed)); -``` - -```c -struct stivale2_smp_info { - uint32_t acpi_processor_uid; // ACPI Processor UID as specified by MADT - uint32_t lapic_id; // LAPIC ID as specified by MADT - uint64_t target_stack; // The stack that will be loaded in ESP/RSP - // once the goto_address field is loaded. - // This MUST point to a valid stack of at least - // 256 bytes in size, and 16-byte aligned. - // target_stack is an unused field for the - // struct describing the BSP (lapic_id == 0) - uint64_t goto_address; // This address is polled by the started APs - // until the kernel on another CPU performs an - // atomic write to this field. - // When that happens, bootloader code will - // load up ESP/RSP with the stack value as - // specified in target_stack. - // It will then proceed to load a pointer to - // this very structure into either register - // RDI for 64-bit or on the stack for 32-bit, - // then, goto_address is called (a bogus return - // address is pushed onto the stack) and execution - // is handed off. - // The CPU state will be the same as described - // in kernel entry machine state, with the exception - // of ESP/RSP and RDI/stack arg being set up as - // above. - // goto_address is an unused field for the - // struct describing the BSP. - uint64_t extra_argument; // This field is here for the kernel to use - // for whatever it wants. Writes here should - // be performed before writing to goto_address - // so that the receiving processor can safely - // retrieve the data. - // extra_argument is an unused field for the - // struct describing the BSP. -} __attribute__((packed)); -``` - -#### PXE server info structure tag - -This tag reports that the kernel has been booted via PXE, and reports the server ip that it was booted from. - -```c -struct stivale2_struct_tag_pxe_server_info { - struct stivale2_tag tag; // Identifier: 0x29d1e96239247032 - uint32_t server_ip; // Server ip in network byte order -} __attribute__((packed)); -``` - -#### MMIO32 UART tag - -This tag reports that there is a memory mapped UART port and its address. To write to this port, write the character, zero extended to a 32 bit unsigned integer to the address provided. - -```c -struct stivale2_struct_tag_mmio32_uart { - uint64_t identifier; // Identifier: 0xb813f9b8dbc78797 - uint64_t next; - uint64_t addr; // The address of the UART port -} __attribute__((packed)); -``` - -#### Device tree blob tag - -This tag describes a device tree blob for the platform. - -```c -struct stivale2_struct_tag_dtb { - uint64_t identifier; // Identifier: 0xabb29bd49a2833fa - uint64_t next; - uint64_t addr; // The address of the dtb - uint64_t size; // The size of the dtb -} __attribute__((packed)); -``` +stivale2 documentation has been moved to https://github.com/stivale/stivale/blob/master/STIVALE2.md