diff options
-rw-r--r-- | Makefile | 20 | ||||
-rw-r--r-- | src/kernel/arch/amd64/32/32 (renamed from src/kernel/arch/i386/gdt/gdt.c) | 2 | ||||
-rw-r--r-- | src/kernel/arch/amd64/32/boot.s | 86 | ||||
-rw-r--r-- | src/kernel/arch/amd64/32/farjump.s (renamed from src/kernel/arch/i386/gdt/farjump.s) | 0 | ||||
-rw-r--r-- | src/kernel/arch/amd64/32/gdt.c | 118 | ||||
-rw-r--r-- | src/kernel/arch/amd64/32/gdt.h (renamed from src/kernel/arch/i386/gdt.h) | 1 | ||||
-rw-r--r-- | src/kernel/arch/amd64/32/paging.c | 131 | ||||
-rw-r--r-- | src/kernel/arch/amd64/ata.c (renamed from src/kernel/arch/i386/ata.c) | 4 | ||||
-rw-r--r-- | src/kernel/arch/amd64/ata.h (renamed from src/kernel/arch/i386/ata.h) | 0 | ||||
-rw-r--r-- | src/kernel/arch/amd64/boot.c (renamed from src/kernel/arch/i386/boot.c) | 26 | ||||
-rw-r--r-- | src/kernel/arch/amd64/boot.h (renamed from src/kernel/arch/i386/boot.h) | 2 | ||||
-rw-r--r-- | src/kernel/arch/amd64/boot64.s | 13 | ||||
-rw-r--r-- | src/kernel/arch/amd64/debug.c (renamed from src/kernel/arch/i386/debug.c) | 12 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/fsroot.c (renamed from src/kernel/arch/i386/driver/fsroot.c) | 4 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/fsroot.h (renamed from src/kernel/arch/i386/driver/fsroot.h) | 0 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/ps2.c (renamed from src/kernel/arch/i386/driver/ps2.c) | 4 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/ps2.h (renamed from src/kernel/arch/i386/driver/ps2.h) | 0 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/serial.c (renamed from src/kernel/arch/i386/driver/serial.c) | 6 | ||||
-rw-r--r-- | src/kernel/arch/amd64/driver/serial.h (renamed from src/kernel/arch/i386/driver/serial.h) | 0 | ||||
-rw-r--r-- | src/kernel/arch/amd64/interrupts/idt.c (renamed from src/kernel/arch/i386/interrupts/idt.c) | 45 | ||||
-rw-r--r-- | src/kernel/arch/amd64/interrupts/idt.h (renamed from src/kernel/arch/i386/interrupts/idt.h) | 0 | ||||
-rw-r--r-- | src/kernel/arch/amd64/interrupts/irq.c (renamed from src/kernel/arch/i386/interrupts/irq.c) | 4 | ||||
-rw-r--r-- | src/kernel/arch/amd64/interrupts/irq.h (renamed from src/kernel/arch/i386/interrupts/irq.h) | 0 | ||||
-rw-r--r-- | src/kernel/arch/amd64/interrupts/isr.c (renamed from src/kernel/arch/i386/interrupts/isr.c) | 22 | ||||
-rw-r--r-- | src/kernel/arch/amd64/interrupts/isr.h (renamed from src/kernel/arch/i386/interrupts/isr.h) | 3 | ||||
-rw-r--r-- | src/kernel/arch/amd64/interrupts/isr_stub.s | 81 | ||||
-rw-r--r-- | src/kernel/arch/amd64/multiboot.h (renamed from src/kernel/arch/i386/multiboot.h) | 17 | ||||
-rw-r--r-- | src/kernel/arch/amd64/multiboot.s (renamed from src/kernel/arch/i386/multiboot.s) | 0 | ||||
-rw-r--r-- | src/kernel/arch/amd64/pagedir.c (renamed from src/kernel/arch/i386/pagedir.c) | 9 | ||||
-rw-r--r-- | src/kernel/arch/amd64/port_io.h (renamed from src/kernel/arch/i386/port_io.h) | 0 | ||||
-rw-r--r-- | src/kernel/arch/amd64/registers.h (renamed from src/kernel/arch/i386/registers.h) | 9 | ||||
-rw-r--r-- | src/kernel/arch/amd64/sysenter.c (renamed from src/kernel/arch/i386/sysenter.c) | 3 | ||||
-rw-r--r-- | src/kernel/arch/amd64/sysenter.h (renamed from src/kernel/arch/i386/sysenter.h) | 0 | ||||
-rw-r--r-- | src/kernel/arch/amd64/sysenter.s (renamed from src/kernel/arch/i386/sysenter.s) | 78 | ||||
-rw-r--r-- | src/kernel/arch/amd64/tty/tty.c (renamed from src/kernel/arch/i386/tty/tty.c) | 4 | ||||
-rw-r--r-- | src/kernel/arch/amd64/tty/tty.h (renamed from src/kernel/arch/i386/tty/tty.h) | 0 | ||||
-rw-r--r-- | src/kernel/arch/amd64/tty/vga.c (renamed from src/kernel/arch/i386/tty/vga.c) | 2 | ||||
-rw-r--r-- | src/kernel/arch/generic.h | 4 | ||||
-rw-r--r-- | src/kernel/arch/i386/boot.s | 34 | ||||
-rw-r--r-- | src/kernel/arch/i386/interrupts/isr_stub.s | 64 | ||||
-rw-r--r-- | src/kernel/panic.h | 2 | ||||
-rw-r--r-- | src/kernel/proc.c | 1 | ||||
-rw-r--r-- | src/kernel/vfs/request.c | 2 | ||||
-rw-r--r-- | src/shared/printf.c | 4 | ||||
-rw-r--r-- | src/user/lib/syscall.s | 31 | ||||
-rwxr-xr-x | tools/dep_builders/binutils | 2 | ||||
-rwxr-xr-x | tools/dep_builders/gcc | 10 |
47 files changed, 609 insertions, 251 deletions
@@ -1,13 +1,13 @@ PATH := $(shell pwd)/toolchain/bin/:$(PATH) -AS = i686-elf-as -CC = i686-elf-gcc +AS = x86_64-elf-as +CC = x86_64-elf-gcc CHECK = sparse CFLAGS += -g -std=gnu99 -ffreestanding -O2 -Wall -Wextra -Wold-style-definition -Werror=implicit-function-declaration -ftrack-macro-expansion=0 CFLAGS += -mgeneral-regs-only CFLAGS += -Isrc/ SPARSEFLAGS = -Wno-non-pointer-null -LFLAGS = -ffreestanding -O2 -nostdlib -lgcc +LFLAGS = -ffreestanding -O2 -nostdlib -lgcc -Wl,-zmax-page-size=4096 -Wl,--no-warn-mismatch QFLAGS = -no-reboot ifndef QEMU_DISPLAY QFLAGS += -display none @@ -23,12 +23,12 @@ endef all: out/boot.iso check boot: all out/hdd - qemu-system-i386 -drive file=out/boot.iso,format=raw,media=disk $(QFLAGS) -serial stdio + qemu-system-x86_64 -drive file=out/boot.iso,format=raw,media=disk $(QFLAGS) -serial stdio test: all @# pipes for the serial @mkfifo out/qemu.in out/qemu.out 2> /dev/null || true - qemu-system-i386 -drive file=out/boot.iso,format=raw,media=disk $(QFLAGS) -serial pipe:out/qemu & + qemu-system-x86_64 -drive file=out/boot.iso,format=raw,media=disk $(QFLAGS) -serial pipe:out/qemu & @# for some reason the first sent character doesn't go through to the shell @# the empty echo takes care of that, so the next echos will work just fine @echo > out/qemu.in @@ -38,7 +38,7 @@ test: all @cat out/qemu.out debug: all - qemu-system-i386 -cdrom out/boot.iso $(QFLAGS) -serial stdio -s -S & + qemu-system-x86_64 -cdrom out/boot.iso $(QFLAGS) -serial stdio -s -S & @sleep 1 gdb @@ -87,5 +87,13 @@ out/obj/%.c.o: src/%.c @mkdir -p $(@D) @$(CC) $(CFLAGS) -c $^ -o $@ +out/obj/kernel/arch/amd64/32/%.c.o: src/kernel/arch/amd64/32/%.c + @mkdir -p $(@D) + @$(CC) $(CFLAGS) -m32 -c $^ -o $@ + +out/obj/kernel/arch/amd64/32/%.s.o: src/kernel/arch/amd64/32/%.s + @mkdir -p $(@D) + @$(CC) -m32 -c $^ -o $@ + src/user/lib/syscall.c: src/user/lib/syscall.c.awk src/shared/syscalls.h awk -f $^ > $@ diff --git a/src/kernel/arch/i386/gdt/gdt.c b/src/kernel/arch/amd64/32/32 index 3521052..9bd97e6 100644 --- a/src/kernel/arch/i386/gdt/gdt.c +++ b/src/kernel/arch/amd64/32/32 @@ -1,5 +1,5 @@ #include <kernel/arch/generic.h> -#include <kernel/arch/i386/gdt.h> +#include <kernel/arch/amd64/gdt.h> #include <shared/mem.h> #include <stdbool.h> #include <stdint.h> diff --git a/src/kernel/arch/amd64/32/boot.s b/src/kernel/arch/amd64/32/boot.s new file mode 100644 index 0000000..eb33c28 --- /dev/null +++ b/src/kernel/arch/amd64/32/boot.s @@ -0,0 +1,86 @@ +.section .text +.global _start +.type _start, @function +_start: + mov $_stack_top, %esp + push %ebx // save the address of the multiboot struct + + mov $0x80000000, %eax // check CPUID extended functions + cpuid + cmp $0x80000001, %eax + jb panic_early + + mov $0x80000001, %eax + cpuid + test $(1<<29), %edx // check long mode support + jz panic_early + + mov %cr4, %eax + or $(1<<5), %eax // PAE + mov %eax, %cr4 + + call pml4_identity_init + mov $pml4_identity, %eax + mov %eax, %cr3 + + mov $0xC0000080, %ecx // EFER MSR + rdmsr + or $(1 | 1<<8 | 1<<11), %eax // sysenter | long mode | NX + wrmsr + + mov %cr0, %eax + or $0x80000000, %eax + mov %eax, %cr0 + + call gdt_init + lgdt (lgdt_arg) + + pop %edi + + // TODO import gdt.h for globals + mov $(2<<3), %eax + mov %eax, %ds // SEG_r0data + mov %eax, %ss + mov %eax, %es + mov %eax, %fs + mov %eax, %gs + + ljmp $(1<<3), $boot64 // SEG_r0code + +panic_early: + // output a vga Fuck + movl $0x4F754F46, 0xB872A + movl $0x4F6B4F63, 0xB872E + jmp cpu_halt + +// TODO not part of anything yet + call sysenter_setup + // TODO will fail + push %ebx // address of the Multiboot struct + call kmain_early + +.global cpu_shutdown +.type cpu_shutdown, @function +cpu_shutdown: +/* This quits QEMU. While I couldn't find this officially documented anywhere, + * it is used by QEMU in tests/tcg/i386/system/boot.S (as of commit 40d6ee), so + * I assume that this is safe-ish to use */ + mov $0x604, %edx + mov $0x2000, %eax + outw %ax, %dx + +.global cpu_halt +.type cpu_halt, @function +cpu_halt: + cli +1: hlt + jmp 1b + + +.global cpu_pause +.type cpu_pause, @function +cpu_pause: + sti + hlt + cli + ret diff --git a/src/kernel/arch/i386/gdt/farjump.s b/src/kernel/arch/amd64/32/farjump.s index 2885d2b..2885d2b 100644 --- a/src/kernel/arch/i386/gdt/farjump.s +++ b/src/kernel/arch/amd64/32/farjump.s diff --git a/src/kernel/arch/amd64/32/gdt.c b/src/kernel/arch/amd64/32/gdt.c new file mode 100644 index 0000000..2229330 --- /dev/null +++ b/src/kernel/arch/amd64/32/gdt.c @@ -0,0 +1,118 @@ +#include <kernel/arch/amd64/32/gdt.h> +#include <kernel/arch/generic.h> +#include <stdbool.h> +#include <stdint.h> + +extern char _isr_mini_stack; + +struct gdt_entry { + uint64_t limit_low : 16; + uint64_t base_low : 24; + uint64_t accessed : 1; // set by the processor + // CODE | DATA + uint64_t rw : 1; // readable? | writeable? + uint64_t conforming : 1; // conforming? | expands down? + uint64_t code : 1; // 1 | 0 + + uint64_t codeordata : 1; // 1 for everything other than TSS and LDT + uint64_t ring : 2; + uint64_t present : 1; // always 1 + uint64_t limit_high : 4; + uint64_t available : 1; // ??? + uint64_t long_mode : 1; + uint64_t x32 : 1; + uint64_t gran : 1; // 1 - 4kb, 0 - 1b + uint64_t base_high : 8; +} __attribute__((packed)); + +struct tss_entry { + uint32_t reserved0; + uint64_t rsp[3]; + uint64_t ist[8]; + uint64_t reserved2; + uint16_t reserved3; + uint16_t iopb; +} __attribute__((packed)); + +struct lgdt_arg { + uint16_t limit; + uint32_t base; +} __attribute__((packed)); + +__attribute__((section(".shared"))) +struct gdt_entry GDT[SEG_end]; +__attribute__((section(".shared"))) +struct tss_entry TSS; + +struct lgdt_arg lgdt_arg; + + +static void *memset32(void *s, int c, size_t n) { + uint8_t *s2 = s; + for (size_t i = 0; i < n; i++) + s2[i] = c; + return s; +} + + +static void gdt_fillout(struct gdt_entry* entry, uint8_t ring, bool code) { + *entry = (struct gdt_entry) { + // set up the identity mapping + .limit_low = 0xFFFF, + .limit_high = 0xF, + .gran = 1, + .base_low = 0, + .base_high = 0, + + .ring = ring, + .code = code, + + .accessed = 0, + .rw = 1, + .conforming = 0, + .codeordata = 1, + .present = 1, + .long_mode = 1, + .available = 1, + .x32 = 0, + }; +} + +void gdt_init(void) { + GDT[SEG_null].present = 0; + + gdt_fillout(&GDT[SEG_r0code], 0, true); + gdt_fillout(&GDT[SEG_r0data], 0, false); + gdt_fillout(&GDT[SEG_r3code], 3, true); + gdt_fillout(&GDT[SEG_r3data], 3, false); + + lgdt_arg.limit = sizeof(GDT) - 1; + lgdt_arg.base = (uint64_t) &GDT; + + + memset32(&TSS, 0, sizeof(TSS)); + for (int i = 0; i < 3; i++) + TSS.rsp[i] = (uint64_t) &_isr_mini_stack; + TSS.ist[1] = (uint64_t) &_isr_mini_stack; + + uint64_t tss_addr = (uint64_t) &TSS; + GDT[SEG_TSS] = (struct gdt_entry) { + .limit_low = sizeof(TSS), + .limit_high = sizeof(TSS) >> 16, + .gran = 0, + .base_low = tss_addr, + .base_high = tss_addr >> 24, + + .accessed = 1, + .rw = 0, + .conforming = 0, + .code = 1, + .codeordata = 0, + .ring = 0, // was 3 pre-port + .present = 1, + .available = 1, + .long_mode = 0, + .x32 = 0, + }; + *((uint64_t*)&GDT[SEG_TSS2]) = (tss_addr >> 32); +} diff --git a/src/kernel/arch/i386/gdt.h b/src/kernel/arch/amd64/32/gdt.h index 5e40cd7..fbaf681 100644 --- a/src/kernel/arch/i386/gdt.h +++ b/src/kernel/arch/amd64/32/gdt.h @@ -8,6 +8,7 @@ enum { SEG_r3code, SEG_r3data, SEG_TSS, + SEG_TSS2, SEG_end }; diff --git a/src/kernel/arch/amd64/32/paging.c b/src/kernel/arch/amd64/32/paging.c new file mode 100644 index 0000000..975dd98 --- /dev/null +++ b/src/kernel/arch/amd64/32/paging.c @@ -0,0 +1,131 @@ +#include <stddef.h> +#include <stdint.h> + +struct pml4e { + uint64_t present : 1; + uint64_t writeable : 1; + uint64_t user : 1; + uint64_t writethru : 1; + + uint64_t uncached : 1; + uint64_t accessed : 1; + uint64_t _unused1 : 1; + uint64_t reserved : 1; // always 0 + + uint64_t _unused2 : 3; + uint64_t _unused3 : 1; // HLAT thing + + uint64_t address : 40; + + uint64_t _unused4 : 11; + uint64_t noexec : 1; +} __attribute__((packed)); + +struct pdpte { // page directory pointer table entry, 1gb page | 512 * pde + uint64_t present : 1; + uint64_t writeable : 1; + uint64_t user : 1; + uint64_t writethru : 1; + + uint64_t uncached : 1; + uint64_t accessed : 1; + uint64_t _unused1 : 1; + uint64_t large : 1; // 1gb page + + uint64_t _unused2 : 3; + uint64_t _unused3 : 1; // HLAT + + uint64_t address : 40; + + uint64_t _unused4 : 11; + uint64_t noexec : 1; +} __attribute__((packed)); + +struct pde { // page directory entry, 2mb page | 512 * pte + uint64_t present : 1; + uint64_t writeable : 1; + uint64_t user : 1; + uint64_t writethru : 1; + + uint64_t uncached : 1; + uint64_t accessed : 1; + uint64_t dirty : 1; // only if large + uint64_t large : 1; // 2mb + + uint64_t global : 1; // only if large ; TODO enable CR4.PGE + uint64_t _unused2 : 2; + uint64_t _unused3 : 1; // HLAT + + uint64_t address : 40; // highest bit - PAT + + uint64_t _unused4 : 7; + uint64_t pke : 4; + uint64_t noexec : 1; +} __attribute__((packed)); + +struct pte { // page table entry, 4kb page + uint64_t present : 1; + uint64_t writeable : 1; + uint64_t user : 1; + uint64_t writethru : 1; + + uint64_t uncached : 1; + uint64_t accessed : 1; + uint64_t dirty : 1; + uint64_t pat : 1; + + uint64_t global : 1; // TODO enable CR4.PGE + uint64_t _unused2 : 2; + uint64_t _unused3 : 1; // HLAT + + uint64_t address : 40; + + uint64_t _unused4 : 7; + uint64_t pke : 4; + uint64_t noexec : 1; +} __attribute__((packed)); + +__attribute__((aligned(4096))) +struct pml4e pml4_identity[512]; + +__attribute__((aligned(4096))) +struct pdpte pdpte_low[512]; // 0-512gb + +__attribute__((aligned(4096))) +struct pde pde_low[512]; // 0-1gb + + +static void *memset32(void *s, int c, size_t n) { + uint8_t *s2 = s; + for (size_t i = 0; i < n; i++) + s2[i] = c; + return s; +} + + +void pml4_identity_init(void) { + memset32(pml4_identity, 0, sizeof pml4_identity); + memset32(pdpte_low, 0, sizeof pdpte_low); + memset32(pde_low, 0, sizeof pde_low); + + pml4_identity[0] = (struct pml4e) { + .present = 1, + .writeable = 1, + .address = ((uintptr_t)pdpte_low) >> 12, + }; + + pdpte_low[0] = (struct pdpte) { + .present = 1, + .writeable = 1, + .address = ((uintptr_t)pde_low) >> 12, + }; + + for (int i = 0; i < 512; i++) { + pde_low[i] = (struct pde) { + .present = 1, + .writeable = 1, + .large = 1, + .address = (i * 2 * 1024 * 1024) >> 12, + }; + } +} diff --git a/src/kernel/arch/i386/ata.c b/src/kernel/arch/amd64/ata.c index 56344e4..371730e 100644 --- a/src/kernel/arch/i386/ata.c +++ b/src/kernel/arch/amd64/ata.c @@ -1,5 +1,5 @@ -#include <kernel/arch/i386/ata.h> -#include <kernel/arch/i386/port_io.h> +#include <kernel/arch/amd64/ata.h> +#include <kernel/arch/amd64/port_io.h> #include <kernel/panic.h> #include <stdbool.h> diff --git a/src/kernel/arch/i386/ata.h b/src/kernel/arch/amd64/ata.h index 82f4f81..82f4f81 100644 --- a/src/kernel/arch/i386/ata.h +++ b/src/kernel/arch/amd64/ata.h diff --git a/src/kernel/arch/i386/boot.c b/src/kernel/arch/amd64/boot.c index 754a327..0e61ed3 100644 --- a/src/kernel/arch/i386/boot.c +++ b/src/kernel/arch/amd64/boot.c @@ -1,36 +1,34 @@ #include <kernel/arch/generic.h> -#include <kernel/arch/i386/ata.h> -#include <kernel/arch/i386/boot.h> -#include <kernel/arch/i386/driver/fsroot.h> -#include <kernel/arch/i386/driver/ps2.h> -#include <kernel/arch/i386/driver/serial.h> -#include <kernel/arch/i386/gdt.h> -#include <kernel/arch/i386/interrupts/idt.h> -#include <kernel/arch/i386/interrupts/irq.h> -#include <kernel/arch/i386/multiboot.h> -#include <kernel/arch/i386/tty/tty.h> +#include <kernel/arch/amd64/32/gdt.h> +#include <kernel/arch/amd64/ata.h> +#include <kernel/arch/amd64/boot.h> +#include <kernel/arch/amd64/driver/fsroot.h> +#include <kernel/arch/amd64/driver/ps2.h> +#include <kernel/arch/amd64/driver/serial.h> +#include <kernel/arch/amd64/interrupts/idt.h> +#include <kernel/arch/amd64/interrupts/irq.h> +#include <kernel/arch/amd64/multiboot.h> +#include <kernel/arch/amd64/tty/tty.h> #include <kernel/main.h> #include <kernel/mem/alloc.h> #include <kernel/panic.h> static void find_init(struct multiboot_info *multiboot, struct kmain_info *info) { - struct multiboot_mod *module = &multiboot->mods[0]; + struct multiboot_mod *module = (void*)multiboot->mods; + kprintf("mods count 0x%x", multiboot->mods_count); if (multiboot->mods_count < 1) { kprintf("can't find init! "); panic_invalid_state(); } info->init.at = module->start; info->init.size = module->end - module->start; - } void kmain_early(struct multiboot_info *multiboot) { struct kmain_info info; tty_init(); - kprintf("gdt..."); - gdt_init(); kprintf("idt..."); idt_init(); kprintf("irq..."); diff --git a/src/kernel/arch/i386/boot.h b/src/kernel/arch/amd64/boot.h index 544f02d..98adff5 100644 --- a/src/kernel/arch/i386/boot.h +++ b/src/kernel/arch/amd64/boot.h @@ -1,4 +1,4 @@ #pragma once -#include <kernel/arch/i386/multiboot.h> +#include <kernel/arch/amd64/multiboot.h> void kmain_early(struct multiboot_info *multiboot); diff --git a/src/kernel/arch/amd64/boot64.s b/src/kernel/arch/amd64/boot64.s new file mode 100644 index 0000000..1dca0ca --- /dev/null +++ b/src/kernel/arch/amd64/boot64.s @@ -0,0 +1,13 @@ +.global boot64 +boot64: + lgdt (lgdt_arg) // try reloading gdt again + mov $(5 << 3 | 3), %ax // SEG_TSS + ltr %ax + + xchgw %bx, %bx + push %rdi // preserve multiboot struct + call sysenter_setup + pop %rdi + + // multiboot struct in %rdi + jmp kmain_early diff --git a/src/kernel/arch/i386/debug.c b/src/kernel/arch/amd64/debug.c index b1920db..52127da 100644 --- a/src/kernel/arch/i386/debug.c +++ b/src/kernel/arch/amd64/debug.c @@ -1,14 +1,14 @@ #include <kernel/arch/generic.h> void *debug_caller(size_t depth) { - void **ebp; - asm("mov %%ebp, %0" - : "=r" (ebp)); + void **rbp; + asm("mov %%rbp, %0" + : "=r" (rbp)); while (depth--) { - if (!ebp) return NULL; - ebp = *ebp; + if (!rbp) return NULL; + rbp = *rbp; } - return ebp[1]; + return rbp[1]; } void debug_stacktrace(void) { diff --git a/src/kernel/arch/i386/driver/fsroot.c b/src/kernel/arch/amd64/driver/fsroot.c index 8b1b307..02a4a21 100644 --- a/src/kernel/arch/i386/driver/fsroot.c +++ b/src/kernel/arch/amd64/driver/fsroot.c @@ -1,9 +1,9 @@ -#include <kernel/arch/i386/ata.h> +#include <kernel/arch/amd64/ata.h> #include <kernel/mem/virt.h> #include <kernel/panic.h> #include <kernel/proc.h> #include <kernel/util.h> -#include <kernel/arch/i386/driver/fsroot.h> +#include <kernel/arch/amd64/driver/fsroot.h> #include <shared/mem.h> #include <stdbool.h> diff --git a/src/kernel/arch/i386/driver/fsroot.h b/src/kernel/arch/amd64/driver/fsroot.h index dd72202..dd72202 100644 --- a/src/kernel/arch/i386/driver/fsroot.h +++ b/src/kernel/arch/amd64/driver/fsroot.h diff --git a/src/kernel/arch/i386/driver/ps2.c b/src/kernel/arch/amd64/driver/ps2.c index 341a7d3..8a5a078 100644 --- a/src/kernel/arch/i386/driver/ps2.c +++ b/src/kernel/arch/amd64/driver/ps2.c @@ -1,5 +1,5 @@ -#include <kernel/arch/i386/driver/ps2.h> -#include <kernel/arch/i386/interrupts/irq.h> +#include <kernel/arch/amd64/driver/ps2.h> +#include <kernel/arch/amd64/interrupts/irq.h> #include <kernel/mem/virt.h> #include <kernel/panic.h> #include <kernel/vfs/request.h> diff --git a/src/kernel/arch/i386/driver/ps2.h b/src/kernel/arch/amd64/driver/ps2.h index 54e8fb2..54e8fb2 100644 --- a/src/kernel/arch/i386/driver/ps2.h +++ b/src/kernel/arch/amd64/driver/ps2.h diff --git a/src/kernel/arch/i386/driver/serial.c b/src/kernel/arch/amd64/driver/serial.c index dac5b75..6dda657 100644 --- a/src/kernel/arch/i386/driver/serial.c +++ b/src/kernel/arch/amd64/driver/serial.c @@ -1,6 +1,6 @@ -#include <kernel/arch/i386/driver/serial.h> -#include <kernel/arch/i386/interrupts/irq.h> -#include <kernel/arch/i386/port_io.h> +#include <kernel/arch/amd64/driver/serial.h> +#include <kernel/arch/amd64/interrupts/irq.h> +#include <kernel/arch/amd64/port_io.h> #include <kernel/mem/virt.h> #include <kernel/panic.h> #include <shared/container/ring.h> diff --git a/src/kernel/arch/i386/driver/serial.h b/src/kernel/arch/amd64/driver/serial.h index 6a4876e..6a4876e 100644 --- a/src/kernel/arch/i386/driver/serial.h +++ b/src/kernel/arch/amd64/driver/serial.h diff --git a/src/kernel/arch/i386/interrupts/idt.c b/src/kernel/arch/amd64/interrupts/idt.c index cd2adfd..9c71000 100644 --- a/src/kernel/arch/i386/interrupts/idt.c +++ b/src/kernel/arch/amd64/interrupts/idt.c @@ -1,26 +1,28 @@ -#include <kernel/arch/i386/gdt.h> -#include <kernel/arch/i386/interrupts/idt.h> -#include <kernel/arch/i386/interrupts/isr.h> +#include <kernel/arch/amd64/32/gdt.h> +#include <kernel/arch/amd64/interrupts/idt.h> +#include <kernel/arch/amd64/interrupts/isr.h> #include <kernel/panic.h> #include <stdbool.h> #include <stdint.h> struct idt_entry { - uint16_t offset_low ; - uint16_t code_seg ; - uint8_t zero ; // unused, has to be 0 - uint8_t type : 4; // 16/32 bit, task/interrupt/task gate - uint8_t storage : 1; // 0 for interrupt/trap gates - uint8_t ring : 2; - uint8_t present : 1; - uint16_t offset_high ; + uint16_t offset_low; + uint16_t seg; + uint8_t ist; + uint8_t type : 4; // 0xE - interrupt, 0xF - trap + uint8_t zero1 : 1; + uint8_t ring : 2; + uint8_t present : 1; + uint16_t offset_mid; + uint32_t offset_high; + uint32_t zero2; } __attribute__((packed)); // is exactly the same as lgdt_arg, i should combine them into a single struct // later struct lidt_arg { uint16_t limit; - uint32_t base; + uintptr_t base; } __attribute__((packed)); __attribute__((section(".shared"))) @@ -33,19 +35,17 @@ static void idt_test(void); static void idt_prepare(void) { - uintptr_t offset; for (int i = 0; i < 256; i++) { - offset = (uintptr_t) &_isr_stubs + i * 8; + uintptr_t offset = (uintptr_t) &_isr_stubs + i * 8; IDT[i] = (struct idt_entry) { .offset_low = offset, - .offset_high = offset >> 16, - .code_seg = SEG_r0code << 3, - .zero = 0, - .present = 1, - .ring = 0, - .storage = 0, - .type = 0xE, // 32-bit interrupt gate + .offset_mid = offset >> 16, + .offset_high = offset >> 32, + .seg = SEG_r0code << 3, + .present = 1, + .type = 0xE, + .ist = 1, }; } } @@ -57,8 +57,11 @@ static void idt_load(void) { } static void idt_test(void) { + kprintf("idt test?\n"); + asm("xchgw %%bx, %%bx" ::: "memory"); asm("int $0x34" : : : "memory"); assert(isr_test_interrupt_called); + kprintf("done.\n"); } void idt_init(void) { diff --git a/src/kernel/arch/i386/interrupts/idt.h b/src/kernel/arch/amd64/interrupts/idt.h index 6576cf9..6576cf9 100644 --- a/src/kernel/arch/i386/interrupts/idt.h +++ b/src/kernel/arch/amd64/interrupts/idt.h diff --git a/src/kernel/arch/i386/interrupts/irq.c b/src/kernel/arch/amd64/interrupts/irq.c index 5918169..74bc48c 100644 --- a/src/kernel/arch/i386/interrupts/irq.c +++ b/src/kernel/arch/amd64/interrupts/irq.c @@ -1,5 +1,5 @@ -#include <kernel/arch/i386/interrupts/irq.h> -#include <kernel/arch/i386/port_io.h> +#include <kernel/arch/amd64/interrupts/irq.h> +#include <kernel/arch/amd64/port_io.h> #include <stdint.h> static const int PIC1 = 0x20; diff --git a/src/kernel/arch/i386/interrupts/irq.h b/src/kernel/arch/amd64/interrupts/irq.h index f523154..f523154 100644 --- a/src/kernel/arch/i386/interrupts/irq.h +++ b/src/kernel/arch/amd64/interrupts/irq.h diff --git a/src/kernel/arch/i386/interrupts/isr.c b/src/kernel/arch/amd64/interrupts/isr.c index 2d893cb..b55bc8b 100644 --- a/src/kernel/arch/i386/interrupts/isr.c +++ b/src/kernel/arch/amd64/interrupts/isr.c @@ -1,8 +1,8 @@ -#include <kernel/arch/i386/driver/ps2.h> -#include <kernel/arch/i386/driver/serial.h> -#include <kernel/arch/i386/interrupts/irq.h> -#include <kernel/arch/i386/interrupts/isr.h> -#include <kernel/arch/i386/port_io.h> +#include <kernel/arch/amd64/driver/ps2.h> +#include <kernel/arch/amd64/driver/serial.h> +#include <kernel/arch/amd64/interrupts/irq.h> +#include <kernel/arch/amd64/interrupts/isr.h> +#include <kernel/arch/amd64/port_io.h> #include <kernel/arch/generic.h> #include <kernel/panic.h> #include <kernel/proc.h> @@ -11,12 +11,22 @@ bool isr_test_interrupt_called = false; -void isr_stage3(int interrupt) { +void isr_stage3(int interrupt, uint64_t *stackframe) { + if (interrupt == 0xe) stackframe++; + kprintf("interrupt %x, rip = k/%08x, cs 0x%x\n", interrupt, stackframe[0], stackframe[1]); switch (interrupt) { case 0x08: // double fault kprintf("#DF"); panic_invalid_state(); + + case 0xe: + uint64_t addr = 0x69; + asm("mov %%cr2, %0" : "=r"(addr)); + kprintf("error code 0x%x, addr 0x%x\n", stackframe[-1], addr); + panic_unimplemented(); + case 0x34: + asm("nop" ::: "memory"); isr_test_interrupt_called = true; return; diff --git a/src/kernel/arch/i386/interrupts/isr.h b/src/kernel/arch/amd64/interrupts/isr.h index 3189538..01f5236 100644 --- a/src/kernel/arch/i386/interrupts/isr.h +++ b/src/kernel/arch/amd64/interrupts/isr.h @@ -1,7 +1,8 @@ #pragma once #include <stdbool.h> +#include <stdint.h> extern bool isr_test_interrupt_called; // used in the self-test in idt.c extern const char _isr_stubs; -void isr_stage3(int interrupt); +void isr_stage3(int interrupt, uint64_t *stackframe); diff --git a/src/kernel/arch/amd64/interrupts/isr_stub.s b/src/kernel/arch/amd64/interrupts/isr_stub.s new file mode 100644 index 0000000..e45c1c1 --- /dev/null +++ b/src/kernel/arch/amd64/interrupts/isr_stub.s @@ -0,0 +1,81 @@ +.section .shared + +.global _isr_stubs +_isr_stubs: +.rept 256 + .set _stub_start, . + + cli + call _isr_stage2 + + .if . - _stub_start > 8 + .error "isr stubs over maximum size" + .abort + .endif + .align 8 +.endr + +_isr_stage2: + // pushal order, without %esp + push %rax + push %rcx + push %rdx + push %rbx + push %rbp + push %rsi + push %rdi + push %r8 + push %r9 + push %r10 + push %r11 + push %r12 + push %r13 + push %r14 + push %r15 + + // convert the return address into the vector nr + mov 120(%rsp), %rdi + sub $_isr_stubs, %rdi + shr $3, %rdi + + lea 128(%rsp), %rsi // second argument - IRET stack frame + + // load kernel paging + mov %cr3, %rbx + push %rbx + mov $pml4_identity, %rbx + mov %rbx, %cr3 + + mov %rsp, %rbp + mov $_isr_big_stack, %rsp + call isr_stage3 + + mov %rbp, %rsp + pop %rax // restore old cr3 + mov %rax, %cr3 + + // restore registers + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %r11 + pop %r10 + pop %r9 + pop %r8 + pop %rdi + pop %rsi + pop %rbp + pop %rbx + pop %rdx + pop %rcx + pop %rax + + add $8, %rsp // skip call's return address + iretq + +.align 8 +// TODO overflow check +.skip 256 // seems to be enough +.global _isr_mini_stack +_isr_mini_stack: diff --git a/src/kernel/arch/i386/multiboot.h b/src/kernel/arch/amd64/multiboot.h index 1d6718f..c6a2650 100644 --- a/src/kernel/arch/i386/multiboot.h +++ b/src/kernel/arch/amd64/multiboot.h @@ -1,15 +1,10 @@ #pragma once #include <stdint.h> -#ifndef __CHECKER__ -_Static_assert(sizeof(void*) == 4, - "this code assumes that pointers have 4 bytes"); -#endif - struct multiboot_mod { - void *start; - void *end; - const char *str; + uint32_t start; + uint32_t end; + uint32_t str; uint32_t _reserved; } __attribute__((packed)); @@ -19,16 +14,16 @@ struct multiboot_info { uint32_t flag_cmdline : 1; uint32_t flag_mods : 1; uint32_t _flag_other : 28; // unimplemented - + uint32_t mem_lower; uint32_t mem_upper; uint32_t boot_device; - const char *cmdline; + uint32_t cmdline; uint32_t mods_count; - struct multiboot_mod *mods; + uint32_t mods; // [...] } __attribute__((packed)); diff --git a/src/kernel/arch/i386/multiboot.s b/src/kernel/arch/amd64/multiboot.s index dc19b36..dc19b36 100644 --- a/src/kernel/arch/i386/multiboot.s +++ b/src/kernel/arch/amd64/multiboot.s diff --git a/src/kernel/arch/i386/pagedir.c b/src/kernel/arch/amd64/pagedir.c index e607cc7..334cfc2 100644 --- a/src/kernel/arch/i386/pagedir.c +++ b/src/kernel/arch/amd64/pagedir.c @@ -90,15 +90,20 @@ void *pagedir_unmap(struct pagedir *dir, void __user *virt) { void pagedir_map(struct pagedir *dir, void __user *virt, void *phys, bool user, bool writeable) { + kprintf("in pagedir_map, dir 0x%x\n", dir); uintptr_t virt_cast = (uintptr_t) virt; uint32_t pd_idx = virt_cast >> 22; uint32_t pt_idx = virt_cast >> 12 & 0x03FF; struct pagetable_entry *pagetable; + kprintf("pre-if, accessing 0x%x because 0x%x\n", &dir->e[pd_idx], pd_idx); if (dir->e[pd_idx].present) { + kprintf("present already\n"); pagetable = (void*) (dir->e[pd_idx].address << 11); } else { + kprintf("allocing\n"); pagetable = page_alloc(1); + kprintf("alloc successful\n"); for (int i = 0; i < 1024; i++) pagetable[i].present = 0; @@ -128,10 +133,12 @@ void pagedir_map(struct pagedir *dir, void __user *virt, void *phys, ._unused = 0, .address = (uintptr_t) phys >> 11 }; + kprintf("out pagedir_map\n"); } +extern void *pagedir_current; void pagedir_switch(struct pagedir *dir) { - asm volatile("mov %0, %%cr3;" : : "r" (dir) : "memory"); + pagedir_current = dir; } // creates a new pagedir with exact copies of the user pages diff --git a/src/kernel/arch/i386/port_io.h b/src/kernel/arch/amd64/port_io.h index eac9331..eac9331 100644 --- a/src/kernel/arch/i386/port_io.h +++ b/src/kernel/arch/amd64/port_io.h diff --git a/src/kernel/arch/i386/registers.h b/src/kernel/arch/amd64/registers.h index 9f481d3..e365e2c 100644 --- a/src/kernel/arch/i386/registers.h +++ b/src/kernel/arch/amd64/registers.h @@ -3,19 +3,16 @@ #include <stdint.h> struct registers { - /* those are in the order of pushad/popad - so you can load/save this - * struct in (almost) one instruction */ - uint32_t edi, esi; + uint64_t edi, esi; userptr_t ebp, esp; - uint32_t ebx, edx, ecx, eax; + uint64_t ebx, edx, ecx, eax; - // not part of pushad/popad, but still useful userptr_t eip; } __attribute__((__packed__)); // saves a return value according to the SysV ABI static inline uint64_t regs_savereturn(struct registers *regs, uint64_t value) { regs->eax = value; - regs->edx = value >> 32; + regs->edx = value >> 32; // TODO check ABI return value; } diff --git a/src/kernel/arch/i386/sysenter.c b/src/kernel/arch/amd64/sysenter.c index 5837474..e42ec7d 100644 --- a/src/kernel/arch/i386/sysenter.c +++ b/src/kernel/arch/amd64/sysenter.c @@ -1,5 +1,5 @@ #include <kernel/arch/generic.h> -#include <kernel/arch/i386/sysenter.h> +#include <kernel/arch/amd64/sysenter.h> #include <kernel/proc.h> #include <shared/syscalls.h> @@ -14,6 +14,7 @@ void sysexit(struct registers regs) { } _Noreturn void sysenter_stage2(void) { + kprintf("ring0 again!\n"); struct registers *regs = &process_current->regs; *regs = _sysexit_regs; // save the registers diff --git a/src/kernel/arch/i386/sysenter.h b/src/kernel/arch/amd64/sysenter.h index b88c186..b88c186 100644 --- a/src/kernel/arch/i386/sysenter.h +++ b/src/kernel/arch/amd64/sysenter.h diff --git a/src/kernel/arch/i386/sysenter.s b/src/kernel/arch/amd64/sysenter.s index d04f839..4dfe19d 100644 --- a/src/kernel/arch/i386/sysenter.s +++ b/src/kernel/arch/amd64/sysenter.s @@ -1,4 +1,4 @@ -/* arch/i386/gdt.c */ +/* TODO include gdt.h */ .set SEG_r0code, 1 .set SEG_r3code, 3 .set SEG_r3data, 4 @@ -11,18 +11,18 @@ .global sysenter_setup .type sysenter_setup, @function sysenter_setup: - xor %edx, %edx + xor %rdx, %rdx - mov $(SEG_r0code << 3), %eax - mov $IA32_SYSENTER_CS, %ecx + mov $(SEG_r0code << 3), %rax + mov $IA32_SYSENTER_CS, %rcx wrmsr - mov $IA32_SYSENTER_ESP, %ecx - mov $0, %eax // unused + mov $IA32_SYSENTER_ESP, %rcx + mov $0, %rax // unused wrmsr - mov $IA32_SYSENTER_EIP, %ecx - mov $sysenter_stage1, %eax + mov $IA32_SYSENTER_EIP, %rcx + mov $sysenter_stage1, %rax wrmsr ret @@ -34,9 +34,15 @@ sysenter_setup: stored_eax: .long 0 +.global pagedir_current +// a hack to maintain compat with the old arch api, TODO +pagedir_current: +.long 0 + .global _sysexit_real .type _sysexit_real, @function _sysexit_real: + xchgw %bx, %bx mov $(SEG_r3data << 3 | 3), %ax mov %ax, %ds mov %ax, %es @@ -44,46 +50,44 @@ _sysexit_real: mov %ax, %gs // restore the registers - mov $_sysexit_regs, %esp - pop %edi - pop %esi - pop %ebp - add $4, %esp - pop %ebx - pop %edx - pop %ecx - pop %eax + mov $_sysexit_regs, %rsp + pop %rdi + pop %rsi + pop %rbp + add $8, %rsp + pop %rbx + pop %rdx + pop %rcx + pop %rax // enable paging - mov %eax, stored_eax - mov %cr0, %eax - or $0x80000000, %eax - mov %eax, %cr0 - mov stored_eax, %eax - + // %rsp used as a scratch register + mov (pagedir_current), %rsp + mov %rsp, %cr3 sysexit sysenter_stage1: cli /* prevent random IRQs in the middle of kernel code */ + xchgw %bx, %bx // disable paging // I don't want to damage any of the registers passed in by the user, // so i'm using ESP as a temporary register. At this point there's nothing // useful in it, it's == _bss_end. - mov %cr0, %esp - and $0x7FFFFFFF, %esp // disable paging - mov %esp, %cr0 + mov %cr0, %rsp + and $0x7FFFFFFF, %rsp // disable paging + mov %rsp, %cr0 // save the registers - mov $(_sysexit_regs + 32), %esp - push %eax - push %ecx - push %edx - push %ebx - push $0x0 // pushal pushes %esp here, but that's worthless - push %ebp - push %esi - push %edi - - mov $_bss_end, %esp + mov $(_sysexit_regs + 64), %rsp + push %rax + push %rcx + push %rdx + push %rbx + push $0x0 // pushal pushes %rsp here, but that's worthless + push %rbp + push %rsi + push %rdi + + mov $_bss_end, %rsp jmp sysenter_stage2 diff --git a/src/kernel/arch/i386/tty/tty.c b/src/kernel/arch/amd64/tty/tty.c index 9451059..6593ef6 100644 --- a/src/kernel/arch/i386/tty/tty.c +++ b/src/kernel/arch/amd64/tty/tty.c @@ -1,6 +1,6 @@ #include <kernel/arch/generic.h> -#include <kernel/arch/i386/driver/serial.h> -#include <kernel/arch/i386/tty/tty.h> +#include <kernel/arch/amd64/driver/serial.h> +#include <kernel/arch/amd64/tty/tty.h> #include <shared/printf.h> void tty_init(void) { diff --git a/src/kernel/arch/i386/tty/tty.h b/src/kernel/arch/amd64/tty/tty.h index b96003d..b96003d 100644 --- a/src/kernel/arch/i386/tty/tty.h +++ b/src/kernel/arch/amd64/tty/tty.h diff --git a/src/kernel/arch/i386/tty/vga.c b/src/kernel/arch/amd64/tty/vga.c index 9efd326..e5f2274 100644 --- a/src/kernel/arch/i386/tty/vga.c +++ b/src/kernel/arch/amd64/tty/vga.c @@ -1,4 +1,4 @@ -#include <kernel/arch/i386/tty/tty.h> +#include <kernel/arch/amd64/tty/tty.h> struct vga_cell { unsigned char c; diff --git a/src/kernel/arch/generic.h b/src/kernel/arch/generic.h index a9e1ac9..d1ff292 100644 --- a/src/kernel/arch/generic.h +++ b/src/kernel/arch/generic.h @@ -1,6 +1,6 @@ #pragma once -#include <kernel/arch/i386/registers.h> +#include <kernel/arch/amd64/registers.h> #include <shared/types.h> #include <stdarg.h> #include <stdbool.h> @@ -15,7 +15,7 @@ extern char _bss_end; __attribute__((noreturn)) -void halt_cpu(void); +void cpu_halt(void); __attribute__((noreturn)) void cpu_shutdown(void); diff --git a/src/kernel/arch/i386/boot.s b/src/kernel/arch/i386/boot.s deleted file mode 100644 index 743c6d6..0000000 --- a/src/kernel/arch/i386/boot.s +++ /dev/null @@ -1,34 +0,0 @@ -.section .text -.global _start -.type _start, @function -_start: - mov $_stack_top, %esp - call sysenter_setup - push %ebx // address of the Multiboot struct - call kmain_early - -.global cpu_shutdown -.type cpu_shutdown, @function -cpu_shutdown: -/* This quits QEMU. While I couldn't find this officially documented anywhere, - * it is used by QEMU in tests/tcg/i386/system/boot.S (as of commit 40d6ee), so - * I assume that this is safe-ish to use */ - mov $0x604, %edx - mov $0x2000, %eax - outw %ax, %dx - -.global halt_cpu -.type halt_cpu, @function -halt_cpu: - cli -1: hlt - jmp 1b - - -.global cpu_pause -.type cpu_pause, @function -cpu_pause: - sti - hlt - cli - ret diff --git a/src/kernel/arch/i386/interrupts/isr_stub.s b/src/kernel/arch/i386/interrupts/isr_stub.s deleted file mode 100644 index fdbae6f..0000000 --- a/src/kernel/arch/i386/interrupts/isr_stub.s +++ /dev/null @@ -1,64 +0,0 @@ -.section .shared - -.global _isr_stubs -_isr_stubs: -.rept 256 - .set _stub_start, . - - cli - call _isr_stage2 - - .if . - _stub_start > 8 - .error "isr stubs over maximum size" - .abort - .endif - .align 8 -.endr - -_isr_stage2: - // pushal order, without %esp - push %eax - push %ecx - push %edx - push %ebx - push %ebp - push %esi - push %edi - - // convert the return address into the vector nr - mov 28(%esp), %eax - add $-_isr_stubs, %eax - shr $3, %eax - - // disable paging, if present - mov %cr0, %ebx - push %ebx // push original cr0 - and $0x7FFFFFFF, %ebx - mov %ebx, %cr0 - - mov %esp, %ebp - mov $_isr_big_stack, %esp - push %eax // push the vector nr - call isr_stage3 - - mov %ebp, %esp - pop %eax // restore old cr0 - mov %eax, %cr0 - - // restore registers - pop %edi - pop %esi - pop %ebp - pop %ebx - pop %edx - pop %ecx - pop %eax - - add $4, %esp // skip call's return address - iret - -.align 8 -// TODO overflow check -.skip 64 // seems to be enough -.global _isr_mini_stack -_isr_mini_stack: diff --git a/src/kernel/panic.h b/src/kernel/panic.h index 8cb32f4..4e591f1 100644 --- a/src/kernel/panic.h +++ b/src/kernel/panic.h @@ -7,7 +7,7 @@ kprintf(__func__); \ kprintf(" (" __FILE__ ":" NUM2STR(__LINE__) ")\n"); \ debug_stacktrace(); \ - halt_cpu(); \ + cpu_halt(); \ } while (0) #define panic_invalid_state() _panic("invalid state") diff --git a/src/kernel/proc.c b/src/kernel/proc.c index 1cb6eb0..616bd79 100644 --- a/src/kernel/proc.c +++ b/src/kernel/proc.c @@ -196,6 +196,7 @@ void process_forget(struct process *p) { } static _Noreturn void process_switch(struct process *proc) { + kprintf("process_switch\n"); assert(proc->state == PS_RUNNING); process_current = proc; pagedir_switch(proc->pages); diff --git a/src/kernel/vfs/request.c b/src/kernel/vfs/request.c index 7c677cc..97c71a7 100644 --- a/src/kernel/vfs/request.c +++ b/src/kernel/vfs/request.c @@ -1,4 +1,4 @@ -#include <kernel/arch/i386/driver/fsroot.h> +#include <kernel/arch/amd64/driver/fsroot.h> #include <kernel/mem/alloc.h> #include <kernel/mem/virt.h> #include <kernel/panic.h> diff --git a/src/shared/printf.c b/src/shared/printf.c index 496d5b8..b50d4ef 100644 --- a/src/shared/printf.c +++ b/src/shared/printf.c @@ -47,9 +47,9 @@ modifier_break: break; case 'x': - unsigned int n = va_arg(argp, int); + unsigned long n = va_arg(argp, long); size_t i = 4; // nibbles * 4 - while (n >> i && i < (sizeof(int) * 8)) + while (n >> i && i < (sizeof(n) * 8)) i += 4; if (i < pad_len * 4) diff --git a/src/user/lib/syscall.s b/src/user/lib/syscall.s index 0af49f3..0f9e444 100644 --- a/src/user/lib/syscall.s +++ b/src/user/lib/syscall.s @@ -2,23 +2,24 @@ .global _syscall .type _syscall, @function _syscall: - push %ebx // preserve registers - push %esi - push %edi - push %ebp + push %rbx // preserve registers + push %rsi + push %rdi + push %rbp - mov 20(%esp), %eax - mov 24(%esp), %ebx - mov %esp, %ecx - mov $_syscall_ret, %edx - mov 28(%esp), %esi - mov 32(%esp), %edi - mov 36(%esp), %ebp + // NOT the calling convention TODO you lazy fuck + mov 20(%rsp), %rax + mov 24(%rsp), %rbx + mov %rsp, %rcx + mov $_syscall_ret, %rdx + mov 28(%rsp), %rsi + mov 32(%rsp), %rdi + mov 36(%rsp), %rbp sysenter _syscall_ret: - pop %ebp - pop %edi - pop %esi - pop %ebx + pop %rbp + pop %rdi + pop %rsi + pop %rbx ret diff --git a/tools/dep_builders/binutils b/tools/dep_builders/binutils index 210c13b..cd88f5c 100755 --- a/tools/dep_builders/binutils +++ b/tools/dep_builders/binutils @@ -11,7 +11,7 @@ HASHES export PREFIX="$(pwd)/toolchain/" export CACHE="$(pwd)/toolchain/cache/" export PATH="$(pwd)/toolchain/bin/:$PATH" -export TARGET=i686-elf +export TARGET=x86_64-elf # ensure that we're in the repo root diff --git a/tools/dep_builders/gcc b/tools/dep_builders/gcc index 4c32b53..6813abe 100755 --- a/tools/dep_builders/gcc +++ b/tools/dep_builders/gcc @@ -11,7 +11,7 @@ HASHES export PREFIX="$(pwd)/toolchain/" export CACHE="$(pwd)/toolchain/cache/" export PATH="$(pwd)/toolchain/bin/:$PATH" -export TARGET=i686-elf +export TARGET=x86_64-elf # ensure that we're in the repo root @@ -48,7 +48,7 @@ mkdir $CACHE/$TOOL-$VER/builddir cd $CACHE/$TOOL-$VER/builddir ../configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c --without-headers -make all-gcc -make all-target-libgcc -make install-gcc -make install-target-libgcc +make -j4 all-gcc +make -j4 all-target-libgcc +make -j4 install-gcc +make -j4 install-target-libgcc |