diff --git a/Makefile b/Makefile index 3e8a13a..1d7164b 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ ASM ?= nasm -CC := i686-elf-gcc -GDB := i686-elf-gdb -LD := i686-elf-ld +CC := x86_64-elf-gcc +GDB := gdb +LD := x86_64-elf-ld C_FILES = $(shell find src/ -type f -name '*.c') CO_FILES = $(patsubst src/%.c, obj/%.o, $(C_FILES)) @@ -10,15 +10,15 @@ AO_FILES = $(patsubst src/kernel/%.asm, obj/kernel/%.o, $(ASM_FILES)) KERNEL_O_FILES = ${CO_FILES} ${AO_FILES} +BOOT_O_FILES = obj/entry.o obj/entry64.o obj/mb2.o obj/vga-print.o +BOOT_SRC_FILES = obj/entry.asm obj/entry64.asm obj/mb2.asm obj/vga-print.asm + iso: bin/shade.iso -obj/boot.o: src/boot.asm - $(ASM) -felf32 $^ -o $@ - -bin/shade.bin: obj/boot.o ${KERNEL_O_FILES} +bin/shade.bin: ${BOOT_O_FILES} ${KERNEL_O_FILES} mkdir -p bin - $(CC) -T src/linker.ld -ffreestanding -O2 -nostdlib $^ -o $@ -lgcc - grub-file --is-x86-multiboot bin/shade.bin + $(LD) -T src/linker.ld $^ -o $@ + grub-file --is-x86-multiboot2 bin/shade.bin bin/shade.iso: bin/shade.bin mkdir -p isodir/boot/grub @@ -33,7 +33,7 @@ obj/%.o: src/%.c obj/%.o: src/%.asm mkdir -p "$(@D)" - $(ASM) -f elf $< -o $@ + $(ASM) -f elf64 $< -o $@ run: clean bin/shade.iso diff --git a/bin/shade.bin b/bin/shade.bin index bc273eb..8b749db 100755 Binary files a/bin/shade.bin and b/bin/shade.bin differ diff --git a/bin/shade.iso b/bin/shade.iso index f81d3d4..a3e044b 100644 Binary files a/bin/shade.iso and b/bin/shade.iso differ diff --git a/obj/boot.o b/obj/boot.o deleted file mode 100644 index b5ff9cd..0000000 Binary files a/obj/boot.o and /dev/null differ diff --git a/obj/kernel/kernel.o b/obj/kernel/kernel.o index 4c95461..3f1f673 100644 Binary files a/obj/kernel/kernel.o and b/obj/kernel/kernel.o differ diff --git a/obj/kernel/platform/drivers/ports.o b/obj/kernel/platform/drivers/ports.o deleted file mode 100644 index a5820f9..0000000 Binary files a/obj/kernel/platform/drivers/ports.o and /dev/null differ diff --git a/obj/kernel/platform/interrupts/int.o b/obj/kernel/platform/interrupts/int.o deleted file mode 100644 index 0a99241..0000000 Binary files a/obj/kernel/platform/interrupts/int.o and /dev/null differ diff --git a/obj/kernel/platform/interrupts/int_lowlevel.o b/obj/kernel/platform/interrupts/int_lowlevel.o deleted file mode 100644 index 98f9819..0000000 Binary files a/obj/kernel/platform/interrupts/int_lowlevel.o and /dev/null differ diff --git a/obj/kernel/print.o b/obj/kernel/print.o index 30f77e5..91008f8 100644 Binary files a/obj/kernel/print.o and b/obj/kernel/print.o differ diff --git a/obj/kernel/strings.o b/obj/kernel/strings.o index b0718e1..07d9acf 100644 Binary files a/obj/kernel/strings.o and b/obj/kernel/strings.o differ diff --git a/obj/kernel/util.o b/obj/kernel/util.o index ddd8515..7cc7d31 100644 Binary files a/obj/kernel/util.o and b/obj/kernel/util.o differ diff --git a/src/boot.asm b/src/boot.asm deleted file mode 100644 index c4eac95..0000000 --- a/src/boot.asm +++ /dev/null @@ -1,52 +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 - -section .multiboot -align 4 - dd MAGIC - dd FLAGS - dd CHECKSUM - -section .bss -align 16 - -stack_bottom: -resb 16384 -stack_top: - -%include "src/gdt.asm" - -; _start = entry to kernel -; Since the bootloader will be gone, it doesn't make sense to return from this -section .text - -global _start:function (_start.end - _start) -_start: - ; 32bit protected mode, no int, no paging - mov esp, stack_top ; Initialize stack - - cli ; Disable interrupts - lgdt [gdt_descriptor] ; load the GDT - jmp CODE_SEG:.reload_seg ; far jump into a different segment - -.reload_seg: ; now in 32bit - mov ax, DATA_SEG ; update segment registers - mov ds, ax - mov ss, ax - mov es, ax - mov fs, ax - mov gs, ax - - extern kmain - call kmain - - cli ; Turn off interrupts in case they are on -.hang: - hlt ; Totally halt the cpu - jmp .hang ; If the cpu un-halts for some reason, halt again - -.end: \ No newline at end of file diff --git a/src/gdt.asm b/src/gdt.asm deleted file mode 100644 index 94a1299..0000000 --- a/src/gdt.asm +++ /dev/null @@ -1,33 +0,0 @@ -section .data - -gdt_start: ; use labels to compute sizes and jumps - ; gdt starts with 8 byte null - dd 0x0 - dd 0x0 - -; GDT for code segment, base = 0x00000000, length = 0xfffff -gdt_code: - dw 0xffff ; segment length - dw 0x0 ; segment base - db 0x0 ; segment base - db 10011010b ; flags - db 11001111b ; flags + segment length - db 0x0 ; segment base - -; GDT for data segment -gdt_data: - dw 0xffff ; segment length - dw 0x0 ; segment base - db 0x0 ; segment base - db 10010010b ; flags - db 11001111b ; flags + segment length - db 0x0 ; segment base - -gdt_end: - -gdt_descriptor: - dw gdt_end - gdt_start - 1 ; size, always 1 less than what it actually is - dd gdt_start ; address - -CODE_SEG equ gdt_code - gdt_start -DATA_SEG equ gdt_data - gdt_start \ No newline at end of file diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 3002fb1..dbb52be 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -1,6 +1,5 @@ -#include "./platform/drivers/ports.h" +#include "./platform/ports.h" #include "print.h" -#include "./platform/interrupts/int.h" void dummy_test_entrypoint() {} @@ -45,10 +44,4 @@ void kmain() { print_str("Copyright (c) e3team 2022. All rights reserved.\n"); print_str("This program is provided \"as-is\" and no express or implied warranty is provided.\n"); print_str("The full license can be found at /sys/LICENCE on this system or ./LICENCE in the source tree.\n"); - - idt_init(); - - __asm__ __volatile__("int $2"); - - //kernel_msg_ok("Interrupts working"); } \ No newline at end of file diff --git a/src/kernel/platform/drivers/ports.c b/src/kernel/platform/drivers/ports.c deleted file mode 100644 index 34a48db..0000000 --- a/src/kernel/platform/drivers/ports.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Read 1 byte from specified port - */ -unsigned char port_byte_in(unsigned short port) { - unsigned char result; - // source and dest are backwards. - // "=a (result)" set the C variable to the value of register e'a'x - // '"d" (port) map the C variable port into e'd'x register - __asm__("in %%dx, %%al" : "=a" (result) : "d" (port)); -} - -void port_byte_out(unsigned short port, unsigned char data) { - // both regs are C vars, nothing is returned, so no '=' in asm syntax - // comma because two vars in input area and none in return area - __asm__("out %%al, %%dx" : : "a" (data), "d" (port)); -} - -unsigned short port_word_in(unsigned short port) { - unsigned short result; - __asm__("in %%dx, %%ax" : "=a" (result) : "d" (port)); - return result; -} - -void port_word_out(unsigned short port, unsigned short data) { - __asm__("out %%ax, %%dx" : : "a" (data), "d" (port)); -} \ No newline at end of file diff --git a/src/kernel/platform/drivers/ports.h b/src/kernel/platform/drivers/ports.h deleted file mode 100644 index d616f0e..0000000 --- a/src/kernel/platform/drivers/ports.h +++ /dev/null @@ -1,4 +0,0 @@ -unsigned char port_byte_in(unsigned short port); -void port_byte_out(unsigned short port, unsigned char data); -unsigned short port_word_in(unsigned short port); -void port_word_out(unsigned short port, unsigned short data); \ No newline at end of file diff --git a/src/kernel/platform/interrupts/int.c b/src/kernel/platform/interrupts/int.c deleted file mode 100644 index 7474267..0000000 --- a/src/kernel/platform/interrupts/int.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "int.h" -#include "../../print.h" - -#include -#include -#include - -int count = 0; - -void exception_handler() { - print_str("I"); -} - -void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags) { - idt_entry_t* descriptor = &idt[vector]; - - descriptor->isr_low = (uint32_t)isr & 0xFFFF; - descriptor->kernel_cs = 0x08; // this value can be whatever offset your kernel code selector is in your GDT - descriptor->attributes = flags; - descriptor->isr_high = (uint32_t)isr >> 16; - descriptor->reserved = 0; -} - -void idt_init() { - idtr.base = (uint32_t)&idt[0]; - idtr.limit = (uint16_t)sizeof(idt_entry_t) * 256 - 1; - - for (uint8_t vector = 0; vector < 32; vector++) { - idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); - isr_stub_table[vector] = true; - } - - __asm__ volatile ("lidt %0" : : "m"(idtr)); // load the new IDT - __asm__ volatile ("sti"); // set the interrupt flag -} \ No newline at end of file diff --git a/src/kernel/platform/interrupts/int.h b/src/kernel/platform/interrupts/int.h deleted file mode 100644 index f2a0d01..0000000 --- a/src/kernel/platform/interrupts/int.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef INT_H -#define INT_H - -#include "../../util.h" -#include -#include -#include - -typedef struct { - uint16_t isr_low; // The lower 16 bits of the ISR's address - uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR - uint8_t reserved; // Set to zero - uint8_t attributes; // Type and attributes; see the IDT page - uint16_t isr_high; // The higher 16 bits of the ISR's address -} __attribute__((packed)) idt_entry_t; - -__attribute__((aligned(0x10))) -static idt_entry_t idt[256]; // Create an array of IDT entries; aligned for performance - -typedef struct { - uint16_t limit; - uint32_t base; -} __attribute__((packed)) idtr_t; - -static idtr_t idtr; - -typedef struct { - uint32_t ds; /* Data segment selector */ - uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; /* Pushed by pusha. */ - uint32_t int_no, err_code; /* Interrupt number and error code (if applicable) */ - uint32_t eip, cs, eflags, useresp, ss; /* Pushed by the processor automatically */ -} registers_t; - -__attribute__((noreturn)) -void exception_handler(); - -void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags); - -extern void* isr_stub_table[]; - -void idt_init(void); - -#endif \ No newline at end of file diff --git a/src/kernel/platform/interrupts/int_lowlevel.asm b/src/kernel/platform/interrupts/int_lowlevel.asm deleted file mode 100644 index a030f48..0000000 --- a/src/kernel/platform/interrupts/int_lowlevel.asm +++ /dev/null @@ -1,101 +0,0 @@ -%macro isr_err_stub 1 -isr_stub_%+%1: - ;push byte %1 ; Push interrupt no to stack - - ; 1. Save CPU state - ;pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax - ;mov ax, ds ; Lower 16-bits of eax = ds. - ;push eax ; save the data segment descriptor - ;mov ax, 0x10 ; kernel data segment descriptor - ;mov ds, ax - ;mov es, ax - ;mov fs, ax - ;mov gs, ax - - ; 2. Call C handler - call exception_handler - - ; 3. Restore state - ;pop eax - ;mov ds, ax - ;mov es, ax - ;mov fs, ax - ;mov gs, ax - ;popa - ;add esp, 8 ; Cleans up the pushed error code and pushed ISR number - iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP -%endmacro -; if writing for 64-bit, use iretq instead -%macro isr_no_err_stub 1 -isr_stub_%+%1: - ;push byte 0 ; No error occured - ;push byte %1 ; Push interrupt no to stack - - ; 1. Save CPU state - ;pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax - ;mov ax, ds ; Lower 16-bits of eax = ds. - ;push eax ; save the data segment descriptor - ;mov ax, 0x10 ; kernel data segment descriptor - ;mov ds, ax - ;mov es, ax - ;mov fs, ax - ;mov gs, ax - - ; 2. Call C handler - call exception_handler - - ; 3. Restore state - ;pop eax - ;mov ds, ax - ;mov es, ax - ;mov fs, ax - ;mov gs, ax - ;popa - ;add esp, 8 ; Cleans up the pushed error code and pushed ISR number - ;sti - iret ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP -%endmacro - -extern exception_handler - -isr_no_err_stub 0 -isr_no_err_stub 1 -isr_no_err_stub 2 -isr_no_err_stub 3 -isr_no_err_stub 4 -isr_no_err_stub 5 -isr_no_err_stub 6 -isr_no_err_stub 7 -isr_err_stub 8 -isr_no_err_stub 9 -isr_err_stub 10 -isr_err_stub 11 -isr_err_stub 12 -isr_err_stub 13 -isr_err_stub 14 -isr_no_err_stub 15 -isr_no_err_stub 16 -isr_err_stub 17 -isr_no_err_stub 18 -isr_no_err_stub 19 -isr_no_err_stub 20 -isr_no_err_stub 21 -isr_no_err_stub 22 -isr_no_err_stub 23 -isr_no_err_stub 24 -isr_no_err_stub 25 -isr_no_err_stub 26 -isr_no_err_stub 27 -isr_no_err_stub 28 -isr_no_err_stub 29 -isr_err_stub 30 -isr_no_err_stub 31 - -global isr_stub_table -isr_stub_table: -%assign i 0 -%rep 32 - dd isr_stub_%+i ; use DQ instead if targeting 64-bit -%assign i i+1 -%endrep - diff --git a/src/kernel/print.c b/src/kernel/print.c index 014de03..85bde11 100644 --- a/src/kernel/print.c +++ b/src/kernel/print.c @@ -1,5 +1,5 @@ #include "print.h" -#include "./platform/drivers/ports.h" +#include "./platform/ports.h" int row = 0; int col = 0; @@ -87,10 +87,10 @@ void print_set_color(char foreground, char background) { void set_cursor_pos(int col, int row) { int offset = col + NUM_COLS * row; - port_byte_out(REG_SCREEN_CTRL, 14); - port_byte_out(REG_SCREEN_DATA, (unsigned char)(offset >> 8)); - port_byte_out(REG_SCREEN_CTRL, 15); - port_byte_out(REG_SCREEN_DATA, (unsigned char)(offset & 0xff)); + outb(REG_SCREEN_CTRL, 14); + outb(REG_SCREEN_DATA, (unsigned char)(offset >> 8)); + outb(REG_SCREEN_CTRL, 15); + outb(REG_SCREEN_DATA, (unsigned char)(offset & 0xff)); } void kernel_msg_ok(char* msg) { diff --git a/src/linker.ld b/src/linker.ld index dfc6a97..f5b8dcd 100644 --- a/src/linker.ld +++ b/src/linker.ld @@ -1,32 +1,23 @@ -ENTRY(_start) + +ENTRY(entry_x86) SECTIONS { - . = 1M; + . = 1M; - /* MB header */ - .text BLOCK(4K) : ALIGN(4K) + .boot : + { + KEEP(*(.mb2_header)) + } + + .text : { - *(.multiboot) *(.text) } - /* Read-only data. */ - .rodata BLOCK(4K) : ALIGN(4K) + .idt BLOCK(0x1000) : ALIGN(0x1000) { - *(.rodata) - } - - /* Read-write data (initialized) */ - .data BLOCK(4K) : ALIGN(4K) - { - *(.data) - } - - /* Read-write data (uninitialized) and stack */ - .bss BLOCK(4K) : ALIGN(4K) - { - *(COMMON) - *(.bss) + _idt = .; + . = . + 0x1000; } } \ No newline at end of file