commit 115b4c88a1dccad461f5ee222a59500109d65a68 Author: Justus Wolff Date: Thu Feb 26 00:06:36 2026 +0100 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c795b05 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build \ No newline at end of file diff --git a/README b/README new file mode 100644 index 0000000..87b6fef --- /dev/null +++ b/README @@ -0,0 +1,3 @@ +compilation: (with installed dependencies, see dependencies.txt) + +make build \ No newline at end of file diff --git a/dependencies.txt b/dependencies.txt new file mode 100644 index 0000000..cbf2693 --- /dev/null +++ b/dependencies.txt @@ -0,0 +1,4 @@ +to compile: + +grub-pc-bin, gcc, makefile, grub-mkrescue, tar, +and lastly: L I N U X \ No newline at end of file diff --git a/grubtemplate/boot/grub/grub.cfg b/grubtemplate/boot/grub/grub.cfg new file mode 100644 index 0000000..ec22ed4 --- /dev/null +++ b/grubtemplate/boot/grub/grub.cfg @@ -0,0 +1,5 @@ +menuentry "JPOS" { + multiboot2 /boot/kernel + module2 /boot/JPOS.initrd + boot +} \ No newline at end of file diff --git a/initrd/vga/main.c b/initrd/vga/main.c new file mode 100644 index 0000000..903c7b0 --- /dev/null +++ b/initrd/vga/main.c @@ -0,0 +1,9 @@ +void main() { + volatile char *video = (volatile char*)0xB8000; // small welcome message + char* welcome = "Hello VGA, World!"; + + while (*welcome != 0) { + *video++ = *welcome++; + *video++ = 15; + } +} \ No newline at end of file diff --git a/linker.ld b/linker.ld new file mode 100644 index 0000000..cfb6ff1 --- /dev/null +++ b/linker.ld @@ -0,0 +1,30 @@ +ENTRY(_start) + +SECTIONS { + . = ALIGN(8); + .boot : { + KEEP(*(.multiboot)) + } + . = 1M; /* Load kernel at 1MB */ + + .text BLOCK(4K) : ALIGN(4K) + { + *(.text) + } + + .rodata BLOCK(4K) : ALIGN(4K) + { + *(.rodata) + } + + .data BLOCK(4K) : ALIGN(4K) + { + *(.data) + } + + .bss BLOCK(4K) : ALIGN(4K) + { + *(COMMON) + *(.bss) + } +} \ No newline at end of file diff --git a/makefile b/makefile new file mode 100644 index 0000000..067baa5 --- /dev/null +++ b/makefile @@ -0,0 +1,27 @@ +build: prepare copygrub + nasm -felf32 src/bootload/boot.asm -o build/boot.o # entrypoint for grub + + gcc -c src/kernel/entry.c -o build/kernel.o -ffreestanding -O2 -Wall -Wextra -m32 # kernel + gcc -c src/kernel/registrar.c -o build/registrar.o -ffreestanding -O2 -Wall -Wextra -m32 # registrar + + gcc -c initrd/vga/main.c -o build/initrddir/vga_graph -ffreestanding -O2 -Wall -Wextra -m32 # initrd/vga driver + + tar -czf build/initrd build/initrddir/* # build initrd + + gcc -m32 -T linker.ld -o build/linked -ffreestanding -O2 -nostdlib build/boot.o build/kernel.o build/registrar.o -fno-pie -fno-pic -no-pie # link + + cp build/linked build/grub/boot/kernel # copy kernel over to grub template + cp build/initrd build/grub/boot/JPOS.initrd # copy initrd to grub template + + grub-mkrescue /usr/lib/grub/i386-pc -o build/live.iso build/grub # create final image +test: build + qemu-system-i386 \ + -boot d \ + -cdrom build/live.iso +copygrub: + cp grubtemplate -r build/grub +prepare: clean + mkdir build + mkdir build/initrddir +clean: + -rm -rf build \ No newline at end of file diff --git a/src/bootload/GDT.asm b/src/bootload/GDT.asm new file mode 100644 index 0000000..67323e2 --- /dev/null +++ b/src/bootload/GDT.asm @@ -0,0 +1,28 @@ +gdt_start: + dd 0x0 ; 4 byte + dd 0x0 ; 4 byte + +gdt_code: + dw 0xffff ; segment length, bits 0-15 + dw 0x0 ; segment base, bits 0-15 + db 0x0 ; segment base, bits 16-23 + db 10011010b ; flags (8 bits) + db 11001111b ; flags (4 bits) + segment length, bits 16-19 + db 0x0 ; segment base, bits 24-31 + +gdt_data: + dw 0xffff + dw 0x0 + db 0x0 + db 10010010b + db 11001111b + db 0x0 + +gdt_end: + +gdt_descriptor: + dw gdt_end - gdt_start - 1 + dd gdt_start + +CODE_SEG equ gdt_code - gdt_start +DATA_SEG equ gdt_data - gdt_start \ No newline at end of file diff --git a/src/bootload/boot.asm b/src/bootload/boot.asm new file mode 100644 index 0000000..6c9b583 --- /dev/null +++ b/src/bootload/boot.asm @@ -0,0 +1,69 @@ +; constants for multiboot +MAGIC equ 0xE85250D6 +ARCH equ 0 ; 0 for i386, 4 for MIPS +HDRLEN equ 24 ; Total length: 4 fields + end tag +CHECKSUM equ -(MAGIC + ARCH + HDRLEN) + +section .multiboot_header +align 8 +header_start: + dd 0xE85250D6 ; Magic + dd 0 ; Architecture (i386) + dd header_end - header_start ; Length + dd -(0xE85250D6 + 0 + (header_end - header_start)) ; Checksum + + ; End tag + dw 0 ; Type + dw 0 ; Flags + dd 8 ; Size +header_end: + + +section .bss +align 16 +stack_bottom: +resb 16384 ; 16 KiB is reserved for stack +stack_top: + +section .rodata +%include "src/bootload/GDT.asm" + +section .text ; entrypoint for bootloader +[BITS 32] +global _start:function (_start.end - _start) +_start: + ; 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 + mov ebp, esp + + mov ecx, eax ; move multiboot magic number to ecx + + ; TODO: + ; load GDT [x] + ; enter long m. [ ] + ; init FPU [ ] + + ; load GDT + cli + lgdt [gdt_descriptor] + jmp CODE_SEG:.final ; if I get problems, check this line here, future me! +.final: + mov AX, DATA_SEG ; data segment selectors + mov DS, AX + mov ES, AX + mov FS, AX + mov GS, AX + mov SS, AX + + push ecx ; magic number + push ebx ; info structure + extern kernel_main + call kernel_main + add esp, 8 ; remove arguments + cli ; the infamous infinite loop +.hang: hlt + jmp .hang +.end: + diff --git a/src/bootload/longm.asm b/src/bootload/longm.asm new file mode 100644 index 0000000..f8b66cb --- /dev/null +++ b/src/bootload/longm.asm @@ -0,0 +1,55 @@ +; DEPRECATED! + +CPUID_EXTENSIONS equ 0x80000000 +CPUID_EXT_FEATURES equ 0x80000001 +EFLAGS_ID equ 1 << 21 +CPUID_EDX_EXT_FEAT_LM equ 1 << 29 + +enterlong: + call .queryLongMode + + +.NoLongMode + cli + hlt + jmp .NoLongMode + +.checkCPUID: + pushfd + pop eax + + ; The original value should be saved for comparison and restoration later + mov ecx, eax + xor eax, EFLAGS_ID + + ; storing the eflags and then retrieving it again will show whether or not + ; the bit could successfully be flipped + push eax ; save to eflags + popfd + pushfd ; restore from eflags + pop eax + + ; Restore EFLAGS to its original value + push ecx + popfd + + ; if the bit in eax was successfully flipped (eax != ecx), CPUID is supported. + xor eax, ecx + jnz .NoLongMode + ret + +.queryLongMode: + call .checkCPUID + + mov eax, CPUID_EXTENSIONS + cpuid + cmp eax, CPUID_FEATURES + jb .NoLongMode + + mov eax, CPUID_EXT_FEATURES + cpuid + test edx, CPUID_EDX_EXT_FEAT_LM + jz .NoLongMode + + ret + diff --git a/src/headers/multiboot2.h b/src/headers/multiboot2.h new file mode 100644 index 0000000..518a750 --- /dev/null +++ b/src/headers/multiboot2.h @@ -0,0 +1,416 @@ +/* multiboot2.h - Multiboot 2 header file. */ +/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY + * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef MULTIBOOT_HEADER +#define MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 32768 +#define MULTIBOOT_HEADER_ALIGN 8 + +/* The magic field should contain this. */ +#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 + +/* This should be in %eax. */ +#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000008 + +/* Flags set in the 'flags' member of the multiboot header. */ + +#define MULTIBOOT_TAG_ALIGN 8 +#define MULTIBOOT_TAG_TYPE_END 0 +#define MULTIBOOT_TAG_TYPE_CMDLINE 1 +#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 +#define MULTIBOOT_TAG_TYPE_MODULE 3 +#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4 +#define MULTIBOOT_TAG_TYPE_BOOTDEV 5 +#define MULTIBOOT_TAG_TYPE_MMAP 6 +#define MULTIBOOT_TAG_TYPE_VBE 7 +#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 +#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 +#define MULTIBOOT_TAG_TYPE_APM 10 +#define MULTIBOOT_TAG_TYPE_EFI32 11 +#define MULTIBOOT_TAG_TYPE_EFI64 12 +#define MULTIBOOT_TAG_TYPE_SMBIOS 13 +#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14 +#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15 +#define MULTIBOOT_TAG_TYPE_NETWORK 16 +#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17 +#define MULTIBOOT_TAG_TYPE_EFI_BS 18 +#define MULTIBOOT_TAG_TYPE_EFI32_IH 19 +#define MULTIBOOT_TAG_TYPE_EFI64_IH 20 +#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21 + +#define MULTIBOOT_HEADER_TAG_END 0 +#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 +#define MULTIBOOT_HEADER_TAG_ADDRESS 2 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3 +#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4 +#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 +#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6 +#define MULTIBOOT_HEADER_TAG_EFI_BS 7 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8 +#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 +#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10 + +#define MULTIBOOT_ARCHITECTURE_I386 0 +#define MULTIBOOT_ARCHITECTURE_MIPS32 4 +#define MULTIBOOT_HEADER_TAG_OPTIONAL 1 + +#define MULTIBOOT_LOAD_PREFERENCE_NONE 0 +#define MULTIBOOT_LOAD_PREFERENCE_LOW 1 +#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2 + +#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 +#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 + +#ifndef ASM_FILE + +typedef unsigned char multiboot_uint8_t; +typedef unsigned short multiboot_uint16_t; +typedef unsigned int multiboot_uint32_t; +typedef unsigned long long multiboot_uint64_t; + +struct multiboot_header { + /* Must be MULTIBOOT_MAGIC - see above. */ + multiboot_uint32_t magic; + + /* ISA */ + multiboot_uint32_t architecture; + + /* Total header length. */ + multiboot_uint32_t header_length; + + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; +}; + +struct multiboot_header_tag +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; +}; + +struct multiboot_header_tag_information_request +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t requests[0]; +}; + +struct multiboot_header_tag_address +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; +}; + +struct multiboot_header_tag_entry_address +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t entry_addr; +}; + +struct multiboot_header_tag_console_flags +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t console_flags; +}; + +struct multiboot_header_tag_framebuffer +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +struct multiboot_header_tag_module_align +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; +}; + +struct multiboot_header_tag_relocatable +{ + multiboot_uint16_t type; + multiboot_uint16_t flags; + multiboot_uint32_t size; + multiboot_uint32_t min_addr; + multiboot_uint32_t max_addr; + multiboot_uint32_t align; + multiboot_uint32_t preference; +}; + +struct multiboot_color +{ + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + +struct multiboot_mmap_entry +{ + multiboot_uint64_t addr; + multiboot_uint64_t len; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 + multiboot_uint32_t type; + multiboot_uint32_t zero; +}; +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_tag +{ + multiboot_uint32_t type; + multiboot_uint32_t size; +}; + +struct multiboot_tag_string +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + char string[0]; +}; + +struct multiboot_tag_module +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + char cmdline[0]; +}; + +struct multiboot_tag_basic_meminfo +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; +}; + +struct multiboot_tag_bootdev +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t biosdev; + multiboot_uint32_t slice; + multiboot_uint32_t part; +}; + +struct multiboot_tag_mmap +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t entry_size; + multiboot_uint32_t entry_version; + struct multiboot_mmap_entry entries[0]; +}; + +struct multiboot_vbe_info_block +{ + multiboot_uint8_t external_specification[512]; +}; + +struct multiboot_vbe_mode_info_block +{ + multiboot_uint8_t external_specification[256]; +}; + +struct multiboot_tag_vbe +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; + + struct multiboot_vbe_info_block vbe_control_info; + struct multiboot_vbe_mode_info_block vbe_mode_info; +}; + +struct multiboot_tag_framebuffer_common +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + multiboot_uint8_t framebuffer_type; + multiboot_uint16_t reserved; +}; + +struct multiboot_tag_framebuffer +{ + struct multiboot_tag_framebuffer_common common; + + union + { + struct + { + multiboot_uint16_t framebuffer_palette_num_colors; + struct multiboot_color framebuffer_palette[0]; + }; + struct + { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; +}; + +struct multiboot_tag_elf_sections +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t num; + multiboot_uint32_t entsize; + multiboot_uint32_t shndx; + char sections[0]; +}; + +struct multiboot_tag_apm +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; +}; + +struct multiboot_tag_efi32 +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t pointer; +}; + +struct multiboot_tag_efi64 +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint64_t pointer; +}; + +struct multiboot_tag_smbios +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t major; + multiboot_uint8_t minor; + multiboot_uint8_t reserved[6]; + multiboot_uint8_t tables[0]; +}; + +struct multiboot_tag_old_acpi +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t rsdp[0]; +}; + +struct multiboot_tag_new_acpi +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t rsdp[0]; +}; + +struct multiboot_tag_network +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint8_t dhcpack[0]; +}; + +struct multiboot_tag_efi_mmap +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t descr_size; + multiboot_uint32_t descr_vers; + multiboot_uint8_t efi_mmap[0]; +}; + +struct multiboot_tag_efi32_ih +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t pointer; +}; + +struct multiboot_tag_efi64_ih +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint64_t pointer; +}; + +struct multiboot_tag_load_base_addr +{ + multiboot_uint32_t type; + multiboot_uint32_t size; + multiboot_uint32_t load_base_addr; +}; + +#endif /* ! ASM_FILE */ + +#endif /* ! MULTIBOOT_HEADER */ diff --git a/src/headers/registrar.h b/src/headers/registrar.h new file mode 100644 index 0000000..bdd4f5a --- /dev/null +++ b/src/headers/registrar.h @@ -0,0 +1,6 @@ +#pragma once +#include "stddef.h" + +typedef void (*FU_kupdbuf_t)(char*, uint16_t); +extern void* FU_kupdbuf; +void FUINV_kupdbuf(char* buf, uint16_t count); diff --git a/src/headers/stddef.h b/src/headers/stddef.h new file mode 100644 index 0000000..d28fa48 --- /dev/null +++ b/src/headers/stddef.h @@ -0,0 +1,9 @@ +#define uint8_t unsigned char +#define uint16_t unsigned short +#define uint32_t unsigned int + +#define int8_t signed char +#define int16_t signed short +#define int32_t signed int + +#define size_t uint32_t \ No newline at end of file diff --git a/src/headers/stdlib.h b/src/headers/stdlib.h new file mode 100644 index 0000000..e69de29 diff --git a/src/kernel/entry.c b/src/kernel/entry.c new file mode 100644 index 0000000..d6ceff6 --- /dev/null +++ b/src/kernel/entry.c @@ -0,0 +1,81 @@ +#include "../headers/stddef.h" +#include "../headers/multiboot2.h" +#include "../headers/registrar.h" + +void basevga_writestdout(char* buf, uint16_t count) { + volatile char *video = (volatile char*)0xB8000; + volatile uint8_t VGA_MAX_ROWS = 25; + volatile uint8_t VGA_MAX_COLS = 80; + uint32_t offset = 0; + uint32_t offsets[VGA_MAX_ROWS]; + for (uint8_t i=0;i count*2%(VGA_MAX_COLS*VGA_MAX_ROWS)) { + offset += (count*2%(VGA_MAX_COLS*VGA_MAX_ROWS))-offsets[i]; + break; + } + } + continue; + } + video[count*2%(VGA_MAX_COLS*VGA_MAX_ROWS)+offset] = buf[i]; + video[count*2%(VGA_MAX_COLS*VGA_MAX_ROWS)+1+offset] = 15; + } +} +struct multiboot_info { + uint32_t total_size; + uint32_t reserved; + struct multiboot_tag tags[0]; +}; +uint32_t findtag(uint32_t type, struct multiboot_info* info) { + uint32_t index = 0; + while (1) { + struct multiboot_tag current = info->tags[index]; + + if (current.type == type) {return index;} + if (current.type == 0 && current.size == 8) {break;} + + index ++; + } + return 0; // failsafe +} + +// kernel stdout +void* FU_kupdbuf = basevga_writestdout; // register basevga_writestdout as kupdbuf function +char kstdout[8192] = {}; +uint16_t kstdout_count = 0; +void kputchar(char x) { + kstdout[kstdout_count++] = x; + FUINV_kupdbuf(kstdout, kstdout_count); +} +void kputstr(char* x) { + + while (*x != 0) { + kputchar(*x++); + } + kputchar('\n'); +} + +void kernel_main(struct multiboot_info* header, uint32_t magic) { + kputstr("Hello JPOS, World!"); + + if (magic != MULTIBOOT2_BOOTLOADER_MAGIC) { + kputstr("Invalid magic from bootloader."); + return; + } + + kputstr("Got past magic check."); + + // load drivers + + // find boot modules tag + struct multiboot_tag_module* bootmodules = (struct multiboot_tag_module*)&header->tags[findtag(3, header)]; + if (bootmodules->type != 3) {kputstr("Boot module failure.");return;} + //memcpy(0x200000, driver_code, size); + //((void(*)())0x200000)(); + +} \ No newline at end of file diff --git a/src/kernel/registrar.c b/src/kernel/registrar.c new file mode 100644 index 0000000..862da87 --- /dev/null +++ b/src/kernel/registrar.c @@ -0,0 +1,7 @@ +#include "../headers/registrar.h" + +void FUINV_kupdbuf(char* buf, uint16_t count) { + if (FU_kupdbuf != 0x00) { + ((FU_kupdbuf_t)FU_kupdbuf)(buf, count); + } +} \ No newline at end of file