diff --git a/examples/bootloader-stivale2-limine/.gitignore b/examples/bootloader-stivale2-limine/.gitignore index f4d8c1d..5087bbb 100644 --- a/examples/bootloader-stivale2-limine/.gitignore +++ b/examples/bootloader-stivale2-limine/.gitignore @@ -1,8 +1,9 @@ +/*.c.d + /build-libkernaux/* !/build-libkernaux/.keep /image.iso -/main.c.d /output.txt /rootfs/boot/kernel /rootfs/boot/limine-cd.bin diff --git a/examples/bootloader-stivale2-limine/Makefile b/examples/bootloader-stivale2-limine/Makefile index df57b3c..f58ec71 100644 --- a/examples/bootloader-stivale2-limine/Makefile +++ b/examples/bootloader-stivale2-limine/Makefile @@ -56,7 +56,7 @@ CFLAGS = \ -MMD # -pedantic \ -OBJS = main.c.o # start.S.o +OBJS = main.c.o stivale2.c.o test: run $(DIFF) -a -Z $(EXPECTED) $(OUTPUT) diff --git a/examples/bootloader-stivale2-limine/main.c b/examples/bootloader-stivale2-limine/main.c index 8262e90..c5e22ca 100644 --- a/examples/bootloader-stivale2-limine/main.c +++ b/examples/bootloader-stivale2-limine/main.c @@ -7,80 +7,7 @@ static void poweroff(); -// We need to tell the stivale bootloader where we want our stack to be. -// We are going to allocate our stack as an array in .bss. -static uint8_t stack[8192]; - -// stivale2 uses a linked list of tags for both communicating TO the -// bootloader, or receiving info FROM it. More information about these tags -// is found in the stivale2 specification. - -// stivale2 offers a runtime terminal service which can be ditched at any -// time, but it provides an easy way to print out to graphical terminal, -// especially during early boot. -// Read the notes about the requirements for using this feature below this -// code block. -static struct stivale2_header_tag_terminal terminal_hdr_tag = { - // All tags need to begin with an identifier and a pointer to the next tag. - .tag = { - // Identification constant defined in stivale2.h and the specification. - .identifier = STIVALE2_HEADER_TAG_TERMINAL_ID, - // If next is 0, it marks the end of the linked list of header tags. - .next = 0 - }, - // The terminal header tag possesses a flags field, leave it as 0 for now - // as it is unused. - .flags = 0 -}; - -// We are now going to define a framebuffer header tag. -// This tag tells the bootloader that we want a graphical framebuffer instead -// of a CGA-compatible text mode. Omitting this tag will make the bootloader -// default to text mode, if available. -static struct stivale2_header_tag_framebuffer framebuffer_hdr_tag = { - // Same as above. - .tag = { - .identifier = STIVALE2_HEADER_TAG_FRAMEBUFFER_ID, - // Instead of 0, we now point to the previous header tag. The order in - // which header tags are linked does not matter. - .next = (uint64_t)&terminal_hdr_tag - }, - // We set all the framebuffer specifics to 0 as we want the bootloader - // to pick the best it can. - .framebuffer_width = 0, - .framebuffer_height = 0, - .framebuffer_bpp = 0 -}; - -// The stivale2 specification says we need to define a "header structure". -// This structure needs to reside in the .stivale2hdr ELF section in order -// for the bootloader to find it. We use this __attribute__ directive to -// tell the compiler to put the following structure in said section. -__attribute__((section(".stivale2hdr"), used)) -static struct stivale2_header stivale_hdr = { - // The entry_point member is used to specify an alternative entry - // point that the bootloader should jump to instead of the executable's - // ELF entry point. We do not care about that so we leave it zeroed. - .entry_point = 0, - // Let's tell the bootloader where our stack is. - // We need to add the sizeof(stack) since in x86(_64) the stack grows - // downwards. - .stack = (uintptr_t)stack + sizeof(stack), - // Bit 1, if set, causes the bootloader to return to us pointers in the - // higher half, which we likely want since this is a higher half kernel. - // Bit 2, if set, tells the bootloader to enable protected memory ranges, - // that is, to respect the ELF PHDR mandated permissions for the executable's - // segments. - // Bit 3, if set, enables fully virtual kernel mappings, which we want as - // they allow the bootloader to pick whichever *physical* memory address is - // available to load the kernel, rather than relying on us telling it where - // to load it. - // Bit 4 disables a deprecated feature and should always be set. - .flags = (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4), - // This header structure is the root of the linked list of header tags and - // points to the first one in the linked list. - .tags = (uintptr_t)&framebuffer_hdr_tag -}; +uint8_t stack[8192]; // We will now write a helper function which will allow us to scan for tags // that we want FROM the bootloader (structure tags). diff --git a/examples/bootloader-stivale2-limine/stivale2.c b/examples/bootloader-stivale2-limine/stivale2.c new file mode 100644 index 0000000..bcd4c1c --- /dev/null +++ b/examples/bootloader-stivale2-limine/stivale2.c @@ -0,0 +1,78 @@ +#include + +#include "stivale2.h" + +// We need to tell the stivale bootloader where we want our stack to be. +// We are going to allocate our stack as an array in .bss. +extern uint8_t stack[8192]; + +// stivale2 uses a linked list of tags for both communicating TO the +// bootloader, or receiving info FROM it. More information about these tags +// is found in the stivale2 specification. + +// stivale2 offers a runtime terminal service which can be ditched at any +// time, but it provides an easy way to print out to graphical terminal, +// especially during early boot. +// Read the notes about the requirements for using this feature below this +// code block. +static struct stivale2_header_tag_terminal terminal_hdr_tag = { + // All tags need to begin with an identifier and a pointer to the next tag. + .tag = { + // Identification constant defined in stivale2.h and the specification. + .identifier = STIVALE2_HEADER_TAG_TERMINAL_ID, + // If next is 0, it marks the end of the linked list of header tags. + .next = 0 + }, + // The terminal header tag possesses a flags field, leave it as 0 for now + // as it is unused. + .flags = 0 +}; + +// We are now going to define a framebuffer header tag. +// This tag tells the bootloader that we want a graphical framebuffer instead +// of a CGA-compatible text mode. Omitting this tag will make the bootloader +// default to text mode, if available. +static struct stivale2_header_tag_framebuffer framebuffer_hdr_tag = { + // Same as above. + .tag = { + .identifier = STIVALE2_HEADER_TAG_FRAMEBUFFER_ID, + // Instead of 0, we now point to the previous header tag. The order in + // which header tags are linked does not matter. + .next = (uint64_t)&terminal_hdr_tag + }, + // We set all the framebuffer specifics to 0 as we want the bootloader + // to pick the best it can. + .framebuffer_width = 0, + .framebuffer_height = 0, + .framebuffer_bpp = 0 +}; + +// The stivale2 specification says we need to define a "header structure". +// This structure needs to reside in the .stivale2hdr ELF section in order +// for the bootloader to find it. We use this __attribute__ directive to +// tell the compiler to put the following structure in said section. +__attribute__((section(".stivale2hdr"), used)) +static struct stivale2_header stivale_hdr = { + // The entry_point member is used to specify an alternative entry + // point that the bootloader should jump to instead of the executable's + // ELF entry point. We do not care about that so we leave it zeroed. + .entry_point = 0, + // Let's tell the bootloader where our stack is. + // We need to add the sizeof(stack) since in x86(_64) the stack grows + // downwards. + .stack = (uintptr_t)stack + sizeof(stack), + // Bit 1, if set, causes the bootloader to return to us pointers in the + // higher half, which we likely want since this is a higher half kernel. + // Bit 2, if set, tells the bootloader to enable protected memory ranges, + // that is, to respect the ELF PHDR mandated permissions for the executable's + // segments. + // Bit 3, if set, enables fully virtual kernel mappings, which we want as + // they allow the bootloader to pick whichever *physical* memory address is + // available to load the kernel, rather than relying on us telling it where + // to load it. + // Bit 4 disables a deprecated feature and should always be set. + .flags = (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4), + // This header structure is the root of the linked list of header tags and + // points to the first one in the linked list. + .tags = (uintptr_t)&framebuffer_hdr_tag +};