Move multiboot2 header from assembly to C.

This commit is contained in:
Josh Holtrop 2020-10-19 21:42:14 -04:00
parent 412925a790
commit 85e5b76aa3
4 changed files with 68 additions and 64 deletions

View File

@ -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 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 (esp) and it is up to the kernel to provide a stack. This allocates room for a

View File

@ -1,43 +1,28 @@
/* The bootloader will look at this image and start execution at the symbol
designated as the entry point. */
ENTRY(_start) ENTRY(_start)
/* Tell where the various sections of the object files will be put in the final
kernel image. */
SECTIONS SECTIONS
{ {
/* Begin putting sections at 1 MiB, a conventional place for kernels to be . = 1M;
loaded at by the bootloader. */
. = 1M;
/* First put the multiboot header, as it is required to be put very early .text BLOCK(4K) : ALIGN(4K)
early in the image or the bootloader won't recognize the file format. {
Next we'll put the .text section. */ *(.multiboot)
.text BLOCK(4K) : ALIGN(4K) *(.text)
{ }
*(.multiboot)
*(.text)
}
/* Read-only data. */ .rodata BLOCK(4K) : ALIGN(4K)
.rodata BLOCK(4K) : ALIGN(4K) {
{ *(.rodata)
*(.rodata) }
}
/* Read-write data (initialized) */ .data BLOCK(4K) : ALIGN(4K)
.data BLOCK(4K) : ALIGN(4K) {
{ *(.data)
*(.data) }
}
/* Read-write data (uninitialized) and stack */ .bss BLOCK(4K) : ALIGN(4K)
.bss BLOCK(4K) : ALIGN(4K) {
{ *(COMMON)
*(COMMON) *(.bss)
*(.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. */
} }

37
src/multiboot2.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef MULTIBOOT2_H
#define MULTIBOOT2_H
#include <stdint.h>
#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

12
src/multiboot_header.c Normal file
View File

@ -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(),
};