From 81255d13ce78ebf600171c71ead0c325d518aac4 Mon Sep 17 00:00:00 2001 From: Tom-on64 Date: Mon, 30 Dec 2024 18:41:35 +0100 Subject: [PATCH] Did stuff... --- defaults.mk | 31 ++---- docs/coding-style.txt | 10 ++ kernel/entry.s | 108 ++++++++++++++++++ kernel/header.c | 15 --- kernel/{ => include}/stdint.h | 3 +- kernel/kernel.c | 200 +--------------------------------- kernel/linker.ld | 21 +++- kernel/makefile | 28 +++-- kernel/multiboot.h | 96 ---------------- makefile | 42 +------ 10 files changed, 166 insertions(+), 388 deletions(-) create mode 100644 kernel/entry.s delete mode 100644 kernel/header.c rename kernel/{ => include}/stdint.h (95%) delete mode 100644 kernel/multiboot.h diff --git a/defaults.mk b/defaults.mk index ef3385c..1416507 100644 --- a/defaults.mk +++ b/defaults.mk @@ -1,30 +1,17 @@ -# -# kern. makefile defaults -# - # Tools HOSTCC = cc CC = i686-elf-gcc LD = i686-elf-ld AS = nasm -MAKE = make +AR = i686-elf-ar +OBJCOPY = i686-elf-objcopy # Flags -CFLAGS = -Wall -Wextra -Wpedantic -Wno-pointer-arith\ - -ffreestanding -fno-stack-protector -fno-builtin -fno-pie -fcommon\ - -O2 -std=c17 -nostdinc -nostdlib -z notext -march=i386 -LDFLAGS = -melf_i386 -ASFLAGS = - -# Directories -KERNEL_DIR = ./kernel -BOOT_DIR = ./boot -LIBC_DIR = ./libc -USER_DIR = ./user - -# Modules -MODULES = $(KERNEL_DIR) \ - $(BOOT_DIR) \ - $(LIBC_DIR) \ - $(USER_DIR) +HOSTCFLAGS = -Wall -Wextra -Wpedantic -O2 -std=c17 -g +CFLAGS = -Wall -Wextra -Wpedantic -Wno-pointer-arith\ + -ffreestanding -fno-stack-protector -fno-builtin -fno-pie -fcommon\ + -O2 -std=c17 -nostdinc -nostdlib -z notext -march=i386 -g +LDFLAGS = -melf_i386 +ASFLAGS = +ARFLAGS = diff --git a/docs/coding-style.txt b/docs/coding-style.txt index ba50c45..e51e283 100644 --- a/docs/coding-style.txt +++ b/docs/coding-style.txt @@ -186,3 +186,13 @@ The prefered way of allocating memory for a struct is: Casting the returned void pointer is redundant since C converts void pointers to any other pointers. +Include Order +************* +The prefered way of ordering '#include' directives is as so: +* Include path includes (ones in <>) +* Local path includes (ones in "") +* Header implementation include, if you're implementing a header, include it last + +Directives should be ordered by lenght, descending. If two or more includes +have the same length, order alphabetically. + diff --git a/kernel/entry.s b/kernel/entry.s new file mode 100644 index 0000000..7dce2e2 --- /dev/null +++ b/kernel/entry.s @@ -0,0 +1,108 @@ +; +; Kernel entry point +; + +MBH_MAGIC equ 0xe85250d6 +MBH_ARCH equ 0x00000000 +STACK_SIZE equ 4096 +global VIRT_BASE +KERN_VIRT_BASE equ 0xC000000 +KERN_PAGE_NUM equ (KERN_VIRT_BASE >> 22) + +bits 32 + +; Multiboot2 Header +section .multiboot +align 64 +mbh: +; Magic fields +.magic: dd MBH_MAGIC +.arch: dd MBH_ARCH +.size: dd (mbh.end - mbh) +.checksum: dd 0x10000000 - (MBH_MAGIC + MBH_ARCH + (mbh.end - mbh)) + +; Framebuffer Tag +align 8 +dw 5 ; Type - Framebuffer +dw 1 ; Flags - Optional +dd 20 ; Size +dd 1920 ; Width +dd 1080 ; Height +dd 32 ; Depth + +; Zero Tag +align 8 +dw 0 ; Type - Zero +dw 0 ; Flags +dd 8 ; Size + +.end: + +; Stack +section .bss +align 16 +stack_bottom: + resb 16384*8 +stack_top: + +; Entry section +section .boot +global start + +extern kmain +start: + ; Init temporary paging + mov eax, (initpd - 0xC0000000) + mov cr3, eax + + mov ecx, cr4 + or ecx, 0x10 ; Paging enable bit + mov cr4, ecx + + mov ecx, cr0 + or ecx, 0x8000000 + mov cr0, ecx + + jmp higher_half + +Shutdown: + mov ax, 0x1000 + mov ss, ax + mov sp, 0xf000 + mov ax, 0x5307 + mov bx, 0x0001 + mov cx, 0x0003 + int 0x15 + +section .text +higher_half: + mov esp, stack_top ; Stack Pointer + + add ebx, KERN_VIRT_BASE ; Make address in EBX virtual + push ebx ; Push multiboot mem info pointer + + call kmain + +; Halt on return +cli +h: hlt + jmp h + +section .data + +; Inital Page Directory +align 4096 +global initpd +initpd: + dd 0b10000011 ; Initial 4MB identity map + + times 768-1 dd 0 ; Padding + + ; Higher half kernel start, map 16MB + dd (0 << 22) | 0b10000011 + dd (1 << 22) | 0b10000011 + dd (2 << 22) | 0b10000011 + dd (3 << 22) | 0b10000011 + + times 256-4 dd 0 ; More padding + diff --git a/kernel/header.c b/kernel/header.c deleted file mode 100644 index 97ebefe..0000000 --- a/kernel/header.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "multiboot.h" - -#define FLAGS (MBH_PAGE_ALIGN | MBH_GRAPH_INFO) - -__attribute__ ((section(".multiboot"))) -struct multiboot_header mbh = { - .magic = HEAD_MAGIC, - .flags = FLAGS, - .checksum = -(HEAD_MAGIC + FLAGS), - // We don't need the a.out format fields - .mode_type = 0, - .width = 1920, - .height = 1080, - .depth = 32, -}; diff --git a/kernel/stdint.h b/kernel/include/stdint.h similarity index 95% rename from kernel/stdint.h rename to kernel/include/stdint.h index c76ac94..cb6d964 100644 --- a/kernel/stdint.h +++ b/kernel/include/stdint.h @@ -3,7 +3,7 @@ #define NULL ((void*)0) -// Naitive width +// Naitive size typedef unsigned int size_t; typedef signed int ssize_t; @@ -19,5 +19,4 @@ typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long long uint64_t; - #endif diff --git a/kernel/kernel.c b/kernel/kernel.c index b8f2161..9b53f64 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -1,200 +1,4 @@ -#include "stdint.h" -#include "multiboot.h" +#include -/* Constants */ -#define COLS 80 -#define ROWS 24 -#define ATTR 0x0f -#define VID_MEM 0xb8000 - -/* Variables */ -static int xpos; -static int ypos; -static uint8_t* video; - -/* Forward Declarations */ -void cls(void); -void itoa(char* buf, int base, int d); -void putc(int c); -void printf(const char* fmt, ...); - -/* Entry Point */ -void kmain(void) { - uint32_t magic, addr; - __asm__ volatile ("movl %%eax, %0; movl %%ebx, %1" : "=m"(magic), "=m"(addr)); - struct multiboot_info* mbi; - video = (uint8_t*)VID_MEM; - - // Clear Screen - cls(); - - // Didn't boot with Multiboot - if (magic != BOOT_MAGIC) { - printf("Invalid Magic Number: 0x%x\n", magic); - while (1); - } - - mbi = (struct multiboot_info*)addr; - - printf("flags: 0x%x\n", mbi->flags); - - if (mbi->flags & MBI_MEMORY) { - printf("mem_lower: %ukB, mem_upper: %ukB\n", - mbi->mem_lower, mbi->mem_upper); - } - - if (mbi->flags & MBI_BOOT_DEV) { - printf("boot_device: 0x%x\n", mbi->boot_device); - } - - if (mbi->flags & MBI_CMDLINE) { - printf("cmdline: %s\n", mbi->cmdline); - } - - if (mbi->flags & MBI_MODS) { - printf("mods_count: %d, mods_addr: 0x%x\n", - mbi->mods_count, mbi->mods_addr); - - struct multiboot_module* mod = - (struct multiboot_module*)mbi->mods_addr; - - for (size_t i = 0; i < mbi->mods_count; i++) { - printf(" start 0x%x, end: 0x%x, cmdline: %s\n", - mod->start, mod->end, mod->cmdline); - mod++; - } - } - - if (mbi->flags & MBI_SYMBOLS && - mbi->flags & MBI_ELF_HEAD) { - printf("Flag SYMBOLS and ELF HEADER are both set!\n"); - while (1); - } - - if (mbi->flags & MBI_MEMMAP) { - printf("mmap_addr: 0x%x, mmap_length: 0x%x\n", - mbi->mmap_addr, mbi->mmap_length); - - struct multiboot_memmap* mmap = - (struct multiboot_memmap*)mbi->mmap_addr; - - while ((uint32_t)mmap < mbi->mmap_addr + mbi->mmap_length) { - printf( " size: 0x%x, base: 0x%08x, " - "length: 0x%08x, type: 0x%x\n", - mmap->size, mmap->base, mmap->len, mmap->type); - - mmap = (struct multiboot_memmap*) - ((uint32_t)mmap + mmap->size + (sizeof(mmap->size))); - } - } - - while (1); -} - -void cls(void) { - for (int i = 0; i < COLS * ROWS * 2; i++) video[i] = 0; - xpos = 0; - ypos = 0; -} - -void itoa(char* buf, int base, int d) { - char* p = buf; - char* p1; - char* p2; - uint32_t ud = d; - int divisor = 10; - - if (base == 'd' && d < 0) { - *p++ = '-'; - buf++; - ud = -d; - } else if (base == 'x') divisor = 16; - - do { - int remainder = ud % divisor; - *p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10; - } while (ud /= divisor); - - *p = 0; - - p1 = buf; - p2 = p - 1; - while (p1 < p2) { - char tmp = *p1; - *p1 = *p2; - *p2 = tmp; - p1++; - p2--; - } -} - -/* Put the character C on the screen. */ -void putc(int c) { - if (c == '\n' || c == '\r') { - newline: - xpos = 0; - ypos++; - if (ypos >= ROWS) - ypos = 0; - return; - } - - video[(xpos + ypos * COLS) * 2] = c & 0xFF; - video[(xpos + ypos * COLS) * 2 + 1] = ATTR; - - xpos++; - if (xpos >= COLS) - goto newline; -} - -void printf(const char *format, ...) { - char** arg = (char**)&format; - int c; - char buf[20]; - - arg++; - - while ((c = *format++) != 0) { - if (c != '%') { - putc (c); - continue; - } - - char *p, *p2; - int pad0 = 0, pad = 0; - - c = *format++; - - if (c == '0') { - pad0 = 1; - c = *format++; - } - - if (c >= '0' && c <= '9') { - pad = c - '0'; - c = *format++; - } - - switch (c) { - case 'd': - case 'u': - case 'x': - itoa(buf, c, *((int *) arg++)); - p = buf; - goto string; - break; - case 's': - p = *arg++; - if (! p) p = "(null)"; - string: - for (p2 = p; *p2; p2++); - for (; p2 < p + pad; p2++) putc (pad0 ? '0' : ' '); - while (*p) putc (*p++); - break; - default: - putc(*((int *) arg++)); - break; - } - } -} +void kmain(uint32_t addr) {} diff --git a/kernel/linker.ld b/kernel/linker.ld index b036efa..020c27f 100644 --- a/kernel/linker.ld +++ b/kernel/linker.ld @@ -1,34 +1,41 @@ OUTPUT_FORMAT(elf32-i386) -ENTRY(kmain) +ENTRY(start) SECTIONS { . = 0x00100000; + kernel_start = .; /* Multiboot Header */ - .multiboot ALIGN(4) : { + .multiboot ALIGN(4K) : { *(.multiboot) } + .boot ALIGN(4K) : { + *(.boot) + } + + . += 0xC000000; + /* Kernel Code */ - .text ALIGN(4) : { + .text ALIGN(4) : AT(ADDR(.text) - 0xC000000) { *(.text) *(.text.*) } /* Read-Only Data */ - .rodata ALIGN(4) : { + .rodata ALIGN(4) : AT(ADDR(.rodata) - 0xC000000) { *(.rodata) *(.rodata.*) } /* Read/Write Data */ - .data ALIGN(4) : { + .data ALIGN(4) : AT(ADDR(.data) - 0xC000000) { *(.data) *(.data.*) } /* BSS Section */ - .bss ALIGN(4) : { + .bss ALIGN(4) : AT(ADDR(.bss) - 0xC000000) { *(COMMON) *(.bss) *(.bss.*) @@ -40,4 +47,6 @@ SECTIONS { *(.note.*) *(.comment) } + + kernel_end = .; } diff --git a/kernel/makefile b/kernel/makefile index 298064b..b5f3a50 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -1,19 +1,29 @@ -include defaults.mk +include ../defaults.mk -SRCS = $(shell find $(SRC) -name '**.c') -OBJS = $(patsubst $(SRC)/%.c, $(BIN)/%.o, $(SRCS)) -LINKER = $(SRC)/linker.ld -OUT = $(BIN)/kernel.elf +INC = ./include +BIN = ./bin + +SRCS_C = $(shell find . -name '*.c') +SRCS_S = $(shell find . -name '*.s') +OBJS = $(patsubst %.c, $(BIN)/%.o, $(SRCS_C)) \ + $(patsubst %.s, $(BIN)/%.s.o, $(SRCS_S)) +LINKER = ./linker.ld +OUT = ./kernel.elf .PHONY: all clean all: $(OUT) $(OUT): $(OBJS) - $(LD) $(LDFLAGS) -T $(LINKER) -o $@ $^ + $(LD) $(LDFLAGS) -T$(LINKER) -o $@ $^ -$(BIN)/%.o: $(SRC)/%.c - $(CC) $(CFLAGS) -c -o $@ $< +$(BIN)/%.o: %.c + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) -I$(INC) -c -o $@ $< + +$(BIN)/%.s.o: %.s + @mkdir -p $(dir $@) + $(AS) $(ASFLAGS) -felf32 -o $@ $< clean: - rm -fr $(BIN) + rm -fr $(BIN) $(OUT) diff --git a/kernel/multiboot.h b/kernel/multiboot.h deleted file mode 100644 index e79a12b..0000000 --- a/kernel/multiboot.h +++ /dev/null @@ -1,96 +0,0 @@ -#ifndef _MULTIBOOT_H -#define _MULTIBOOT_H - -#include "stdint.h" - -#define __packed __attribute__ ((packed)) - -#define HEAD_MAGIC 0x1BADB002 -#define BOOT_MAGIC 0x2BADB002 - -// Multiboot Header Flags -enum { - MBH_PAGE_ALIGN = (1<<0), - MBH_MEMORY_INFO = (1<<1), - MBH_GRAPH_INFO = (1<<2), - MBH_ADDR_FIELDS = (1<<16), -}; - -struct multiboot_header { - uint32_t magic; - uint32_t flags; - uint32_t checksum; - uint32_t header_addr; - uint32_t load_addr; - uint32_t load_end_addr; - uint32_t bss_end_addr; - uint32_t entry_addr; - uint32_t mode_type; - uint32_t width; - uint32_t height; - uint32_t depth; -} __packed; - -// Multiboot Info Flags -enum { - MBI_MEMORY = (1<<0), - MBI_BOOT_DEV = (1<<1), - MBI_CMDLINE = (1<<2), - MBI_MODS = (1<<3), - MBI_SYMBOLS = (1<<4), - MBI_ELF_HEAD = (1<<5), - MBI_MEMMAP = (1<<6), - MBI_DRIVES = (1<<7), - MBI_CONF_TAB = (1<<8), - MBI_BOOTLD_NAME = (1<<9), - MBI_APM_TABLE = (1<<10), - MBI_VBE_TABLE = (1<<11), - MBI_FB_TABLE = (1<<12), -}; - -struct multiboot_info { - uint32_t flags; - uint32_t mem_lower; - uint32_t mem_upper; - uint32_t boot_device; - uint32_t cmdline; - uint32_t mods_count; - uint32_t mods_addr; - uint32_t syms[4]; - uint32_t mmap_length; - uint32_t mmap_addr; - uint32_t drives_length; - uint32_t drives_addr; - uint32_t config_table; - uint32_t bootloader_name; - uint32_t apm_table; - uint32_t vbe_control_info; - uint32_t vbe_mode_info; - uint32_t vbe_mode; - uint32_t vbe_interface_seg; - uint32_t vbe_interface_off; - uint32_t vbe_interface_len; - uint32_t framebuffer_addr; - uint32_t framebuffer_pitch; - uint32_t framebuffer_width; - uint32_t framebuffer_height; - uint32_t framebuffer_bpp; - uint32_t framebuffer_type; - uint32_t color_info; -} __packed; - -struct multiboot_module { - uint32_t start; - uint32_t end; - uint32_t cmdline; - uint32_t __reserved; -} __packed; - -struct multiboot_memmap { - uint32_t size; - uint64_t base; - uint64_t len; - uint32_t type; -} __packed; - -#endif diff --git a/makefile b/makefile index 88492b1..b07698a 100644 --- a/makefile +++ b/makefile @@ -1,40 +1,2 @@ -# -# Root kern. makefile -# (c) 2023-2025 Tomas Kubecek -# - -export VERSION = 0.3.0 - -# Configurable variables -include defaults.mk - -BIN = ./bin -IMG = ./kern.img - -.PHONY: all clean qemu msg $(MODULES) - -all: msg $(IMG) -$(IMG): $(MODULES) - @echo "\nDone!\n" - -# Build each module -$(MODULES): - mkdir -p $(BIN)/$@ - $(MAKE) BIN=$(BIN)/$@ SRC=$@ -f $@/makefile all - -clean: - for m in $(MODULES); do $(MAKE) BIN=$(BIN)/$$m SRC=$$m -C . -f $$m/makefile clean; done - rm -fr $(BIN) - rm -fr $(IMG) - -msg: - @echo "\x1b[36mBuilding \x1b[1mkern.\x1b[22m V$(VERSION)\x1b[0m\n" - -# Core Audio only works on MacOS -qemu: - qemu-system-x86_64\ - -drive format=raw,file=$(IMG),index=0,media=disk\ - -m 256M -accel tcg -monitor stdio\ - -rtc base=localtime,clock=host,driftfix=slew\ - -audiodev coreaudio,id=audio0 -machine pcspk-audiodev=audio0 - +all: + @echo TODO