From ef1ee78320486ef9cb869df1603b9040dbaecd65 Mon Sep 17 00:00:00 2001 From: Tunacan Date: Fri, 2 Jul 2021 21:49:20 +0300 Subject: [PATCH] switch bootloader protocol to stivale2, os now 64-bit (very buggy because i still havent updated the GDT and IDT) and on the higher half, framebuffer, drawing text on the framebuffer with a font loaded from a psf file --- .gitignore | 5 +- .gitmodules | 4 + Makefile | 95 ++++++---- arch/i386/boot/asm.asm | 41 +++++ arch/i386/boot/boot.asm | 160 ---------------- arch/i386/boot/kernel.c | 160 +++++++++++++--- arch/i386/drivers/framebuffer.c | 24 +++ arch/i386/drivers/ide/ide.c | 4 +- arch/i386/drivers/keyboard/keyboard.c | 9 +- arch/i386/drivers/psf.c | 32 ++++ arch/i386/drivers/tar/tar.c | 5 +- arch/i386/drivers/terminal/terminal.c | 20 +- font.psfu | Bin 0 -> 4969 bytes include/drivers/keyboard/keyboard.h | 1 + include/drivers/terminal/terminal.h | 24 +-- include/framebuffer.h | 24 +++ include/psf.h | 33 ++++ include/std/inline.h | 12 +- include/stivale2.h | 251 ++++++++++++++++++++++++++ limine | 1 + limine.cfg | 14 ++ linker.ld | 57 +++--- sysroot/boot/grub/grub.cfg | 3 - 23 files changed, 687 insertions(+), 292 deletions(-) create mode 100644 .gitmodules create mode 100644 arch/i386/boot/asm.asm delete mode 100644 arch/i386/boot/boot.asm create mode 100644 arch/i386/drivers/framebuffer.c create mode 100644 arch/i386/drivers/psf.c create mode 100644 font.psfu create mode 100644 include/framebuffer.h create mode 100644 include/psf.h create mode 100644 include/stivale2.h create mode 160000 limine create mode 100644 limine.cfg delete mode 100644 sysroot/boot/grub/grub.cfg diff --git a/.gitignore b/.gitignore index e5f1b56..b6532b1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,7 @@ workspace.code-workspace *.o *.bin *.iso -disk.img \ No newline at end of file +*.elf +*.img +sysroot/ +*.log \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..16fe246 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "limine"] + path = limine + url = https://github.com/limine-bootloader/limine.git + branch = v2.0-branch-binary diff --git a/Makefile b/Makefile index 5f73b42..5386bb6 100644 --- a/Makefile +++ b/Makefile @@ -1,47 +1,68 @@ -TARGET = i686-elf -ARCH = i386 -CC = $(TARGET)-gcc -STRIP = $(TARGET)-strip +KERNEL := hhhos.elf +ISO := hhhos.iso + +CC = x86_64-elf-gcc NASM = nasm -QEMU = qemu-system-i386 -MKDIR_P = mkdir -p + +# User controllable CFLAGS. +CFLAGS = -Wall -Wextra -O3 -pipe +NASMFLAGS = -felf64 + +# Internal link flags that should not be changed by the user. +INTERNALLDFLAGS := \ + -fno-pic -fpie \ + -Wl,-static,-pie,--no-dynamic-linker,-ztext \ + -static-pie \ + -nostdlib \ + -Tlinker.ld \ + -z max-page-size=0x1000 + +# Internal C flags that should not be changed by the user. +INTERNALCFLAGS := \ + -Iinclude \ + -std=gnu11 \ + -ffreestanding \ + -fno-stack-protector \ + -fno-pic -fpie \ + -mno-80387 \ + -mno-mmx \ + -mno-3dnow \ + -mno-sse \ + -mno-sse2 \ + -mno-red-zone + +# Use find to glob all *.c files in the directory and extract the object names. +CFILES := $(shell find ./arch -type f -name '*.c') +OBJ := $(CFILES:.c=.o) +OBJ += font.o -CFLAGS += -std=gnu18 -ffreestanding -O2 -Wall -Wextra -mgeneral-regs-only -LDFLAGS += -ffreestanding -O2 -nostdlib -lgcc -NASMFLAGS += -felf32 +# Targets that do not actually build a file of the same name. +.PHONY: all clean run -BIN = sysroot/boot/hhhos.bin -ISO = build/HhhOS.iso +run: $(ISO) + qemu-system-x86_64 -cdrom $(ISO) -serial file:serial.log -drive id=disk,file=build/disk.img,if=none,format=raw -device ide-hd,drive=disk,bus=ide.0 -DIRS = build build/boot build/std build/drivers build/drivers/terminal build/drivers/idt build/drivers/device build/drivers/keyboard build/drivers/pic build/drivers/ide +$(ISO): $(KERNEL) + mkdir -p sysroot + cp -v $(KERNEL) limine.cfg limine/limine.sys limine/limine-cd.bin limine/limine-eltorito-efi.bin sysroot/ + xorriso -as mkisofs -b limine-cd.bin -no-emul-boot -boot-load-size 4 -boot-info-table \ + --efi-boot limine-eltorito-efi.bin -efi-boot-part --efi-boot-image --protective-msdos-label \ + sysroot -o $(ISO) -OBJS = build/boot/boot.o build/boot/kernel.o build/std/string.o build/drivers/terminal/terminal.o build/drivers/idt/idt.o \ -build/drivers/idt/isr.o build/std/util.o build/drivers/device/device.o build/drivers/keyboard/keyboard.o build/drivers/pic/pic.o \ -build/drivers/ide/ide.o build/std/stdio.o +# Default target. +all: $(KERNEL) -ARCHDIR = arch/$(ARCH)/ +# Link rules for the final kernel executable. +$(KERNEL): $(OBJ) + $(CC) $(OBJ) -o $@ $(INTERNALLDFLAGS) -.PHONY: all run clean build +# Compilation rules for *.c files. +%.o: %.c + $(CC) $(CFLAGS) $(INTERNALCFLAGS) -c $< -o $@ -dirs: - ${MKDIR_P} ${DIRS} - -all: dirs $(BIN) - -run: $(ISO) - $(QEMU) -cdrom $(ISO) -drive id=disk,file=build/disk.img,if=none,format=raw -device ide-hd,drive=disk,bus=ide.0 - -$(ISO): dirs $(BIN) - grub-mkrescue -o $(ISO) sysroot - -$(BIN): $(OBJS) - $(CC) -T linker.ld -o $@ $^ $(LDFLAGS) - -build/%.o: $(ARCHDIR)%.c - $(CC) -c $(CFLAGS) -Iinclude -o $@ $< - -build/%.o: $(ARCHDIR)%.asm - $(NASM) $(NASMFLAGS) -o $@ $< +font.o: + objcopy -O elf64-x86-64 -B i386 -I binary font.psfu font.o +# Remove object files and the final executable. clean: - rm -rf $(OBJS) $(BIN) $(ISO) + rm -rf $(KERNEL) $(OBJ) $(ISO) \ No newline at end of file diff --git a/arch/i386/boot/asm.asm b/arch/i386/boot/asm.asm new file mode 100644 index 0000000..ac7f89c --- /dev/null +++ b/arch/i386/boot/asm.asm @@ -0,0 +1,41 @@ +.intel_syntax noprefix + +.rodata +gdt: +.null: + dq 0x0 +.code: + dw 0xffff + dw 0x0000 + db 0x00 + db 10011010b + db 11001111b + db 0x00 +.data: + dw 0xffff + dw 0x0000 + db 0x00 + db 10010010b + db 11001111b + db 0x00 +.end: +.descriptor: + dw .end - gdt - 1 + dd gdt + +.text + .global gdt_load + +gdt_load: + push eax + lgdt [gdt.descriptor] + jmp 0x08:.loaded_cs +.loaded_cs: + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + pop eax + ret diff --git a/arch/i386/boot/boot.asm b/arch/i386/boot/boot.asm deleted file mode 100644 index 89e5f92..0000000 --- a/arch/i386/boot/boot.asm +++ /dev/null @@ -1,160 +0,0 @@ -; Declare constants for the multiboot header. -MBALIGN equ 1 << 0 ; align loaded modules on page boundaries -MEMINFO equ 1 << 1 ; provide memory map -FLAGS equ MBALIGN | MEMINFO ; this is the Multiboot 'flag' field -MAGIC equ 0x1BADB002 ; 'magic number' lets bootloader find the header -CHECKSUM equ -(MAGIC + FLAGS) ; 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 - dd MAGIC - dd FLAGS - dd CHECKSUM - -; 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 -; small stack by creating a symbol at the bottom of it, then allocating 16384 -; bytes for it, and finally creating a symbol at the top. The stack grows -; downwards on x86. The stack is in its own section so it can be marked nobits, -; which means the kernel file is smaller because it does not contain an -; uninitialized stack. The stack on x86 must be 16-byte aligned according to the -; System V ABI standard and de-facto extensions. The compiler will assume the -; stack is properly aligned and failure to align the stack will result in -; undefined behavior. -section .bss -align 16 -stack_bottom: -resb 16384 ; 16 KiB -stack_top: - -section .rodata -gdt: -.null: - dq 0x0 -.code: - dw 0xffff - dw 0x0000 - db 0x00 - db 10011010b - db 11001111b - db 0x00 -.data: - dw 0xffff - dw 0x0000 - db 0x00 - db 10010010b - db 11001111b - db 0x00 -.end: -.descriptor: - dw .end - gdt - 1 - dd gdt -code_segment equ gdt.code - gdt -data_segment equ gdt.data - gdt - -; The linker script specifies _start as the entry point to the kernel and the -; bootloader will jump to this position once the kernel has been loaded. It -; doesn't make sense to return from this function as the bootloader is gone. -; Declare _start as a function symbol with the given symbol size. -section .text -global _start:function (_start.end - _start) - -gdt_load: - push eax - lgdt [gdt.descriptor] - jmp 0x08:.loaded_cs -.loaded_cs: - mov ax, 0x10 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - pop eax - ret - -global load_page_directory -load_page_directory: - push ebp - mov ebp, esp - mov eax, [esp + 8] - mov cr3, eax - mov esp, ebp - pop ebp - ret - -global enable_paging -enable_paging: - push ebp - mov ebp, esp - mov eax, cr0 - or eax, 80000001h - mov cr0, eax - mov esp, ebp - pop ebp - ret - -_start: - ; The bootloader has loaded us into 32-bit protected mode on a x86 - ; machine. Interrupts are disabled. Paging is disabled. The processor - ; state is as defined in the multiboot standard. The kernel has full - ; control of the CPU. The kernel can only make use of hardware features - ; and any code it provides as part of itself. There's no printf - ; function, unless the kernel provides its own header and a - ; printf implementation. There are no security restrictions, no - ; safeguards, no debugging mechanisms, only what the kernel provides - ; itself. It has absolute and complete power over the machine. - - ; To set up a stack, we set the esp register to point to the top of our - ; stack (as it grows downwards on x86 systems). This is necessarily done - ; in assembly as languages such as C cannot function without a stack. - mov esp, stack_top - - ;now enable SSE and the like - mov eax, cr0 - and ax, 0xFFFB ;clear coprocessor emulation CR0.EM - or ax, 0x2 ;set coprocessor monitoring CR0.MP - mov cr0, eax - mov eax, cr4 - or ax, 3 << 9 ;set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time - mov cr4, eax - - ; This is a good place to initialize crucial processor state before the - ; high-level kernel is entered. It's best to minimize the early - ; environment where crucial features are offline. Note that the - ; processor is not fully initialized yet: Features such as floating - ; point instructions and instruction set extensions are not initialized - ; yet. The GDT should be loaded here. Paging should be enabled here. - ; C++ features such as global constructors and exceptions will require - ; runtime support to work as well. - call gdt_load - - ; Enter the high-level kernel. The ABI requires the stack is 16-byte - ; aligned at the time of the call instruction (which afterwards pushes - ; the return pointer of size 4 bytes). The stack was originally 16-byte - ; aligned above and we've since pushed a multiple of 16 bytes to the - ; stack since (pushed 0 bytes so far) and the alignment is thus - ; preserved and the call is well defined. - ; note, that if you are building on Windows, C functions may have "_" prefix in assembly: _kmain - extern kmain - call kmain - - ; If the system has nothing more to do, put the computer into an - ; infinite loop. To do that: - ; 1) Disable interrupts with cli (clear interrupt enable in eflags). - ; They are already disabled by the bootloader, so this is not needed. - ; Mind that you might later enable interrupts and return from - ; kmain (which is sort of nonsensical to do). - ; 2) Wait for the next interrupt to arrive with hlt (halt instruction). - ; Since they are disabled, this will lock up the computer. - ; 3) Jump to the hlt instruction if it ever wakes up due to a - ; non-maskable interrupt occurring or due to system management mode. - cli -.hang: hlt - jmp .hang -.end: \ No newline at end of file diff --git a/arch/i386/boot/kernel.c b/arch/i386/boot/kernel.c index f0c8cdf..ba561ee 100644 --- a/arch/i386/boot/kernel.c +++ b/arch/i386/boot/kernel.c @@ -1,16 +1,119 @@ -#include +#include #include +#include +#include +#include +#include #include #include #include #include #include #include +#include +#include -uint8_t is_running = 1; +// We need to tell the stivale bootloader where we want our stack to be. +// We are going to allocate our stack as an uninitialised array in .bss. +static uint8_t stack[4096]; +void kmain(); + +bool is_running = true; int keyboard_descriptor = 0; int terminal_descriptor = 0; +// 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. + +// We are now going to define a framebuffer header tag, which is mandatory when +// using the stivale2 terminal. +// 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, + .next = 0 + }, + // set all the framebuffer specifics to 0 for it to pick the best it can. + .framebuffer_width = 800, + .framebuffer_height = 600, + .framebuffer_bpp = 32 +}; + +// 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. + .flags = (1 << 1), + // 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 +}; + +// We will now write a helper function which will allow us to scan for tags +// that we want FROM the bootloader (structure tags). +void *stivale2_get_tag(struct stivale2_struct *stivale2_struct, uint64_t id) { + struct stivale2_tag *current_tag = (void *)stivale2_struct->tags; + for (;;) { + // If the tag pointer is NULL (end of linked list), we did not find + // the tag. Return NULL to signal this. + if (current_tag == NULL) { + return NULL; + } + + // Check whether the identifier matches. If it does, return a pointer + // to the matching tag. + if (current_tag->identifier == id) { + return current_tag; + } + + // Get a pointer to the next tag in the linked list and repeat. + current_tag = (void *)current_tag->next; + } +} + +framebuffer_t *framebuffer; + +// The following will be our kernel's entry point. +void _start(struct stivale2_struct *stivale2_struct) { + struct stivale2_struct_tag_framebuffer *tagfb = stivale2_get_tag(stivale2_struct, STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID); + + if (tagfb == NULL) { + printf("Requested stivale2 tags were not found, hanging..."); + for (;;) { + asm ("hlt"); + } + } + framebuffer->address = (uint8_t*)tagfb->framebuffer_addr; + framebuffer->width = tagfb->framebuffer_width; + framebuffer->height = tagfb->framebuffer_height; + framebuffer->depth = tagfb->framebuffer_bpp; + framebuffer->pitch = tagfb->framebuffer_pitch; + framebuffer->pixelwidth = tagfb->framebuffer_bpp / 8; + + terminal_descriptor = terminal_initialize(framebuffer); + printf("Terminal initialized, descriptor: %d\n", terminal_descriptor); + + printf("Framebuffer | addr: %#X, width: %d, height: %d, depth: %d, pitch: %d\n", framebuffer->address, framebuffer->width, framebuffer->height, framebuffer->depth, framebuffer->pitch, framebuffer->pixelwidth); + + kmain(); +} + void shell() { printf("hello yes"); @@ -18,7 +121,7 @@ void shell() { printf("\n> "); while (true) { - unsigned char scancode = read(keyboard_descriptor, NULL); + uint32_t scancode = (uint32_t)read(keyboard_descriptor, NULL); if (!scancode) continue; bool special = true; @@ -56,46 +159,55 @@ extern void enable_paging(); uint32_t page_directory[1024] __attribute__((aligned(4096))); uint32_t first_page_table[1024] __attribute__((aligned(4096))); +uint32_t second_page_table[1024] __attribute__((aligned(4096))); -void kmain() { - //set each entry to not present +#define PAGE_PRESENT 1 << 0 +#define PAGE_WRITABLE 1 << 1 +#define PAGE_USER 1 << 2 +#define PAGE_WRITE_THROUGH 1 << 3 +#define PAGE_CACHE_DISABLE 1 << 4 +#define PAGE_ACCESSED 1 << 5 +#define PAGE_DIRTY 1 << 6 +#define PAGE_LARGE 1 << 7 +#define PAGE_GLOBAL 1 << 8 +/* +void setup_paging() { + // set each entry to not present for (uint32_t i = 0; i < 1024; i++) { - // This sets the following flags to the pages: - // Supervisor: Only kernel-mode can access them - // Write Enabled: It can be both read from and written to - // Not Present: The page table is not present - page_directory[i] = 0x00000002; + page_directory[i] = 0; } // i holds the physical address where we want to start mapping these pages to. // in this case, we want to map these pages to the very beginning of memory. // we will fill all 1024 entries in the table, mapping 4 megabytes for (uint32_t i = 0; i < 1024; i++) { - // As the address is page aligned, it will always leave 12 bits zeroed. - // Those bits are used by the attributes ;) - first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present. + first_page_table[i] = (i * 0x1000) | PAGE_PRESENT | PAGE_WRITABLE; } - // attributes: supervisor level, read/write, present - page_directory[0] = ((uint32_t)first_page_table) | 3; + page_directory[0] = ((uint32_t)first_page_table) | PAGE_PRESENT | PAGE_WRITABLE; - load_page_directory(page_directory); + load_page_directory((uint32_t)page_directory); enable_paging(); +} +*/ +void kmain() { + //setup_paging(); - terminal_descriptor = terminal_initialize(); - printf("Terminal initialized, descriptor: %d\n", terminal_descriptor); printf("Preparing interrupts... "); pic_init(); isr_install(); printf("done\n"); + + printf("Preparing IDE driver... \n"); + printf("Searching for IDE devices... \n"); + ide_init(); + + fillrect(framebuffer, 500, 200, 100, 100, 0x00FFD5FF); + fillrect(framebuffer, 600, 300, 100, 100, 0xFF00D5FF); keyboard_descriptor = keyboard_init(); printf("Keyboard ready, descriptor: %d\n", keyboard_descriptor); - printf("Preparing IDE driver... \n"); - printf("Searching for IDE devices... \n"); - ide_init(); - printf("Are interrupts enabled? "); if (are_interrupts_enabled() == 1) { printf("yes\n"); @@ -103,8 +215,8 @@ void kmain() { printf("no\n"); } - printf("kmain memory address: %p\n", kmain); + printf("kmain memory address: %#X\n", (unsigned int)kmain); printf("----------\n"); shell(); -} \ No newline at end of file +} diff --git a/arch/i386/drivers/framebuffer.c b/arch/i386/drivers/framebuffer.c new file mode 100644 index 0000000..abba19f --- /dev/null +++ b/arch/i386/drivers/framebuffer.c @@ -0,0 +1,24 @@ +#include +#include + +void putpixel(framebuffer_t *framebuffer, uint16_t x, uint16_t y, uint32_t color) { + if (color & 255 == 0) return; + uint64_t where = x * framebuffer->pixelwidth + y * framebuffer->pitch; + framebuffer->address[where] = (color >> 8) & 255; // BLUE + framebuffer->address[where + 1] = (color >> 16) & 255; // GREEN + framebuffer->address[where + 2] = (color >> 24) & 255; // RED +} + +void fillrect(framebuffer_t *framebuffer, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color) { + if (color & 255 == 0) return; + uint8_t* where; + uint32_t pw = framebuffer->pixelwidth; + for (uint16_t i = y; i < h + y; i++) { + where = (uint8_t*)((uint64_t)framebuffer->address + framebuffer->pitch * i); + for (uint16_t j = x; j < w + x; j++) { + where[j * pw] = (color >> 8) & 255; // BLUE + where[j * pw + 1] = (color >> 16) & 255; // GREEN + where[j * pw + 2] = (color >> 24) & 255; // RED + } + } +} diff --git a/arch/i386/drivers/ide/ide.c b/arch/i386/drivers/ide/ide.c index 6e5edc7..37f701c 100644 --- a/arch/i386/drivers/ide/ide.c +++ b/arch/i386/drivers/ide/ide.c @@ -88,7 +88,7 @@ void ide_read_buffer(unsigned char channel, unsigned char reg, if (reg > 0x07 && reg < 0x0C) ide_write(channel, ATA_REG_CONTROL, 0x80 | channels[channel].nIEN); - asm("pushw %es; movw %ds, %ax; movw %ax, %es"); + //asm("pushw %es; movw %ds, %ax; movw %ax, %es"); if (reg < 0x08) insl(channels[channel].base + reg - 0x00, buffer, quads); @@ -99,7 +99,7 @@ void ide_read_buffer(unsigned char channel, unsigned char reg, else if (reg < 0x16) insl(channels[channel].bmide + reg - 0x0E, buffer, quads); - asm("popw %es;"); + //asm("popw %es;"); if (reg > 0x07 && reg < 0x0C) ide_write(channel, ATA_REG_CONTROL, channels[channel].nIEN); diff --git a/arch/i386/drivers/keyboard/keyboard.c b/arch/i386/drivers/keyboard/keyboard.c index e0ebaa9..2ca4f0f 100644 --- a/arch/i386/drivers/keyboard/keyboard.c +++ b/arch/i386/drivers/keyboard/keyboard.c @@ -58,7 +58,6 @@ unsigned char keyboard_buffer_pop_key() { return scancode; } - unsigned char keyboard_get_key_from_scancode(unsigned char scancode) { return kbdus[scancode]; } @@ -80,12 +79,12 @@ uint8_t keyboard_enabled(void) { return __kbd_enabled; } -void* keyboard_read(void* data) { - return keyboard_buffer_pop_key(); +void* keyboard_read() { + return (void*) keyboard_buffer_pop_key(); } -void* keyboard_write(void* data) { - return -1; +void* keyboard_write() { + return (void*) -1; } int keyboard_init(void) { diff --git a/arch/i386/drivers/psf.c b/arch/i386/drivers/psf.c new file mode 100644 index 0000000..41a3bb2 --- /dev/null +++ b/arch/i386/drivers/psf.c @@ -0,0 +1,32 @@ +#include + +// c is a unicode character, cx and cy are cursor position in characters +void draw_psf_char(framebuffer_t *framebuffer, uint32_t c, uint16_t cx, uint16_t cy, uint32_t fg, uint32_t bg) { + PSF_font *font = (PSF_font*)&_binary_font_psfu_start; + // we need to know how many bytes encode one row + int bytesperline = (font->width + 7) / 8; + // get the glyph for the character. If there's no + // glyph for a given character, we'll display the first glyph. + uint8_t *glyph = (uint8_t*)&_binary_font_psfu_start + font->headersize + + (c > 0 && c < font->numglyph ? c : 0) * font->bytesperglyph; + // calculate the upper left corner on screen where we want to display. + // we only do this once, and adjust the whereet later. This is faster. + int where = (cy * font->height * framebuffer->pitch) + (cx * (font->width + 1) * 4); + // finally display pixels according to the bitmap + int x, y, line, mask; + for (y = 0; y < font->height; y++) { + // save the starting position of the line + line = where; + mask = 1 << (font->width - 1); + // display a row + for (x = 0; x < font->width; x++) { + *((uint32_t*)(framebuffer->address + line)) = *((uint32_t*)glyph) & mask ? fg : bg; + // adjust to the next pixel + mask >>= 1; + line += 4; + } + // adjust to the next line + glyph += bytesperline; + where += framebuffer->pitch; + } +} \ No newline at end of file diff --git a/arch/i386/drivers/tar/tar.c b/arch/i386/drivers/tar/tar.c index 3b66fd1..587d589 100644 --- a/arch/i386/drivers/tar/tar.c +++ b/arch/i386/drivers/tar/tar.c @@ -1,7 +1,7 @@ #include #include #include - +/* struct tar_header* tar_seek(int fd, char filename[100]) { unsigned int i; unsigned int addr; @@ -15,4 +15,5 @@ struct tar_header* tar_seek(int fd, char filename[100]) { addr += ((size / 512) + 1); if (size % 512) addr++; } -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/arch/i386/drivers/terminal/terminal.c b/arch/i386/drivers/terminal/terminal.c index b7cf5ec..e17a516 100644 --- a/arch/i386/drivers/terminal/terminal.c +++ b/arch/i386/drivers/terminal/terminal.c @@ -4,9 +4,10 @@ size_t terminal_row; size_t terminal_column; uint8_t terminal_color; -uint16_t* terminal_buffer; +uint16_t *terminal_buffer; +framebuffer_t *terminal_framebuffer; -void terminal_clear(void) { +void terminal_clear() { for (size_t y = 0; y < VGA_HEIGHT; y++) { for (size_t x = 0; x < VGA_WIDTH; x++) { const size_t index = y * VGA_WIDTH + x; @@ -35,10 +36,11 @@ void* terminal_devwrite(void* data) { return NULL; } -int terminal_initialize(void) { +int terminal_initialize(framebuffer_t *terminal_fb) { + terminal_framebuffer = terminal_fb; terminal_row = 0; terminal_column = 0; - terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); + terminal_color = vga_entry_color(VGA_COLOR_BLACK, VGA_COLOR_WHITE); terminal_buffer = (uint16_t*) 0xB8000; terminal_clear(); @@ -70,7 +72,7 @@ void terminal_clearlines(size_t from, size_t to) { } } -void terminal_updatecursor(void) { +void terminal_updatecursor() { size_t temp = terminal_row * VGA_WIDTH + terminal_column; outportb(0x3D4, 14); outportb(0x3D5, temp >> 8); @@ -78,7 +80,7 @@ void terminal_updatecursor(void) { outportb(0x3D5, temp); } -void terminal_scrollup(void) { +void terminal_scrollup() { for (size_t index = 0; index < VGA_WIDTH * (VGA_HEIGHT - 1); index++) { terminal_buffer[index] = terminal_buffer[index + VGA_WIDTH]; } @@ -92,17 +94,19 @@ void terminal_scrollup(void) { terminal_updatecursor(); } -void terminal_checknewline(void) { +void terminal_checknewline() { if (terminal_row >= VGA_HEIGHT - 1) { terminal_scrollup(); } } void terminal_putentryat(char c, uint8_t color, size_t x, size_t y) { - terminal_buffer[y * VGA_WIDTH + x] = vga_entry(c, color); + //terminal_buffer[y * VGA_WIDTH + x] = vga_entry(c, color); + draw_psf_char(terminal_framebuffer, c, x, y, 0xFFFFFFFF, 0); } void terminal_putchar(char c) { + outportb(0x3F8, c); // log terminal to serial.log when running on qemu switch (c) { case '\b': if (--terminal_column < 0) { diff --git a/font.psfu b/font.psfu new file mode 100644 index 0000000000000000000000000000000000000000..e789b77189b9c3e585075eeed5a5eba693f3c435 GIT binary patch literal 4969 zcmZu!TWlO>6&`}L;$h{6w-K?N0^xq?(t@+JgAJkF3KS@m`(;VWHo(xD0*;}>W}P~& zLoL*ccN5dnI7yQ<7bp!)5NV<;Gt!6$Yx9OyT4P1?V80+_sZ!#HXg|L5UuI`qj{VQf z`Oo*C|J?pFvyYs=XWAj%%JBwy;AJy!GTtQo>!>z)d~)*g{N!X!i)!cs(JEkg$MJil zpe!mBZ7v5{*7dyA)m7K^jM(*RT-@h5O^Bd}QQ9 z18=!~Vv#hVHF#B$=W+whkKQp_B8{zG)BN6Ddv}o@TwQ7D3D@m#b{R>%H~0 zYpuExZz>E7jr2x_1`3-D+@or@W({^^I}-0&zPH=$KDtFn@j+ZE`*G}-i*cX<>M9}A zEW@GonRsfRQ^tOIBK0?9xQe}^kt!XfO0QDND0f<|meHa`7h)B;MLkn;i;CR7hgA=riMGNpI(9Fsg@$AnIBBh>a_bK#HWkD^lW!-8 z<1T4UbKP$rrprp*JM{8{=iFA~Nw<7)Sgq(z{fl?6MhxS@%U)t@`U)-mC81J+Zs8vufgH_)29h zvwk^_t9NQ%c2e7!{iOI5d0IZCs-b`0SGd*01UFsL^0kVhbU*1N-AKsjU%B2}Zuk9B zu@=_&tNarc#y%te*K$xC5DiK$KAQa~uat|0bUnKBIeSI5BBNiK5=CrL+8)JsyRiL3 ziCnL0?WLSplJOtWv?T8zk?xI-r;kgiWaJJz*jRZm?N^>YKE3MaoRVor~7C{OLVitgn-ynDL2{-3kKtaqyVC7~1fr`qJi7(~j0$&V@s)bX( zKQ8)Bd|8@h6;R_}q2LVgIFQ)pxtMre00ytY{df_w0`}x?mrt6OM7@nSr*w+@{%CoS zmVmX-9_gj=YQH|zdRBn-Z*!@1Q&KWKXm)cPVx(*}>xlDJe{lPx{i6d$yDkEwmeZi%EK!<%=Fopq#~vb5DQ29e^;d>+5mP4ULQ?baW4 z-(DI`can$EQeJ+;N%bonoEsa~r+6bz@d|gNk5~4gug~a7@pk=2|8n~c52yAj9Q{-4 z>?Px`nHt@&9+ubksN-t4l>5efrSVfgf-)DQKb=|IK(}ll1GJXv`}k6)(^=Br=Z^fg z>MXJav9SyB+l+@%NH`(+{1?(30qkl0_Y-GpRM%16MM2cdmmRic7K|@xR}EWZ3s=A3 z3~$;q+k_%vW7+P%njhll?1-q;{YfTkeA(Bul-D;F$iG&z+YOc~(%vhjL4&aUHMT2w zSoFV{Fh4JBO_ziR^`9N7mVR!_9&D2Q*QENPdG6or%RHTN z?b9vl^X@;s?`eNJ5*nKdg2pPX;Q<%dU9|I$#jDYFCn~u@FZo#OuxwS6vs0h zPjftpWae-(OO4ZWgq-8Jgj>Ufq+U9|WFt($NkK#_;1rHy?2uAU7 zd;&Z0N!*Q3;nVmGK8w%c9(*2Oz!z~ZzJxF1E4U9|#n*5@zK(C;oA?&Kjql*Q_#VEG zAE1ICVkdUt0sIJ6Jc!-+F@A!d!pG0>5FW-DevU`*3;Ytl!Z`L|0>8#@@F)WO7BwWZ z`w%^j=n|q+h>jw90nq}Y(2!XgILk2pjqD7{%D_#bt?PtX7W literal 0 HcmV?d00001 diff --git a/include/drivers/keyboard/keyboard.h b/include/drivers/keyboard/keyboard.h index 24e202f..a85cc79 100644 --- a/include/drivers/keyboard/keyboard.h +++ b/include/drivers/keyboard/keyboard.h @@ -13,6 +13,7 @@ extern "C" { int keyboard_init(void); uint8_t keyboard_enabled(void); +unsigned char keyboard_get_key_from_scancode(unsigned char scancode); #ifdef __cplusplus } diff --git a/include/drivers/terminal/terminal.h b/include/drivers/terminal/terminal.h index eee867b..f5e42b6 100644 --- a/include/drivers/terminal/terminal.h +++ b/include/drivers/terminal/terminal.h @@ -4,6 +4,8 @@ #include #include #include +#include +#include #ifdef __cplusplus extern "C" { @@ -29,11 +31,11 @@ enum vga_color { VGA_COLOR_WHITE = 15, }; -static inline uint8_t vga_entry_color(enum vga_color const fg, enum vga_color const bg) { - return fg | bg << 4; +static inline uint8_t vga_entry_color(const enum vga_color fg, const enum vga_color bg) { + return fg | (bg << 4); } -static inline uint16_t vga_entry(unsigned char const uc, uint8_t const color) { +static inline uint16_t vga_entry(const uint8_t uc, const uint8_t color) { return (uint16_t) uc | (uint16_t) color << 8; } @@ -43,25 +45,25 @@ static const size_t VGA_HEIGHT = 25; extern size_t terminal_row; extern size_t terminal_column; extern uint8_t terminal_color; -extern uint16_t* terminal_buffer; +extern uint16_t *terminal_buffer; -void terminal_clear(void); -int terminal_initialize(void); +void terminal_clear(); +int terminal_initialize(framebuffer_t *terminal_fb); void terminal_setcolor(uint8_t color); void terminal_clearline(size_t line); void terminal_clearlines(size_t from, size_t to); -void terminal_updatecursor(void); -void terminal_scrollup(void); -void terminal_checknewline(void); +void terminal_updatecursor(); +void terminal_scrollup(); +void terminal_checknewline(); void terminal_putentryat(char c, uint8_t color, size_t x, size_t y); void terminal_putchar(char c); void terminal_write(const char* data, size_t size); -static inline void terminal_writestring(const char* data) { +static inline void terminal_writestring(const char *data) { terminal_write(data, strlen(data)); } -static inline void terminal_writeline(const char* data) { +static inline void terminal_writeline(const char *data) { terminal_writestring(data); terminal_putchar('\n'); } diff --git a/include/framebuffer.h b/include/framebuffer.h new file mode 100644 index 0000000..14a412d --- /dev/null +++ b/include/framebuffer.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + uint8_t *address; + uint32_t width; + uint32_t height; + uint32_t depth; + uint32_t pitch; + uint32_t pixelwidth; +} framebuffer_t; + +void putpixel(framebuffer_t *framebuffer, uint16_t x, uint16_t y, uint32_t color); +void fillrect(framebuffer_t *framebuffer, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color); + +#ifdef __cplusplus +} +#endif diff --git a/include/psf.h b/include/psf.h new file mode 100644 index 0000000..829ca50 --- /dev/null +++ b/include/psf.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define PSF_FONT_MAGIC 0x864ab572 + +typedef struct { + uint32_t magic; /* magic bytes to identify PSF */ + uint32_t version; /* zero */ + uint32_t headersize; /* whereet of bitmaps in file, 32 */ + uint32_t flags; /* 0 if there's no unicode table */ + uint32_t numglyph; /* number of glyphs */ + uint32_t bytesperglyph; /* size of each glyph */ + uint32_t height; /* height in pixels */ + uint32_t width; /* width in pixels */ +} PSF_font; + +// these are linked using objcopy +extern char _binary_font_psfu_start; +extern char _binary_font_psfu_end; + +// c is a unicode character, cx and cy are cursor position in characters +void draw_psf_char(framebuffer_t *framebuffer, uint32_t c, uint16_t cx, uint16_t cy, uint32_t fg, uint32_t bg); + +#ifdef __cplusplus +} +#endif diff --git a/include/std/inline.h b/include/std/inline.h index e2130c6..11e5b52 100644 --- a/include/std/inline.h +++ b/include/std/inline.h @@ -7,15 +7,15 @@ extern "C" { #endif -static inline void outportb(uint16_t const port, uint8_t const val) { +static inline void outportb(const uint16_t port, const uint8_t val) { asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) ); } -static inline void outportw(uint16_t const port, uint16_t const val) { +static inline void outportw(const uint16_t port, const uint16_t val) { asm volatile ( "outw %0, %1" : : "a"(val), "Nd"(port) ); } -static inline void outportl(uint16_t const port, uint32_t const val) { +static inline void outportl(const uint16_t port, const uint32_t val) { asm volatile ( "outl %0, %1" : : "a"(val), "Nd"(port) ); } @@ -23,19 +23,19 @@ static inline void outportsm(unsigned short port, unsigned char* data, unsigned asm volatile ("rep outsw" : "+S" (data), "+c" (size) : "d" (port)); } -static inline uint8_t inportb(uint16_t const port) { +static inline uint8_t inportb(const uint16_t port) { uint8_t ret; asm volatile ( "inb %1, %0" : "=a"(ret) : "Nd"(port) ); return ret; } -static inline uint16_t inportw(uint16_t const port) { +static inline uint16_t inportw(const uint16_t port) { uint16_t ret; asm volatile ( "inw %1, %0" : "=a"(ret) : "Nd"(port) ); return ret; } -static inline uint32_t inportl(uint16_t const port) { +static inline uint32_t inportl(const uint16_t port) { uint32_t ret; asm volatile ( "inl %1, %0" : "=a"(ret) : "Nd"(port) ); return ret; diff --git a/include/stivale2.h b/include/stivale2.h new file mode 100644 index 0000000..ccddfa2 --- /dev/null +++ b/include/stivale2.h @@ -0,0 +1,251 @@ +#ifndef __STIVALE__STIVALE2_H__ +#define __STIVALE__STIVALE2_H__ + +#include + +struct stivale2_tag { + uint64_t identifier; + uint64_t next; +} __attribute__((__packed__)); + +/* --- Header --------------------------------------------------------------- */ +/* Information passed from the kernel to the bootloader */ + +struct stivale2_header { + uint64_t entry_point; + uint64_t stack; + uint64_t flags; + uint64_t tags; +} __attribute__((__packed__)); + +#define STIVALE2_HEADER_TAG_FRAMEBUFFER_ID 0x3ecc1bc43d0f7971 + +struct stivale2_header_tag_framebuffer { + struct stivale2_tag tag; + uint16_t framebuffer_width; + uint16_t framebuffer_height; + uint16_t framebuffer_bpp; +} __attribute__((__packed__)); + +#define STIVALE2_HEADER_TAG_FB_MTRR_ID 0x4c7bb07731282e00 + +#define STIVALE2_HEADER_TAG_TERMINAL_ID 0xa85d499b1823be72 + +struct stivale2_header_tag_terminal { + struct stivale2_tag tag; + uint64_t flags; +} __attribute__((__packed__)); + +#define STIVALE2_HEADER_TAG_SMP_ID 0x1ab015085f3273df + +struct stivale2_header_tag_smp { + struct stivale2_tag tag; + uint64_t flags; +} __attribute__((__packed__)); + +#define STIVALE2_HEADER_TAG_5LV_PAGING_ID 0x932f477032007e8f + +#define STIVALE2_HEADER_TAG_UNMAP_NULL_ID 0x92919432b16fe7e7 + +/* --- Struct --------------------------------------------------------------- */ +/* Information passed from the bootloader to the kernel */ + +struct stivale2_struct { +#define STIVALE2_BOOTLOADER_BRAND_SIZE 64 + char bootloader_brand[STIVALE2_BOOTLOADER_BRAND_SIZE]; + +#define STIVALE2_BOOTLOADER_VERSION_SIZE 64 + char bootloader_version[STIVALE2_BOOTLOADER_VERSION_SIZE]; + + uint64_t tags; +} __attribute__((__packed__)); + +#define STIVALE2_STRUCT_TAG_CMDLINE_ID 0xe5e76a1b4597a781 + +struct stivale2_struct_tag_cmdline { + struct stivale2_tag tag; + uint64_t cmdline; +} __attribute__((__packed__)); + +#define STIVALE2_STRUCT_TAG_MEMMAP_ID 0x2187f79e8612de07 + +#define STIVALE2_MMAP_USABLE 1 +#define STIVALE2_MMAP_RESERVED 2 +#define STIVALE2_MMAP_ACPI_RECLAIMABLE 3 +#define STIVALE2_MMAP_ACPI_NVS 4 +#define STIVALE2_MMAP_BAD_MEMORY 5 +#define STIVALE2_MMAP_BOOTLOADER_RECLAIMABLE 0x1000 +#define STIVALE2_MMAP_KERNEL_AND_MODULES 0x1001 +#define STIVALE2_MMAP_FRAMEBUFFER 0x1002 + +struct stivale2_mmap_entry { + uint64_t base; + uint64_t length; + uint32_t type; + uint32_t unused; +} __attribute__((__packed__)); + +struct stivale2_struct_tag_memmap { + struct stivale2_tag tag; + uint64_t entries; + struct stivale2_mmap_entry memmap[]; +} __attribute__((__packed__)); + +#define STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID 0x506461d2950408fa + +#define STIVALE2_FBUF_MMODEL_RGB 1 + +struct stivale2_struct_tag_framebuffer { + struct stivale2_tag tag; + uint64_t framebuffer_addr; + uint16_t framebuffer_width; + uint16_t framebuffer_height; + uint16_t framebuffer_pitch; + uint16_t framebuffer_bpp; + uint8_t memory_model; + uint8_t red_mask_size; + 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__)); + +#define STIVALE2_STRUCT_TAG_EDID_ID 0x968609d7af96b845 + +struct stivale2_struct_tag_edid { + struct stivale2_tag tag; + uint64_t edid_size; + uint8_t edid_information[]; +} __attribute__((__packed__)); + +#define STIVALE2_STRUCT_TAG_FB_MTRR_ID 0x6bc1a78ebe871172 + +#define STIVALE2_STRUCT_TAG_TERMINAL_ID 0xc2b3f4c3233b0974 + +struct stivale2_struct_tag_terminal { + struct stivale2_tag tag; + uint32_t flags; + uint16_t cols; + uint16_t rows; + uint64_t term_write; +} __attribute__((__packed__)); + +#define STIVALE2_STRUCT_TAG_MODULES_ID 0x4b6fe466aade04ce + +struct stivale2_module { + uint64_t begin; + uint64_t end; + +#define STIVALE2_MODULE_STRING_SIZE 128 + char string[STIVALE2_MODULE_STRING_SIZE]; +} __attribute__((__packed__)); + +struct stivale2_struct_tag_modules { + struct stivale2_tag tag; + uint64_t module_count; + struct stivale2_module modules[]; +} __attribute__((__packed__)); + +#define STIVALE2_STRUCT_TAG_RSDP_ID 0x9e1786930a375e78 + +struct stivale2_struct_tag_rsdp { + struct stivale2_tag tag; + uint64_t rsdp; +} __attribute__((__packed__)); + +#define STIVALE2_STRUCT_TAG_EPOCH_ID 0x566a7bed888e1407 + +struct stivale2_struct_tag_epoch { + struct stivale2_tag tag; + uint64_t epoch; +} __attribute__((__packed__)); + +#define STIVALE2_STRUCT_TAG_FIRMWARE_ID 0x359d837855e3858c + +#define STIVALE2_FIRMWARE_BIOS (1 << 0) + +struct stivale2_struct_tag_firmware { + struct stivale2_tag tag; + uint64_t flags; +} __attribute__((__packed__)); + +#define STIVALE2_STRUCT_TAG_EFI_SYSTEM_TABLE_ID 0x4bc5ec15845b558e + +struct stivale2_struct_tag_efi_system_table { + struct stivale2_tag tag; + uint64_t system_table; +} __attribute__((__packed__)); + +#define STIVALE2_STRUCT_TAG_KERNEL_FILE_ID 0xe599d90c2975584a + +struct stivale2_struct_tag_kernel_file { + struct stivale2_tag tag; + uint64_t kernel_file; +} __attribute__((__packed__)); + +#define STIVALE2_STRUCT_TAG_KERNEL_SLIDE_ID 0xee80847d01506c57 + +struct stivale2_struct_tag_kernel_slide { + struct stivale2_tag tag; + uint64_t kernel_slide; +} __attribute__((packed)); + +#define STIVALE2_STRUCT_TAG_SMBIOS_ID 0x274bd246c62bf7d1 + +struct stivale2_struct_tag_smbios { + struct stivale2_tag tag; + uint64_t flags; + uint64_t smbios_entry_32; + uint64_t smbios_entry_64; +} __attribute__((packed)); + +#define STIVALE2_STRUCT_TAG_SMP_ID 0x34d1d96339647025 + +struct stivale2_smp_info { + uint32_t processor_id; + uint32_t lapic_id; + uint64_t target_stack; + uint64_t goto_address; + uint64_t extra_argument; +} __attribute__((__packed__)); + +struct stivale2_struct_tag_smp { + struct stivale2_tag tag; + uint64_t flags; + uint32_t bsp_lapic_id; + uint32_t unused; + uint64_t cpu_count; + struct stivale2_smp_info smp_info[]; +} __attribute__((__packed__)); + +#define STIVALE2_STRUCT_TAG_PXE_SERVER_INFO 0x29d1e96239247032 + +struct stivale2_struct_tag_pxe_server_info { + struct stivale2_tag tag; + uint32_t server_ip; +} __attribute__((__packed__)); + +#define STIVALE2_STRUCT_TAG_MMIO32_UART 0xb813f9b8dbc78797 + +struct stivale2_struct_tag_mmio32_uart { + struct stivale2_tag tag; + uint64_t addr; +} __attribute__((__packed__)); + +#define STIVALE2_STRUCT_TAG_DTB 0xabb29bd49a2833fa + +struct stivale2_struct_tag_dtb { + struct stivale2_tag tag; + uint64_t addr; + uint64_t size; +} __attribute__((__packed__)); + +#define STIVALE2_STRUCT_TAG_VMAP 0xb0ed257db18cb58f + +struct stivale2_struct_vmap { + struct stivale2_tag tag; + uint64_t addr; +} __attribute__((__packed__)); + +#endif \ No newline at end of file diff --git a/limine b/limine new file mode 160000 index 0000000..2862a26 --- /dev/null +++ b/limine @@ -0,0 +1 @@ +Subproject commit 2862a261450af7cb2b1504b5a3ed15c32759deaa diff --git a/limine.cfg b/limine.cfg new file mode 100644 index 0000000..b927c48 --- /dev/null +++ b/limine.cfg @@ -0,0 +1,14 @@ +# Timeout in seconds that Limine will use before automatically booting. +TIMEOUT=5 + +# The entry name that will be displayed in the boot menu +:HhhOS + +# Change the protocol line depending on the used protocol. +PROTOCOL=stivale2 + +# Path to the kernel to boot. boot:/// represents the partition on which limine.cfg is located. +KERNEL_PATH=boot:///hhhos.elf + +# Remove the following line to enable kernel address layout randomisation. +KASLR=no \ No newline at end of file diff --git a/linker.ld b/linker.ld index 7292df5..877fe56 100644 --- a/linker.ld +++ b/linker.ld @@ -1,43 +1,34 @@ -/* The bootloader will look at this image and start execution at the symbol - designated as the entry point. */ +/* Tell the linker that we want the symbol _start to be our 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; + /* We wanna be placed in the higher half, 2MiB above 0 in physical memory. */ + /* Since we are going to use PIE, this is just the base load address, but the */ + /* bootloader will be able to relocate us as it sees fit. */ + . = 0xffffffff80200000; - /* 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) - } + /* We place the .stivale2hdr section containing the header in its own section, */ + /* and we use the KEEP directive on it to make sure it doesn't get discarded. */ + .stivale2hdr : { + KEEP(*(.stivale2hdr)) + } - /* Read-only data. */ - .rodata BLOCK(4K) : ALIGN(4K) - { - *(.rodata) - } + /* Then let's place all the other traditional executable sections afterwards. */ + .text : { + *(.text*) + } - /* Read-write data (initialized) */ - .data BLOCK(4K) : ALIGN(4K) - { - *(.data) - } + .rodata : { + *(.rodata*) + } - /* Read-write data (uninitialized) and stack */ - .bss BLOCK(4K) : ALIGN(4K) - { - *(COMMON) - *(.bss) - } + .data : { + *(.data*) + } - /* 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 : { + *(COMMON) + *(.bss*) + } } \ No newline at end of file diff --git a/sysroot/boot/grub/grub.cfg b/sysroot/boot/grub/grub.cfg deleted file mode 100644 index a2aa596..0000000 --- a/sysroot/boot/grub/grub.cfg +++ /dev/null @@ -1,3 +0,0 @@ -menuentry "HhhOS" { - multiboot /boot/hhhos.bin -} \ No newline at end of file