From 85e5b76aa31f56de2435d69b404d8f93086a174c Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 19 Oct 2020 21:42:14 -0400 Subject: [PATCH] Move multiboot2 header from assembly to C. --- src/boot.S | 30 ------------------------ src/link.ld | 53 +++++++++++++++--------------------------- src/multiboot2.h | 37 +++++++++++++++++++++++++++++ src/multiboot_header.c | 12 ++++++++++ 4 files changed, 68 insertions(+), 64 deletions(-) create mode 100644 src/multiboot2.h create mode 100644 src/multiboot_header.c diff --git a/src/boot.S b/src/boot.S index 3c04a19..90b5149 100644 --- a/src/boot.S +++ b/src/boot.S @@ -1,33 +1,3 @@ -/* Declare constants for the multiboot2 header. */ -.set MAGIC, 0xE85250D6 /* 'magic number' lets bootloader find the header */ -.set NTAGS, 1 /* including terminating tag */ -.set LENGTH, 4 * 4 + NTAGS -.set CHECKSUM, -(MAGIC + LENGTH) /* checksum of above, to prove we are multiboot */ - -/* -Declare a multiboot header that marks the program as a kernel. These are magic -values that are documented in the multiboot standard. The bootloader will -search for this signature in the first 8 KiB of the kernel file, aligned at a -32-bit boundary. The signature is in its own section so the header can be -forced to be within the first 8 KiB of the kernel file. -*/ -.section .multiboot -.align 4 -.long MAGIC /* magic */ -.long 0 /* architecture */ -.long LENGTH /* header_length */ -.long CHECKSUM -.short 5 -.short 0 -.long 20 -.long 0 -.long 0 -.long 0 -.long 0 /* padding */ -.short 0 -.short 0 -.long 8 - /* The multiboot standard does not define the value of the stack pointer register (esp) and it is up to the kernel to provide a stack. This allocates room for a diff --git a/src/link.ld b/src/link.ld index 38ddd94..66b9c93 100644 --- a/src/link.ld +++ b/src/link.ld @@ -1,43 +1,28 @@ -/* The bootloader will look at this image and start execution at the symbol - designated as the entry point. */ ENTRY(_start) -/* Tell where the various sections of the object files will be put in the final - kernel image. */ SECTIONS { - /* Begin putting sections at 1 MiB, a conventional place for kernels to be - loaded at by the bootloader. */ - . = 1M; + . = 1M; - /* First put the multiboot header, as it is required to be put very early - early in the image or the bootloader won't recognize the file format. - Next we'll put the .text section. */ - .text BLOCK(4K) : ALIGN(4K) - { - *(.multiboot) - *(.text) - } + .text BLOCK(4K) : ALIGN(4K) + { + *(.multiboot) + *(.text) + } - /* Read-only data. */ - .rodata BLOCK(4K) : ALIGN(4K) - { - *(.rodata) - } + .rodata BLOCK(4K) : ALIGN(4K) + { + *(.rodata) + } - /* Read-write data (initialized) */ - .data BLOCK(4K) : ALIGN(4K) - { - *(.data) - } + .data BLOCK(4K) : ALIGN(4K) + { + *(.data) + } - /* Read-write data (uninitialized) and stack */ - .bss BLOCK(4K) : ALIGN(4K) - { - *(COMMON) - *(.bss) - } - - /* The compiler may produce other sections, by default it will put them in - a segment with the same name. Simply add stuff here as needed. */ + .bss BLOCK(4K) : ALIGN(4K) + { + *(COMMON) + *(.bss) + } } diff --git a/src/multiboot2.h b/src/multiboot2.h new file mode 100644 index 0000000..e8cd8d9 --- /dev/null +++ b/src/multiboot2.h @@ -0,0 +1,37 @@ +#ifndef MULTIBOOT2_H +#define MULTIBOOT2_H + +#include + +#define MULTIBOOT2_MAGIC 0xE85250D6u +#define MULTIBOOT2_ARCHITECTURE_I386 0u + +typedef struct { + uint32_t magic; + uint32_t architecture; + uint32_t header_length; + uint32_t checksum; +} multiboot2_header_t; +#define multiboot2_header(magic, architecture, header_length) \ + {(magic), (architecture), (header_length), (uint32_t)(0x100000000u - (magic) - (architecture) - (header_length))} +#define multiboot2_header_default() \ + multiboot2_header(MULTIBOOT2_MAGIC, MULTIBOOT2_ARCHITECTURE_I386, sizeof(multiboot2_header_t)) + +typedef struct { + uint16_t type; + uint16_t flags; + uint32_t size; +} multiboot2_tag_t; +#define multiboot2_end_tag() {0u, 0u, 8u} + +typedef struct { + multiboot2_tag_t header; + uint32_t width; + uint32_t height; + uint32_t depth; + uint32_t _padding; +} multiboot2_framebuffer_tag_t; +#define multiboot2_framebuffer_tag(width, height, depth) \ + {{5u, 0u, 20u}, width, height, depth} + +#endif diff --git a/src/multiboot_header.c b/src/multiboot_header.c new file mode 100644 index 0000000..93a0d44 --- /dev/null +++ b/src/multiboot_header.c @@ -0,0 +1,12 @@ +#include "multiboot2.h" + +/* Multiboot2 Header. */ +struct { + multiboot2_header_t header; + multiboot2_framebuffer_tag_t framebuffer_tag; + multiboot2_tag_t end_tag; +} multiboot_header __attribute__((section(".multiboot"))) = { + multiboot2_header_default(), + multiboot2_framebuffer_tag(0u, 0u, 0u), + multiboot2_end_tag(), +};