Преглед изворни кода

create page table, enter long mode

greatbridf пре 10 месеци
родитељ
комит
04c392fdc7

+ 5 - 13
CMakeLists.txt

@@ -6,8 +6,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
 set(CMAKE_CXX_LINK_EXECUTABLE
 set(CMAKE_CXX_LINK_EXECUTABLE
     "<CMAKE_LINKER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
     "<CMAKE_LINKER> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
 
 
-set(CMAKE_ASM_FLAGS "-m32")
-set(C_CXX_FLAGS "-nostdinc -m32 -nostdlib -W -Wall -Wextra -Wno-stringop-overflow -Wno-builtin-declaration-mismatch -Wno-format -fverbose-asm -fno-exceptions -ffreestanding -fno-pic -mstack-protector-guard=global")
+set(C_CXX_FLAGS "-nostdinc -nostdlib -W -Wall -Wextra -Wno-stringop-overflow -Wno-builtin-declaration-mismatch -Wno-format -fverbose-asm -fno-exceptions -ffreestanding -fno-pic -mno-red-zone -mstack-protector-guard=global -mcmodel=kernel")
 set(CMAKE_C_FLAGS "${C_CXX_FLAGS} -Werror=implicit-int -Werror=implicit-function-declaration -Werror=strict-aliasing")
 set(CMAKE_C_FLAGS "${C_CXX_FLAGS} -Werror=implicit-int -Werror=implicit-function-declaration -Werror=strict-aliasing")
 set(CMAKE_CXX_FLAGS "${C_CXX_FLAGS} -fno-use-cxa-atexit -fno-rtti")
 set(CMAKE_CXX_FLAGS "${C_CXX_FLAGS} -fno-use-cxa-atexit -fno-rtti")
 set(CMAKE_CXX_LINK_FLAGS "")
 set(CMAKE_CXX_LINK_FLAGS "")
@@ -30,6 +29,7 @@ add_subdirectory(gblibstdc++)
 add_subdirectory(user-space-program)
 add_subdirectory(user-space-program)
 
 
 set(BOOTLOADER_SOURCES src/boot.s
 set(BOOTLOADER_SOURCES src/boot.s
+                       src/mbr.S
                        src/asm/interrupt.s
                        src/asm/interrupt.s
                        src/asm/port_io.s
                        src/asm/port_io.s
                        src/asm/sys.s
                        src/asm/sys.s
@@ -44,7 +44,7 @@ set(KERNEL_MAIN_SOURCES src/fs/fat.cpp
                         src/kernel/interrupt.cpp
                         src/kernel/interrupt.cpp
                         src/kernel/process.cpp
                         src/kernel/process.cpp
                         src/kernel/tty.cpp
                         src/kernel/tty.cpp
-                        src/kernel/syscall.cpp
+                        # src/kernel/syscall.cpp
                         src/kernel/syscall/fileops.cc
                         src/kernel/syscall/fileops.cc
                         src/kernel/syscall/mount.cc
                         src/kernel/syscall/mount.cc
                         src/kernel/mem.cpp
                         src/kernel/mem.cpp
@@ -110,26 +110,18 @@ add_executable(kernel.out ${KERNEL_MAIN_SOURCES} ${BOOTLOADER_SOURCES})
 target_link_libraries(kernel.out gblibc gblibstdc++)
 target_link_libraries(kernel.out gblibc gblibstdc++)
 target_include_directories(kernel.out PRIVATE ${PROJECT_SOURCE_DIR}/include)
 target_include_directories(kernel.out PRIVATE ${PROJECT_SOURCE_DIR}/include)
 target_link_options(kernel.out PRIVATE
 target_link_options(kernel.out PRIVATE
-    -T ${CMAKE_SOURCE_DIR}/src/kernel.ld -melf_i386 -lgblibc -L${CMAKE_BINARY_DIR}/gblibc)
+    -T ${CMAKE_SOURCE_DIR}/src/kernel.ld -lgblibc -L${CMAKE_BINARY_DIR}/gblibc)
 set_target_properties(kernel.out PROPERTIES LINK_DEPENDS ${CMAKE_SOURCE_DIR}/src/kernel.ld)
 set_target_properties(kernel.out PROPERTIES LINK_DEPENDS ${CMAKE_SOURCE_DIR}/src/kernel.ld)
 
 
-add_custom_command(OUTPUT mbr.bin
-    DEPENDS ${PROJECT_SOURCE_DIR}/src/mbr.S ${PROJECT_SOURCE_DIR}/src/mbr.ld
-    COMMAND ${CMAKE_ASM_COMPILER} -m32 -c ${PROJECT_SOURCE_DIR}/src/mbr.S -o mbr.o
-    COMMAND ${CMAKE_LINKER} -T ${PROJECT_SOURCE_DIR}/src/mbr.ld mbr.o -o mbr.bin
-)
-
 add_custom_command(OUTPUT mbr_hole.bin
 add_custom_command(OUTPUT mbr_hole.bin
     DEPENDS kernel.out
     DEPENDS kernel.out
     COMMAND ${CMAKE_OBJCOPY} --strip-debug -O binary ${CMAKE_BINARY_DIR}/kernel.out mbr_hole.bin
     COMMAND ${CMAKE_OBJCOPY} --strip-debug -O binary ${CMAKE_BINARY_DIR}/kernel.out mbr_hole.bin
 )
 )
 
 
 add_custom_target(boot.img
 add_custom_target(boot.img
-    DEPENDS mbr.bin
     DEPENDS mbr_hole.bin
     DEPENDS mbr_hole.bin
     DEPENDS user_space_programs
     DEPENDS user_space_programs
-    COMMAND dd if=mbr.bin of=boot.img
-    COMMAND cat mbr_hole.bin >> boot.img
+    COMMAND dd if=mbr_hole.bin of=boot.img
     COMMAND dd if=/dev/zero of=boot.img bs=`expr 512 \\* 1024 \\* 1024` count=0 seek=1
     COMMAND dd if=/dev/zero of=boot.img bs=`expr 512 \\* 1024 \\* 1024` count=0 seek=1
     COMMAND sh -c \"echo n\; echo\; echo\; echo\; echo\; echo a\; echo w\" | ${FDISK_BIN} boot.img
     COMMAND sh -c \"echo n\; echo\; echo\; echo\; echo\; echo a\; echo w\" | ${FDISK_BIN} boot.img
     COMMAND mkfs.fat --offset=2048 -v -n SYSTEM boot.img
     COMMAND mkfs.fat --offset=2048 -v -n SYSTEM boot.img

+ 1 - 1
Makefile.src

@@ -6,7 +6,7 @@ QEMU_DEBUG_FLAG=#-d cpu_reset,int
 QEMU_ARGS=-machine q35 -drive id=disk,file=build/boot.img,format=raw,if=none \
 QEMU_ARGS=-machine q35 -drive id=disk,file=build/boot.img,format=raw,if=none \
 	-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 \
 	-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0 \
 	-no-reboot -no-shutdown $(QEMU_ACCELERATION_FLAG) $(QEMU_DEBUG_FLAG)
 	-no-reboot -no-shutdown $(QEMU_ACCELERATION_FLAG) $(QEMU_DEBUG_FLAG)
-	
+
 CROSS_COMPILE=##PLACEHOLDER_4##
 CROSS_COMPILE=##PLACEHOLDER_4##
 .PHONY: run
 .PHONY: run
 run: build
 run: build

+ 3 - 8
configure

@@ -1,5 +1,5 @@
 #!/bin/sh
 #!/bin/sh
-QEMU_EXECUTABLES="qemu-system-i386 qemu-system-x86_64"
+QEMU_EXECUTABLES="qemu-system-x86_64"
 GDB_EXECUTABLES="gdb x86_64-elf-gdb"
 GDB_EXECUTABLES="gdb x86_64-elf-gdb"
 
 
 event() {
 event() {
@@ -77,13 +77,8 @@ case "$OS" in
         QEMU_ACCEL='-enable-kvm'
         QEMU_ACCEL='-enable-kvm'
         ;;
         ;;
     "Darwin")
     "Darwin")
-        if [ "$QEMU" = "qemu-system-x86_64" ]; then
-            echo "hvf"
-            QEMU_ACCEL='-accel hvf'
-        else
-            echo "tcg"
-            QEMU_ACCEL='-accel tcg'
-        fi
+        echo "tcg"
+        QEMU_ACCEL='-accel tcg'
         ;;
         ;;
 esac
 esac
 
 

+ 22 - 8
doc/mem_layout.txt

@@ -1,12 +1,26 @@
-0x00000000 - 0x00001000 kernel pd
-0x00001000 - 0x00005000 kernel pt
-0x00005000 - 0x00006000 empty page
+physical memory
 
 
-....
+0x0000 - 0x1000: early kernel data
+0x1000 - 0x2000: kernel stage1
+0x2000 - ?     : kernel image
 
 
-0x00100000 - 0x???????? kernel code, data, bss
-0x???????? - 0x01000000 kernel early stack
+0x100000 - 0x101000 : kernel PML4
+0x101000 - 0x102000 : kernel PDPT for physical memory mappings
+0x102000 - 0x103000 : kernel PDPT for kernel space
+0x103000 - 0x104000 : kernel PD for kernel image
+0x104000 - 0x105000 : kernel PT for kernel image
 
 
-....
+0x106000 - 0x200000 : unused empty pages
+0x200000 - 0x300000 : first kernel bss page (2MB)
 
 
-0x30000000 - 0x40000000 kernel heap
+
+virtual address space
+
+0xffffff0000000000 - 0xffffff3fffffffff  256GB physical memory (cached)
+0xffffff4000000000 - 0xffffff7fffffffff  256GB physical memory (not cached)
+0xffffff8000000000 - 0xffffffbfffffffff  256GB kernel bss
+
+0xffffffc000000000 - 0xffffffffffbfffff ~256GB unused
+
+0xffffffffffc00000 - 0xffffffffffdfffff    2MB kernel image
+0xffffffffffe00000 - 0xffffffffffffffff    2MB unused

+ 1 - 1
gblibstdc++/include/functional

@@ -147,7 +147,7 @@ public:
     using result_type = Ret;
     using result_type = Ret;
 
 
 private:
 private:
-    static constexpr std::size_t STACK_ALLOCATED_SIZE = 12;
+    static constexpr std::size_t STACK_ALLOCATED_SIZE = 24;
 
 
     char _data[STACK_ALLOCATED_SIZE];
     char _data[STACK_ALLOCATED_SIZE];
     using fb_t = __inner::_function_base<Ret, Args...>;
     using fb_t = __inner::_function_base<Ret, Args...>;

+ 0 - 1
include/asm/port_io.h

@@ -29,7 +29,6 @@ extern uint8_t asm_inb(port_id_t port_number);
 extern void asm_hlt(void);
 extern void asm_hlt(void);
 extern void asm_cli(void);
 extern void asm_cli(void);
 extern void asm_sti(void);
 extern void asm_sti(void);
-extern void asm_enable_sse(void);
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }

+ 2 - 2
include/kernel/async/lock.hpp

@@ -16,8 +16,8 @@ void init_spinlock(spinlock_t& lock);
 void spin_lock(spinlock_t& lock);
 void spin_lock(spinlock_t& lock);
 void spin_unlock(spinlock_t& lock);
 void spin_unlock(spinlock_t& lock);
 
 
-uint32_t spin_lock_irqsave(spinlock_t& lock);
-void spin_unlock_irqrestore(spinlock_t& lock, uint32_t state);
+size_t spin_lock_irqsave(spinlock_t& lock);
+void spin_unlock_irqrestore(spinlock_t& lock, size_t state);
 
 
 class mutex {
 class mutex {
 private:
 private:

+ 23 - 15
include/kernel/interrupt.h

@@ -11,24 +11,32 @@ extern "C" {
 
 
 #define PIC_EOI (0x20)
 #define PIC_EOI (0x20)
 
 
-struct regs_32 {
-    uint32_t edi;
-    uint32_t esi;
-    uint32_t ebp;
-    uint32_t esp;
-    uint32_t ebx;
-    uint32_t edx;
-    uint32_t ecx;
-    uint32_t eax;
+struct regs_64 {
+    uint64_t rax;
+    uint64_t rbx;
+    uint64_t rcx;
+    uint64_t rdx;
+    uint64_t rsi;
+    uint64_t rdi;
+    uint64_t rsp;
+    uint64_t rbp;
+    uint64_t r8;
+    uint64_t r9;
+    uint64_t r10;
+    uint64_t r11;
+    uint64_t r12;
+    uint64_t r13;
+    uint64_t r14;
+    uint64_t r15;
 };
 };
 
 
 struct interrupt_stack {
 struct interrupt_stack {
-    struct regs_32 s_regs;
-    void* v_eip;
-    uint32_t cs;
-    uint32_t eflags;
-    uint32_t esp;
-    uint32_t ss;
+    regs_64 s_regs;
+    void* v_rip;
+    uint64_t cs;
+    uint64_t flags;
+    uint64_t rsp;
+    uint64_t ss;
 };
 };
 
 
 struct mmx_registers {
 struct mmx_registers {

+ 9 - 9
include/kernel/mm.hpp

@@ -64,24 +64,24 @@ constexpr uint32_t pow()
 }
 }
 
 
 template <int N>
 template <int N>
-constexpr uint32_t align_down(uint32_t v)
+constexpr std::size_t align_down(std::size_t v)
 {
 {
     return v & ~(pow<2, N>() - 1);
     return v & ~(pow<2, N>() - 1);
 }
 }
 template <int N>
 template <int N>
 constexpr void* align_down(void* v)
 constexpr void* align_down(void* v)
 {
 {
-    return std::bit_cast<void*>(align_down<N>(std::bit_cast<uint32_t>(v)));
+    return std::bit_cast<void*>(align_down<N>(std::bit_cast<std::size_t>(v)));
 }
 }
 template <int N>
 template <int N>
-constexpr uint32_t align_up(uint32_t v)
+constexpr std::size_t align_up(std::size_t v)
 {
 {
     return align_down<N>(v + pow<2, N>() - 1);
     return align_down<N>(v + pow<2, N>() - 1);
 }
 }
 template <int N>
 template <int N>
 constexpr void* align_up(void* v)
 constexpr void* align_up(void* v)
 {
 {
-    return std::bit_cast<void*>(align_up<N>(std::bit_cast<uint32_t>(v)));
+    return std::bit_cast<void*>(align_up<N>(std::bit_cast<std::size_t>(v)));
 }
 }
 
 
 constexpr size_t vptrdiff(void* p1, void* p2)
 constexpr size_t vptrdiff(void* p1, void* p2)
@@ -283,7 +283,7 @@ public:
 
 
             free_page(&pg);
             free_page(&pg);
 
 
-            invalidate_tlb((uint32_t)area.start + (i++) * PAGE_SIZE);
+            invalidate_tlb((std::size_t)area.start + (i++) * PAGE_SIZE);
         }
         }
         types::memory::kidelete<mm::pages_vector>(area.pgs);
         types::memory::kidelete<mm::pages_vector>(area.pgs);
     }
     }
@@ -350,13 +350,13 @@ inline page empty_page;
 // {
 // {
 //     return p << 12;
 //     return p << 12;
 // }
 // }
-constexpr size_t v_to_pdi(void* addr)
+constexpr std::size_t v_to_pdi(void* addr)
 {
 {
-    return std::bit_cast<uint32_t>(addr) >> 22;
+    return std::bit_cast<std::size_t>(addr) >> 22;
 }
 }
-constexpr size_t v_to_pti(void* addr)
+constexpr std::size_t v_to_pti(void* addr)
 {
 {
-    return (std::bit_cast<uint32_t>(addr) >> 12) & 0x3ff;
+    return (std::bit_cast<std::size_t>(addr) >> 12) & 0x3ff;
 }
 }
 // inline constexpr pte_t* to_pte(pt_t pt, page_t pg)
 // inline constexpr pte_t* to_pte(pt_t pt, page_t pg)
 // {
 // {

+ 1 - 1
include/kernel/module.hpp

@@ -29,6 +29,6 @@ constexpr int MODULE_DELAYED = 2;
 // TODO: unique_ptr and Deleter
 // TODO: unique_ptr and Deleter
 int insmod(module* mod);
 int insmod(module* mod);
 
 
-extern "C" module_loader kmod_loaders_start[];
+extern "C" module_loader KMOD_LOADERS_START[];
 
 
 } // namespace kernel::module
 } // namespace kernel::module

+ 6 - 6
include/kernel/syscall.hpp

@@ -3,12 +3,12 @@
 #include <kernel/interrupt.h>
 #include <kernel/interrupt.h>
 #include <types/types.h>
 #include <types/types.h>
 
 
-#define SYSCALL_ARG1(type, name) type name = (type)((data)->s_regs.ebx)
-#define SYSCALL_ARG2(type, name) type name = (type)((data)->s_regs.ecx)
-#define SYSCALL_ARG3(type, name) type name = (type)((data)->s_regs.edx)
-#define SYSCALL_ARG4(type, name) type name = (type)((data)->s_regs.esi)
-#define SYSCALL_ARG5(type, name) type name = (type)((data)->s_regs.edi)
-#define SYSCALL_ARG6(type, name) type name = (type)((data)->s_regs.ebp)
+#define SYSCALL_ARG1(type, name) type name = (type)((data)->s_regs.rdi)
+#define SYSCALL_ARG2(type, name) type name = (type)((data)->s_regs.rsi)
+#define SYSCALL_ARG3(type, name) type name = (type)((data)->s_regs.rdx)
+#define SYSCALL_ARG4(type, name) type name = (type)((data)->s_regs.r10)
+#define SYSCALL_ARG5(type, name) type name = (type)((data)->s_regs.r8)
+#define SYSCALL_ARG6(type, name) type name = (type)((data)->s_regs.r9)
 
 
 // return value is stored in %eax and %edx
 // return value is stored in %eax and %edx
 typedef int (*syscall_handler)(interrupt_stack* data);
 typedef int (*syscall_handler)(interrupt_stack* data);

+ 1 - 1
include/kernel/task/thread.hpp

@@ -13,7 +13,7 @@
 
 
 namespace kernel::task {
 namespace kernel::task {
 
 
-using tid_t = uint32_t;
+using tid_t = std::size_t;
 
 
 struct thread {
 struct thread {
 public:
 public:

+ 18 - 7
include/types/hash_map.hpp

@@ -16,19 +16,30 @@ namespace types {
 
 
 // taken from linux
 // taken from linux
 constexpr uint32_t GOLDEN_RATIO_32 = 0x61C88647;
 constexpr uint32_t GOLDEN_RATIO_32 = 0x61C88647;
-// constexpr uint64_t GOLDEN_RATIO_64 = 0x61C8864680B583EBull;
+constexpr uint64_t GOLDEN_RATIO_64 = 0x61C8864680B583EBull;
 
 
-using hash_t = size_t;
+using hash_t = std::size_t;
 
 
 static inline constexpr hash_t _hash32(uint32_t val)
 static inline constexpr hash_t _hash32(uint32_t val)
 {
 {
     return val * GOLDEN_RATIO_32;
     return val * GOLDEN_RATIO_32;
 }
 }
 
 
-static inline constexpr hash_t hash32(uint32_t val, uint32_t bits)
+static inline constexpr hash_t hash32(uint32_t val, std::size_t bits)
 {
 {
     // higher bits are more random
     // higher bits are more random
-    return _hash32(val) >> (32 - bits);
+    return _hash32(val) >> (8 * sizeof(hash_t) - bits);
+}
+
+static inline constexpr hash_t _hash64(uint64_t val)
+{
+    return val * GOLDEN_RATIO_64;
+}
+
+static inline constexpr hash_t hash64(uint64_t val, std::size_t bits)
+{
+    // higher bits are more random
+    return _hash64(val) >> (8 * sizeof(hash_t) - bits);
 }
 }
 
 
 template <typename T>
 template <typename T>
@@ -36,17 +47,17 @@ constexpr bool is_c_string_v = std::is_same_v<std::decay_t<T>, char*>
     || std::is_same_v<std::decay_t<T>, const char*>;
     || std::is_same_v<std::decay_t<T>, const char*>;
 
 
 template <typename T,
 template <typename T,
-    std::enable_if_t<std::is_convertible_v<T, uint32_t>, bool> = true>
+    std::enable_if_t<std::is_convertible_v<T, uint64_t>, bool> = true>
 inline hash_t hash(T val, std::size_t bits)
 inline hash_t hash(T val, std::size_t bits)
 {
 {
-    return hash32(static_cast<uint32_t>(val), bits);
+    return hash64(static_cast<uint64_t>(val), bits);
 }
 }
 
 
 template <typename T,
 template <typename T,
     std::enable_if_t<std::is_pointer_v<T> && !is_c_string_v<T>, bool> = true>
     std::enable_if_t<std::is_pointer_v<T> && !is_c_string_v<T>, bool> = true>
 inline hash_t hash(T val, std::size_t bits)
 inline hash_t hash(T val, std::size_t bits)
 {
 {
-    return hash32(std::bit_cast<uint32_t>(val), bits);
+    return hash(std::bit_cast<ptr_t>(val), bits);
 }
 }
 
 
 inline hash_t hash(const char* str, std::size_t bits)
 inline hash_t hash(const char* str, std::size_t bits)

+ 2 - 9
include/types/size.h

@@ -8,15 +8,8 @@
 #error "no definition for ((PACKED))"
 #error "no definition for ((PACKED))"
 #endif
 #endif
 
 
-#define __32bit_system
-
-#ifdef __32bit_system
-typedef uint32_t ptr_t;
-typedef int32_t diff_t;
-#elif
-typedef uint64_t ptr_t;
-typedef int64_t diff_t;
-#endif
+typedef size_t ptr_t;
+typedef ssize_t diff_t;
 
 
 typedef ptr_t pptr_t;
 typedef ptr_t pptr_t;
 typedef ssize_t page_t;
 typedef ssize_t page_t;

+ 47 - 45
src/asm/interrupt.s

@@ -1,14 +1,15 @@
-.code32
-
 .text
 .text
 
 
+# TODO: LONG MODE
+# rewrite interrupt handlers
+
 # TODO: stack alignment
 # TODO: stack alignment
 .globl int6
 .globl int6
 .type  int6 @function
 .type  int6 @function
 int6:
 int6:
-    pushal
+# pushal
     call int6_handler
     call int6_handler
-    popal
+# popal
 
 
     iret
     iret
 
 
@@ -23,9 +24,9 @@ int8:
 .globl int13
 .globl int13
 .type  int13 @function
 .type  int13 @function
 int13:
 int13:
-    pushal
+# pushal
     call int13_handler
     call int13_handler
-    popal
+# popal
 
 
 # remove the 32bit error code from stack
 # remove the 32bit error code from stack
     addl $4, %esp
     addl $4, %esp
@@ -35,11 +36,11 @@ int13:
 .type  int14 @function
 .type  int14 @function
 int14:
 int14:
     # push general purpose registers
     # push general purpose registers
-    pushal
+# pushal
 
 
     # save %cr2
     # save %cr2
-    movl %cr2, %eax
-    pushl %eax
+    mov %cr2, %rax
+    push %rax
 
 
     # save current esp (also pointer to struct int14_data)
     # save current esp (also pointer to struct int14_data)
     mov %esp, %ebx
     mov %esp, %ebx
@@ -63,7 +64,7 @@ int14:
 
 
     # restore stack and general purpose registers
     # restore stack and general purpose registers
     leal 4(%ebx), %esp
     leal 4(%ebx), %esp
-    popal
+# popal
 
 
 # remove the 32bit error code from stack
 # remove the 32bit error code from stack
     addl $4, %esp
     addl $4, %esp
@@ -71,82 +72,82 @@ int14:
 
 
 .globl irq0
 .globl irq0
 irq0:
 irq0:
-    pushal
+# pushal
     mov $0, %eax
     mov $0, %eax
     jmp irqstub
     jmp irqstub
 .globl irq1
 .globl irq1
 irq1:
 irq1:
-    pushal
+# pushal
     mov $1, %eax
     mov $1, %eax
     jmp irqstub
     jmp irqstub
 .globl irq2
 .globl irq2
 irq2:
 irq2:
-    pushal
+# pushal
     mov $2, %eax
     mov $2, %eax
     jmp irqstub
     jmp irqstub
 .globl irq3
 .globl irq3
 irq3:
 irq3:
-    pushal
+# pushal
     mov $3, %eax
     mov $3, %eax
     jmp irqstub
     jmp irqstub
 .globl irq4
 .globl irq4
 irq4:
 irq4:
-    pushal
+# pushal
     mov $4, %eax
     mov $4, %eax
     jmp irqstub
     jmp irqstub
 .globl irq5
 .globl irq5
 irq5:
 irq5:
-    pushal
+# pushal
     mov $5, %eax
     mov $5, %eax
     jmp irqstub
     jmp irqstub
 .globl irq6
 .globl irq6
 irq6:
 irq6:
-    pushal
+# pushal
     mov $6, %eax
     mov $6, %eax
     jmp irqstub
     jmp irqstub
 .globl irq7
 .globl irq7
 irq7:
 irq7:
-    pushal
+# pushal
     mov $7, %eax
     mov $7, %eax
     jmp irqstub
     jmp irqstub
 .globl irq8
 .globl irq8
 irq8:
 irq8:
-    pushal
+# pushal
     mov $8, %eax
     mov $8, %eax
     jmp irqstub
     jmp irqstub
 .globl irq9
 .globl irq9
 irq9:
 irq9:
-    pushal
+# pushal
     mov $9, %eax
     mov $9, %eax
     jmp irqstub
     jmp irqstub
 .globl irq10
 .globl irq10
 irq10:
 irq10:
-    pushal
+# pushal
     mov $10, %eax
     mov $10, %eax
     jmp irqstub
     jmp irqstub
 .globl irq11
 .globl irq11
 irq11:
 irq11:
-    pushal
+# pushal
     mov $11, %eax
     mov $11, %eax
     jmp irqstub
     jmp irqstub
 .globl irq12
 .globl irq12
 irq12:
 irq12:
-    pushal
+# pushal
     mov $12, %eax
     mov $12, %eax
     jmp irqstub
     jmp irqstub
 .globl irq13
 .globl irq13
 irq13:
 irq13:
-    pushal
+# pushal
     mov $13, %eax
     mov $13, %eax
     jmp irqstub
     jmp irqstub
 .globl irq14
 .globl irq14
 irq14:
 irq14:
-    pushal
+# pushal
     mov $14, %eax
     mov $14, %eax
     jmp irqstub
     jmp irqstub
 .globl irq15
 .globl irq15
 irq15:
 irq15:
-    pushal
+# pushal
     mov $15, %eax
     mov $15, %eax
     jmp irqstub
     jmp irqstub
 
 
@@ -175,14 +176,14 @@ irqstub:
 
 
     # restore stack and general purpose registers
     # restore stack and general purpose registers
     mov %ebx, %esp
     mov %ebx, %esp
-    popal
+# popal
 
 
     iret
     iret
 
 
 .globl syscall_stub
 .globl syscall_stub
 .type  syscall_stub @function
 .type  syscall_stub @function
 syscall_stub:
 syscall_stub:
-    pushal
+# pushal
 
 
     # save current esp
     # save current esp
     mov %esp, %ebx
     mov %esp, %ebx
@@ -199,7 +200,8 @@ syscall_stub:
     lea 16(%esp), %eax
     lea 16(%esp), %eax
     mov %eax, 4(%esp) # pointer to mmx registers
     mov %eax, 4(%esp) # pointer to mmx registers
 
 
-    call syscall_entry
+    # TODO: LONG MODE
+    # call syscall_entry
 
 
     # restore mmx registers
     # restore mmx registers
     fxrstor 16(%esp)
     fxrstor 16(%esp)
@@ -210,7 +212,7 @@ syscall_stub:
 .globl _syscall_stub_fork_return
 .globl _syscall_stub_fork_return
 .type  _syscall_stub_fork_return @function
 .type  _syscall_stub_fork_return @function
 _syscall_stub_fork_return:
 _syscall_stub_fork_return:
-    popal
+# popal
     iret
     iret
 
 
 # parameters
 # parameters
@@ -222,27 +224,27 @@ asm_ctx_switch:
     movl 4(%esp), %ecx
     movl 4(%esp), %ecx
     movl 8(%esp), %eax
     movl 8(%esp), %eax
 
 
-    push $_ctx_switch_return
-    push %ebx
-    push %edi
-    push %esi
-    push %ebp
-    pushfl
+    pushq $_ctx_switch_return
+    push %rbx
+    push %rdi
+    push %rsi
+    push %rbp
+    pushf
 
 
     # push esp to restore
     # push esp to restore
-    pushl (%ecx)
+    push (%rcx)
 
 
-    mov %esp, (%ecx)
-    mov (%eax), %esp
+    mov %esp, (%rcx)
+    mov (%rax), %esp
 
 
     # restore esp
     # restore esp
-    popl (%eax)
+    pop (%rax)
 
 
-    popfl
-    pop %ebp
-    pop %esi
-    pop %edi
-    pop %ebx
+    popf
+    pop %rbp
+    pop %rsi
+    pop %rdi
+    pop %rbx
 
 
     ret
     ret
 
 

+ 9 - 25
src/asm/port_io.s

@@ -1,26 +1,24 @@
-.code32
-
 .text
 .text
 
 
 .globl asm_outb
 .globl asm_outb
 .type  asm_outb @function
 .type  asm_outb @function
 asm_outb:
 asm_outb:
-    pushl %eax
-    pushl %edx
-    movw 12(%esp), %dx
-    movb 16(%esp), %al
+    push %rax
+    push %rdx
+    mov 12(%esp), %dx
+    mov 16(%esp), %al
     outb %al, %dx
     outb %al, %dx
-    popl %edx
-    popl %eax
+    pop %rdx
+    pop %rax
     ret
     ret
 
 
 .globl asm_inb
 .globl asm_inb
 .type  asm_inb @function
 .type  asm_inb @function
 asm_inb:
 asm_inb:
-    pushl %edx
-    movw 8(%esp), %dx
+    push %rdx
+    mov 8(%esp), %dx
     inb %dx, %al
     inb %dx, %al
-    popl %edx
+    pop %rdx
     ret
     ret
 
 
 .globl asm_hlt
 .globl asm_hlt
@@ -40,17 +38,3 @@ asm_cli:
 asm_sti:
 asm_sti:
     sti
     sti
     ret
     ret
-
-.section .text.kinit
-.globl asm_enable_sse
-.type  asm_enable_sse @function
-asm_enable_sse:
-	movl %cr0, %eax
-    andl $0xfffffff3, %eax
-	orl $0b100010, %eax
-	movl %eax, %cr0
-	movl %cr4, %eax
-	orl $0b11000000000, %eax
-	movl %eax, %cr4
-    fninit
-	ret

+ 18 - 18
src/asm/sys.s

@@ -1,19 +1,17 @@
-.code32
-
 .text
 .text
 
 
 .global asm_switch_pd
 .global asm_switch_pd
 .type   asm_switch_pd @function
 .type   asm_switch_pd @function
 asm_switch_pd:
 asm_switch_pd:
-    movl 4(%esp), %eax
-    shll $12, %eax
-    movl %eax, %cr3
+    mov 8(%rsp), %rax
+    shl $12, %rax
+    mov %rax, %cr3
     ret
     ret
 
 
 .global current_pd
 .global current_pd
 .type   current_pd @function
 .type   current_pd @function
 current_pd:
 current_pd:
-    movl %cr3, %eax
+    mov %cr3, %rax
     ret
     ret
 
 
 .section .text.kinit
 .section .text.kinit
@@ -23,31 +21,33 @@ current_pd:
 asm_enable_paging:
 asm_enable_paging:
     cli
     cli
     // page directory address
     // page directory address
-    movl 4(%esp), %eax
-    movl %eax, %cr3
+    mov 8(%rsp), %rax
+    mov %rax, %cr3
 
 
-    movl %cr0, %eax
+    mov %cr0, %rax
     // SET PE, WP, PG
     // SET PE, WP, PG
-    orl $0x80010001, %eax
-    movl %eax, %cr0
+	mov $0x80010001, %rcx
+	or %rcx, %rax
+    mov %rax, %cr0
 
 
     ret
     ret
 
 
 .global asm_load_gdt
 .global asm_load_gdt
 .type   asm_load_gdt @function
 .type   asm_load_gdt @function
 asm_load_gdt:
 asm_load_gdt:
-    cli
-    leal 6(%esp), %eax
-    lgdt (%eax)
-    ljmp $0x08, $_asm_load_gdt_fin
-_asm_load_gdt_fin:
     ret
     ret
+# TODO: LONG MODE
+#     cli
+#     lea 14(%rsp), %rax
+#     lgdt (%rax)
+#     ljmp $0x08, $_asm_load_gdt_fin
+# _asm_load_gdt_fin:
+#     ret
 
 
 .global asm_load_tr
 .global asm_load_tr
 .type   asm_load_tr @function
 .type   asm_load_tr @function
 asm_load_tr:
 asm_load_tr:
     cli
     cli
-    movl 4(%esp), %eax
-    orl $0, %eax
+    mov 8(%rsp), %rax
     ltr %ax
     ltr %ax
     ret
     ret

+ 176 - 287
src/boot.s

@@ -1,294 +1,183 @@
 .section .stage1
 .section .stage1
-.code16
-loader_start:
-# set segment registers
-    movw %cs, %ax
-    movw %ax, %ds
-
-_clear_screen:
-    mov $0x00, %ah
-    mov $0x03, %al
-    int $0x10
-
-# get memory size info and storage it
-_get_memory_size:
-    xorw %cx, %cx
-    xorw %dx, %dx
-    movw $0xe801, %ax
-
-    int $0x15
-    jc _get_memory_size_error
-
-    cmpb $0x86, %ah # unsupported function
-    je _get_memory_size_error
-    cmpb $0x80, %ah # invalid command
-    je _get_memory_size_error
-
-    jcxz _get_memory_size_use_ax
-    movw %cx, %ax
-    movw %dx, %bx
-
-_get_memory_size_use_ax:
-    movl $asm_mem_size_info, %edx
-    movw %ax, (%edx)
-    addw $2, %dx
-    movw %bx, (%edx)
-    jmp _e820_mem_map_load
-
-_get_memory_size_error:
-    xchgw %bx, %bx
-    jmp __stage1_halt
-
-_e820_mem_map_load:
-    addl $4, %esp
-    movl $0, (%esp)
-
-    # save the destination address to es:di
-    movw %cs, %ax
-    movw %ax, %es
-
-    movl $asm_e820_mem_map, %edi
-
-    # clear ebx
-    xorl %ebx, %ebx
-
-    # set the magic number to edx
-    movl $0x534D4150, %edx
-
-_e820_mem_map_load_loop:
-    # set function number to eax
-    movl $0xe820, %eax
-
-    # set default entry size
-    movl $24, %ecx
-
-    int $0x15
-
-    incl (%esp)
-    addl %ecx, %edi
-
-    jc _e820_mem_map_load_fin
-    cmpl $0, %ebx
-    jz _e820_mem_map_load_fin
-    jmp _e820_mem_map_load_loop
-
-_e820_mem_map_load_fin:
-    movl (%esp), %eax
-    movl $asm_e820_mem_map_count, %edi
-    movl %eax, (%edi)
-
-    movl $asm_e820_mem_map_entry_size, %edi
-    movl %ecx, (%edi)
-
-    jmp _load_gdt
-
-_load_gdt:
-    cli
-    lgdt asm_gdt_descriptor
-
-# enable protection enable (PE) bit
-    movl %cr0, %eax
-    orl $1, %eax
-    movl %eax, %cr0
-
-    ljmp $0x08, $start_32bit
-
 .code32
 .code32
-
+.globl start_32bit
 start_32bit:
 start_32bit:
-    movw $0x10, %ax
-    movw %ax, %ds
-    movw %ax, %es
-    movw %ax, %fs
-    movw %ax, %gs
-    movw %ax, %ss
-
-    movl $0, %esp
-    movl $0, %ebp
-
-setup_early_kernel_page_table:
-# memory map:
-# 0x0000-0x1000: empty page
-# 0x1000-0x2000: early kernel pd
-# 0x2000-0x6000: 4 pts
-# 0x6000-0x8000: early kernel stack
-# so we fill the first 8KiB with zero
-    movl $0x00000000, %eax
-    movl $0x8000, %ecx
-
-_fill_zero:
-    cmpl $0, %ecx
-    jz _fill_zero_end
-    subl $4, %ecx
-    movl $0, (%eax)
-    addl $4, %eax
-    jmp _fill_zero
-_fill_zero_end:
-
-# pt#0: 0x00000000 to 0x00400000
-    movl $0x00001000, %eax
-    movl $0x00002003, (%eax)
-# pt#1: 0xc0000000 to 0xc0400000
-    movl $0x00001c00, %eax
-    movl $0x00003003, (%eax)
-# pt#2: 0xff000000 to 0xff400000
-    movl $0x00001ff0, %eax
-    movl $0x00004003, (%eax)
-# pt#3: 0xffc00000 to 0xffffffff
-    movl $0x00001ffc, %eax
-    movl $0x00005003, (%eax)
-
-# map early kernel page directory to 0xff000000
-    movl $0x00004000, %eax
-    movl $0x00001003, (%eax)
-
-# map kernel pt#2 to 0xff001000
-    movl $0x00004004, %eax
-    movl $0x00004003, (%eax)
-
-# map __stage1_start ---- __kinit_end identically
-    movl $__stage1_start, %ebx
-    movl $__kinit_end, %ecx
-    movl %ebx, %edx
-    shrl $12, %edx
-    andl $0x3ff, %edx
-
-
-__map_stage1_kinit:
-    leal 3(%ebx), %eax
-    movl %eax, 0x00002000(, %edx, 4)
-    addl $0x1000, %ebx
-    incl %edx
-    cmpl %ebx, %ecx
-    jne __map_stage1_kinit
-
-# map __text_start ---- __data_end to 0xc0000000
-    movl %ecx, %ebx
-    movl $__text_start, %edx
-    shrl $12, %edx
-    andl $0x3ff, %edx
-
-    movl $__data_end, %ecx
-    subl $__text_start, %ecx
-    addl %ebx, %ecx
-
-__map_kernel_space:
-    leal 3(%ebx), %eax
-    movl %eax, 0x00003000(, %edx, 4)
-    addl $0x1000, %ebx
-    incl %edx
-    cmpl %ebx, %ecx
-    jne __map_kernel_space
-
-# map __data_end ---- __bss_end from 0x100000
-    movl $0x100000, %ebx
-    movl $__bss_end, %ecx
-    subl $__data_end, %ecx
-    addl %ebx, %ecx
-
-__map_kernel_bss:
-    leal 3(%ebx), %eax
-    movl %eax, 0x00003000(, %edx, 4)
-    addl $0x1000, %ebx
-    incl %edx
-    cmpl %ebx, %ecx
-    jne __map_kernel_bss
-
-# map kernel stack 0xffffe000-0xffffffff
-    movl $0x6000, %ebx
-    movl $0x8000, %ecx
-    movl $0x0ffffe, %edx
-    andl $0x3ff, %edx
-
-__map_kernel_stack:
-    leal 3(%ebx), %eax
-    movl %eax, 0x00005000(, %edx, 4)
-    addl $0x1000, %ebx
-    incl %edx
-    cmpl %ebx, %ecx
-    jne __map_kernel_stack
-
-load_early_kernel_page_table:
-    movl $0x00001000, %eax
-    movl %eax, %cr3
-
-    movl %cr0, %eax
+    mov $0x10, %ax
+    mov %ax, %ds
+    mov %ax, %es
+    mov %ax, %fs
+    mov %ax, %gs
+    mov %ax, %ss
+
+    cld
+    xor %eax, %eax
+
+    # clear paging structures
+    mov $0x100000, %edi
+    mov %edi, %ecx
+    shr $2, %ecx # %ecx /= 4
+    rep stosl
+
+    # set P, RW, G
+    mov $0x00000103, %ebx
+	xor %edx, %edx
+    mov $0x00101000, %esi
+
+    # PML4E 0x000
+    # we need the first 1GB identically mapped
+    # so that we won't trigger a triple fault after
+    # enabling paging
+	lea -0x1000(%esi), %edi # %edi = 0x100000
+    call fill_pxe
+
+    # PML4E 0xff0
+	mov $0x80000000, %edx
+	lea 0xff0(%edi), %edi
+	call fill_pxe
+	xor %edx, %edx
+
+    # setup PDPT for physical memory mapping
+    mov %esi, %edi
+
+    # set PS
+    or $0x00000080, %ebx
+    mov $256, %ecx
+    xor %esi, %esi
+_fill_loop1:
+    call fill_pxe
+    lea 8(%edi), %edi
+    add $0x40000000, %esi # 1GB
+    adc $0, %edx
+    loop _fill_loop1
+
+    # set PCD
+    or $0x00000010, %ebx
+    mov $256, %ecx
+    xor %esi, %esi
+_fill_loop2:
+    call fill_pxe
+    lea 8(%edi), %edi
+    add $0x40000000, %esi # 1GB
+    adc $0, %edx
+    loop _fill_loop2
+
+	xor %edx, %edx
+
+    # PML4E 0xff8
+    mov %edi, %esi # 0x102000
+    mov $0x100ff8, %edi
+    # clear PCD, PS
+    and $(~0x00000090), %ebx
+    call fill_pxe
+
+    # PDPTE 0xff8
+    lea 0xff8(%esi), %edi  # 0x102ff8
+    lea 0x1000(%esi), %esi # 0x103000
+    call fill_pxe
+
+    # PDE 0xff0
+    lea 0xff0(%esi), %edi  # 0x103ff0
+    lea 0x1000(%esi), %esi # 0x104000
+    call fill_pxe
+
+    # fill PT (kernel image)
+    mov %esi, %edi # 0x104000
+    mov $0x2000, %esi
+
+.extern KERNEL_PAGES
+    mov $KIMAGE_PAGES, %ecx
+
+_fill_loop3:
+    call fill_pxe
+    lea 8(%edi), %edi
+	lea 0x1000(%esi), %esi
+    loop _fill_loop3
+
+    # set msr
+    mov $0xc0000080, %ecx
+    rdmsr
+    or $0x900, %eax # set LME, NXE
+    wrmsr
+
+    # set cr4
+    mov %cr4, %eax
+    or $0xa0, %eax # set PAE, PGE
+    mov %eax, %cr4
+
+    # load new page table
+	xor %eax, %eax
+	inc %eax
+	shl $20, %eax # %eax = 0x100000
+    mov %eax, %cr3
+
+    mov %cr0, %eax
     // SET PE, WP, PG
     // SET PE, WP, PG
-    orl $0x80010001, %eax
-    movl %eax, %cr0
-
-# set stack pointer and clear stack bottom
-    movl $0xfffffff0, %esp
-    movl $0xfffffff0, %ebp
-
-    movl $0x00, (%esp)
-    movl $0x00, 4(%esp)
-    movl $0x00, 8(%esp)
-    movl $0x00, 12(%esp)
+    or $0x80010001, %eax
+    mov %eax, %cr0
+
+    # create gdt
+	xor %eax, %eax # at 0x0000
+	mov %eax,   (%eax)
+	mov %eax,  4(%eax) # null descriptor
+	mov %eax,  8(%eax) # code segment lower
+	mov %eax, 16(%eax) # data segment lower
+	mov $0x00209a00, %ecx
+	mov %ecx, 12(%eax) # code segment higher
+	mov $0x00009200, %ecx
+	mov %ecx, 20(%eax) # data segment higher
+
+    # gdt descriptor
+	push %eax
+	push %eax
+
+    # pad with a word
+	mov $0x00170000, %eax
+	push %eax
+
+	lgdt 2(%esp)
+	add $12, %esp
+
+    ljmp $0x08, $_64bit_entry
+
+# %ebx: attribute low
+# %edx: attribute high
+# %esi: page physical address
+# %edi: page x entry address
+fill_pxe:
+    lea (%ebx, %esi, 1), %eax
+    mov %eax, (%edi)
+    mov %edx, 4(%edi)
+
+    ret
+
+.code64
+_64bit_entry:
+	jmp start_64bit
+
+.section .text.kinit
+start_64bit:
+    # set stack pointer and clear stack bottom
+	movzw %sp, %rdi
+	xor %rsp, %rsp
+	inc %rsp
+	neg %rsp
+	shr $40, %rsp
+	shl $40, %rsp
+
+	add %rdi, %rsp
+	mov %rsp, %rdi
+
+    # make stack frame
+	lea -16(%rsp), %rsp
+	mov %rsp, %rbp
+
+	xor %rax, %rax
+	mov %rax, (%rsp)
+	mov %rax, 8(%rsp)
 
 
     call kernel_init
     call kernel_init
 
 
-__stage1_halt:
-    hlt
-    jmp __stage1_halt
-
-asm_gdt_descriptor:
-    .word (5 * 8) - 1 # size
-    .long asm_gdt_table  # address
-asm_gdt_table:
-    .8byte 0         # null descriptor
-
-    # kernel code segment
-    .word 0xffff     # limit 0 :15
-    .word 0x0000     # base  0 :15
-    .byte 0x00       # base  16:23
-    .byte 0x9a       # access
-    .byte 0b11001111 # flag and limit 16:20
-    .byte 0x00       # base 24:31
-
-    # kernel data segment
-    .word 0xffff     # limit 0 :15
-    .word 0x0000     # base  0 :15
-    .byte 0x00       # base  16:23
-    .byte 0x92       # access
-    .byte 0b11001111 # flag and limit 16:20
-    .byte 0x00       # base 24:31
-
-    # user code segment
-    .word 0xffff     # limit 0 :15
-    .word 0x0000     # base  0 :15
-    .byte 0x00       # base  16:23
-    .byte 0xfa       # access
-    .byte 0b11001111 # flag and limit 16:20
-    .byte 0x00       # base 24:31
-
-    # user data segment
-    .word 0xffff     # limit 0 :15
-    .word 0x0000     # base  0 :15
-    .byte 0x00       # base  16:23
-    .byte 0xf2       # access
-    .byte 0b11001111 # flag and limit 16:20
-    .byte 0x00       # base 24:31
-
-.globl asm_mem_size_info
-.type  asm_mem_size_info @object
-.size  asm_mem_size_info, (.-asm_mem_size_info)
-asm_mem_size_info:
-    .word 0x12
-    .word 0x34
-
-.globl asm_e820_mem_map
-.type  asm_e820_mem_map @object
-.size  asm_e820_mem_map, (.-asm_e820_mem_map)
-asm_e820_mem_map:
-    .space 1024
-
-.globl asm_e820_mem_map_count
-.type  asm_e820_mem_map_count @object
-asm_e820_mem_map_count:
-    .long 0
-
-.globl asm_e820_mem_map_entry_size
-.type  asm_e820_mem_map_entry_size @object
-asm_e820_mem_map_entry_size:
-    .long 0
+_64bit_hlt:
+	cli
+	hlt
+	jmp _64bit_hlt

+ 50 - 50
src/kernel.ld

@@ -1,36 +1,46 @@
-OUTPUT_FORMAT(elf32-i386)
-OUTPUT_ARCH(i386:i386)
+OUTPUT_FORMAT(elf64-x86-64)
 
 
 MEMORY
 MEMORY
 {
 {
-    MEM : org = 0x00000000, l = 4096M
+    MBR    (wx) : org = 0x0e00, l = 512
+    STAGE1 (wx) : org = 0x1000, l = 4K
+    PHYMEM (w)  : org = 0xffffff0000000000, len = 512 * 1024M
+    KBSS   (w)  : org = 0xffffffffff800000, len = 2M
+    KIMAGE (wx) : org = 0xffffffffffc00000, len = 2M
 }
 }
 
 
 SECTIONS
 SECTIONS
 {
 {
-    .stage1 0x8000 : AT(0x00000000)
+    .mbr : AT(0)
+    {
+        *(.mbr)
+
+        . = 510;
+        BYTE(0x55);
+        BYTE(0xaa);
+    } > MBR
+
+    .stage1 : AT(LOADADDR(.mbr) + SIZEOF(.mbr))
     {
     {
         __stage1_start = .;
         __stage1_start = .;
         *(.stage1)
         *(.stage1)
 
 
         . = ALIGN(0x1000);
         . = ALIGN(0x1000);
         __stage1_end = .;
         __stage1_end = .;
-    } > MEM
+    } > STAGE1
 
 
     .kinit :
     .kinit :
         AT(LOADADDR(.stage1) + SIZEOF(.stage1))
         AT(LOADADDR(.stage1) + SIZEOF(.stage1))
     {
     {
-        __kinit_start = .;
-        *(.text.kinit)
+        KIMAGE_START = .;
+        KINIT_START = .;
 
 
-        LONG(0x00000000)
-        LONG(0x19191919)
-        LONG(0x00000000)
+        *(.text.kinit)
 
 
+        . = ALIGN(16);
         *(.rodata.kinit)
         *(.rodata.kinit)
 
 
         . = ALIGN(16);
         . = ALIGN(16);
-
         start_ctors = .;
         start_ctors = .;
         KEEP(*(.init_array));
         KEEP(*(.init_array));
         KEEP(*(SORT_BY_INIT_PRIORITY(.init_array*)));
         KEEP(*(SORT_BY_INIT_PRIORITY(.init_array*)));
@@ -38,89 +48,79 @@ SECTIONS
         KEEP(*(SORT_BY_INIT_PRIORITY(.ctors*)));
         KEEP(*(SORT_BY_INIT_PRIORITY(.ctors*)));
         end_ctors = .;
         end_ctors = .;
 
 
-        LONG(0x00000000)
-        LONG(0x19191919)
-        LONG(0x00000000)
-
+        . = ALIGN(16);
         *(.data.kinit)
         *(.data.kinit)
 
 
-        LONG(0x00000000)
-        LONG(0x19191919)
-        LONG(0x00000000)
-
+        . = ALIGN(16);
         *(.bss.kinit)
         *(.bss.kinit)
 
 
-        LONG(0x00000000)
-        LONG(0x19191919)
-        LONG(0x00000000)
-
         . = ALIGN(0x1000);
         . = ALIGN(0x1000);
-        __kinit_end = .;
-    } > MEM
+        KINIT_END = .;
+    } > KIMAGE
 
 
-    .text 0xc0000000 :
+    .text :
         AT(LOADADDR(.kinit) + SIZEOF(.kinit))
         AT(LOADADDR(.kinit) + SIZEOF(.kinit))
     {
     {
-        __text_start = .;
+        TEXT_START = .;
         *(.text)
         *(.text)
         *(.text*)
         *(.text*)
 
 
         . = ALIGN(0x1000);
         . = ALIGN(0x1000);
-        __text_end = .;
-    } > MEM
+        TEXT_END = .;
+    } > KIMAGE
 
 
     .rodata :
     .rodata :
         AT(LOADADDR(.text) + SIZEOF(.text))
         AT(LOADADDR(.text) + SIZEOF(.text))
     {
     {
-        __rodata_start = .;
+        RODATA_START = .;
         *(.rodata)
         *(.rodata)
         *(.rodata*)
         *(.rodata*)
 
 
         . = ALIGN(16);
         . = ALIGN(16);
-        kmod_loaders_start = .;
+        KMOD_LOADERS_START = .;
 
 
         *(.kmods)
         *(.kmods)
-
-        __kmod_loaders_end = .;
-        LONG(0);
+        QUAD(0);
 
 
         . = ALIGN(16);
         . = ALIGN(16);
 
 
         bss_addr = .;
         bss_addr = .;
-        LONG(ABSOLUTE(__bss_start));
+        QUAD(ABSOLUTE(BSS_START));
         bss_len = .;
         bss_len = .;
-        LONG(__bss_end - __bss_start);
-        kernel_size = .;
-        LONG(__data_end - __kinit_start);
+        QUAD(BSS_END - BSS_START);
 
 
         . = ALIGN(0x1000);
         . = ALIGN(0x1000);
-        __rodata_end = .;
-    } > MEM
+        RODATA_END = .;
+    } > KIMAGE
 
 
     .data :
     .data :
         AT(LOADADDR(.rodata) + SIZEOF(.rodata))
         AT(LOADADDR(.rodata) + SIZEOF(.rodata))
     {
     {
-        __data_start = .;
+        DATA_START = .;
         *(.data)
         *(.data)
         *(.data*)
         *(.data*)
 
 
         . = ALIGN(0x1000);
         . = ALIGN(0x1000);
-        __data_end = .;
-    } > MEM
+        DATA_END = .;
+        KIMAGE_END = .;
+    } > KIMAGE
+
+    .sentry :
+        AT(0x78000 - 0x4)
+    { LONG(0x01145140); } > KIMAGE
 
 
     .bss :
     .bss :
     {
     {
-        __bss_start = .;
+        BSS_START = .;
         *(.bss)
         *(.bss)
         *(.bss*)
         *(.bss*)
 
 
         . = ALIGN(0x1000);
         . = ALIGN(0x1000);
-        __bss_end = .;
-    } > MEM
+        BSS_END = .;
+    } > KBSS
 
 
-    .sentry :
-        AT(0x60000)
-    { LONG(0x01145140); } > MEM
+    KIMAGE_PAGES = (KIMAGE_END - KIMAGE_START) / 0x1000;
+    BSS_PAGES = (BSS_END - BSS_START) / 0x1000;
 
 
     .eh_frame :
     .eh_frame :
         AT(LOADADDR(.sentry) + SIZEOF(.sentry))
         AT(LOADADDR(.sentry) + SIZEOF(.sentry))
@@ -129,7 +129,7 @@ SECTIONS
         *(.eh_frame*)
         *(.eh_frame*)
         . = ALIGN(0x1000);
         . = ALIGN(0x1000);
         __eh_frame_end = .;
         __eh_frame_end = .;
-    } > MEM
+    } > KIMAGE
 
 
     /* Stabs debugging sections.  */
     /* Stabs debugging sections.  */
     .stab          0 : { *(.stab) }
     .stab          0 : { *(.stab) }

+ 9 - 9
src/kernel/async/lock.cc

@@ -29,12 +29,12 @@ static inline void _raw_spin_unlock(spinlock_t* lock_addr)
         : "eax", "memory");
         : "eax", "memory");
 }
 }
 
 
-static inline uint32_t _save_interrupt_state()
+static inline size_t _save_interrupt_state()
 {
 {
-    uint32_t retval;
+    size_t retval;
     asm volatile(
     asm volatile(
-        "pushfl\n\t"
-        "popl %0\n\t"
+        "pushfq\n\t"
+        "pop %0\n\t"
         "cli"
         "cli"
         : "=g"(retval)
         : "=g"(retval)
         :
         :
@@ -44,11 +44,11 @@ static inline uint32_t _save_interrupt_state()
     return retval;
     return retval;
 }
 }
 
 
-static inline void _restore_interrupt_state(uint32_t flags)
+static inline void _restore_interrupt_state(size_t flags)
 {
 {
     asm volatile(
     asm volatile(
-        "pushl %0\n\t"
-        "popfl"
+        "push %0\n\t"
+        "popf"
         :
         :
         : "g"(flags)
         : "g"(flags)
         :
         :
@@ -90,7 +90,7 @@ void spin_unlock(spinlock_t& lock)
     preempt_enable();
     preempt_enable();
 }
 }
 
 
-uint32_t spin_lock_irqsave(spinlock_t& lock)
+size_t spin_lock_irqsave(spinlock_t& lock)
 {
 {
     auto state = _save_interrupt_state();
     auto state = _save_interrupt_state();
     preempt_disable();
     preempt_disable();
@@ -100,7 +100,7 @@ uint32_t spin_lock_irqsave(spinlock_t& lock)
     return state;
     return state;
 }
 }
 
 
-void spin_unlock_irqrestore(spinlock_t& lock, uint32_t state)
+void spin_unlock_irqrestore(spinlock_t& lock, size_t state)
 {
 {
     _raw_spin_unlock(&lock);
     _raw_spin_unlock(&lock);
     preempt_enable();
     preempt_enable();

+ 41 - 46
src/kernel/interrupt.cpp

@@ -66,19 +66,18 @@ extern "C" void asm_load_idt(uint16_t idt_descriptor[3], int sti);
 
 
 static struct IDT_entry IDT[256];
 static struct IDT_entry IDT[256];
 
 
-static inline void NORETURN die(regs_32& regs, ptr_t eip)
+static inline void NORETURN die(regs_64& regs, void* rip)
 {
 {
-    char buf[512] = {};
-    snprintf(
-        buf, sizeof(buf),
-        "***** KERNEL PANIC *****\n"
-        "eax: %x, ebx: %x, ecx: %x, edx: %x\n"
-        "esp: %x, ebp: %x, esi: %x, edi: %x\n"
-        "eip: %x\n",
-        regs.eax, regs.ebx, regs.ecx,
-        regs.edx, regs.esp, regs.ebp,
-        regs.esi, regs.edi, eip);
-    kmsg(buf);
+    kmsgf( "***** KERNEL PANIC *****\n"
+           "rax: %llx, rbx: %llx, rcx: %llx, rdx: %llx\n"
+           "rsp: %llx, rbp: %llx, rsi: %llx, rdi: %llx\n"
+           "r8 : %llx, r9 : %llx, r10: %llx, r11: %llx\n"
+           "r12: %llx, r13: %llx, r14: %llx, r15: %llx\n"
+           "rip: %llx\n",
+           regs.rax, regs.rbx, regs.rcx, regs.rdx,
+           regs.rsp, regs.rbp, regs.rsi, regs.rdi,
+           regs.r8 , regs.r9 , regs.r10, regs.r11,
+           regs.r12, regs.r13, regs.r14, regs.r15, rip);
     freeze();
     freeze();
 }
 }
 
 
@@ -162,59 +161,55 @@ void init_pic(void)
 }
 }
 
 
 extern "C" void int6_handler(
 extern "C" void int6_handler(
-    regs_32 s_regs,
-    ptr_t eip,
-    uint16_t cs,
-    uint32_t eflags)
+    regs_64 s_regs,
+    void* rip,
+    uint64_t cs,
+    uint64_t rflags,
+    uint64_t rsp,
+    uint64_t ss)
 {
 {
     if (!current_process->attr.system)
     if (!current_process->attr.system)
-        kill_current(SIGSEGV);
+        kill_current(SIGSEGV); // noreturn
 
 
-    char buf[128];
-    snprintf(buf, sizeof(buf),
-        "[kernel] int6 data: cs: %x, eflags: %x\n", cs, eflags);
-    kmsg(buf);
-
-    die(s_regs, eip);
+    kmsgf("[kernel] int6: cs: %llx, rflags: %llx, rsp: %llx, ss: %llx",
+            cs, rflags, rsp, ss);
+    die(s_regs, rip); // noreturn
 }
 }
 
 
 // general protection
 // general protection
 extern "C" void int13_handler(
 extern "C" void int13_handler(
-    struct regs_32 s_regs,
-    uint32_t error_code,
-    ptr_t eip,
-    uint16_t cs,
-    uint32_t eflags)
+    regs_64 s_regs,
+    uint64_t error_code,
+    void* rip,
+    uint64_t cs,
+    uint64_t rflags,
+    uint64_t rsp,
+    uint64_t ss)
 {
 {
     if (!current_process->attr.system)
     if (!current_process->attr.system)
-        kill_current(SIGILL);
+        kill_current(SIGILL); // noreturn
 
 
-    char buf[128] = {};
-    snprintf(buf, sizeof(buf),
-        "[kernel] int13 data: error_code: %x, cs: %x, eflags: %x\n",
-        error_code, cs, eflags);
-    kmsg(buf);
+    kmsgf("[kernel] int13: error_code: %llx, cs: %llx, rflags: %llx, rsp: %llx, ss: %llx",
+            error_code, cs, rflags, rsp, ss);
 
 
-    die(s_regs, eip);
+    die(s_regs, rip); // noreturn
 }
 }
 
 
 struct PACKED int14_data {
 struct PACKED int14_data {
     void* l_addr;
     void* l_addr;
-    struct regs_32 s_regs;
-    struct page_fault_error_code error_code;
+    regs_64 s_regs;
+    page_fault_error_code error_code;
     void* v_eip;
     void* v_eip;
     uint32_t cs;
     uint32_t cs;
     uint32_t eflags;
     uint32_t eflags;
 };
 };
 
 
-static inline void _int14_panic(void* eip, void* cr2, struct page_fault_error_code error_code)
+static inline void _int14_panic(
+        void* rip, void* cr2,
+        struct page_fault_error_code error_code)
 {
 {
-    char buf[128] = {};
-    snprintf(buf, sizeof(buf),
-        "[kernel] int14 data: eip: %p, cr2: %p, error_code: %x\n"
-        "[kernel] freezing...\n",
-        eip, cr2, error_code);
-    kmsg(buf);
+    kmsgf("[kernel] int14: rip: %p, cr2: %p, error_code: %llx",
+          rip, cr2, error_code);
     freeze();
     freeze();
 }
 }
 
 
@@ -287,8 +282,8 @@ extern "C" void int14_handler(int14_data* d)
     if (page->attr & PAGE_MMAP) {
     if (page->attr & PAGE_MMAP) {
         pte->in.p = 1;
         pte->in.p = 1;
 
 
-        size_t offset = align_down<12>((uint32_t)d->l_addr);
-        offset -= (uint32_t)mm_area->start;
+        size_t offset = align_down<12>((std::size_t)d->l_addr);
+        offset -= (std::size_t)mm_area->start;
 
 
         kernel::paccess pa(page->phys_page_id);
         kernel::paccess pa(page->phys_page_id);
         auto* data = (char*)pa.ptr();
         auto* data = (char*)pa.ptr();

+ 53 - 53
src/kernel/mem.cpp

@@ -134,16 +134,13 @@ static inline void init_mem_layout(void)
     mark_addr_range(0x00006000, 0x00008000);
     mark_addr_range(0x00006000, 0x00008000);
     // mark EBDA and upper memory as allocated
     // mark EBDA and upper memory as allocated
     mark_addr_range(0x80000, 0x100000);
     mark_addr_range(0x80000, 0x100000);
-    extern char __stage1_start[];
-    extern char __kinit_end[];
-    extern char __text_start[];
-    extern char __data_end[];
 
 
     constexpr pptr_t PHYS_BSS_START = 0x100000;
     constexpr pptr_t PHYS_BSS_START = 0x100000;
+    // TODO: LONG MODE
     // mark .stage1 and .kinit
     // mark .stage1 and .kinit
-    mark_addr_range((pptr_t)__stage1_start, (pptr_t)__kinit_end);
+    // mark_addr_range((pptr_t)__stage1_start, (pptr_t)__kinit_end);
     // mark kernel .text to .data
     // mark kernel .text to .data
-    mark_addr_len((pptr_t)__kinit_end, __data_end - __text_start);
+    // mark_addr_len((pptr_t)__kinit_end, __data_end - __text_start);
     // mark kernel .bss
     // mark kernel .bss
     mark_addr_len(PHYS_BSS_START, bss_len);
     mark_addr_len(PHYS_BSS_START, bss_len);
 
 
@@ -444,7 +441,7 @@ int mmap(
     }
     }
 
 
     // TODO: find another address
     // TODO: find another address
-    assert(((uint32_t)hint & 0xfff) == 0);
+    assert(((ptr_t)hint & 0xfff) == 0);
     // TODO: return failed
     // TODO: return failed
     assert((offset & 0xfff) == 0);
     assert((offset & 0xfff) == 0);
 
 
@@ -528,59 +525,62 @@ static types::bitmap freebm(
 
 
 void* kernel::pmap(page_t pg, bool cached)
 void* kernel::pmap(page_t pg, bool cached)
 {
 {
-    auto* const pmap_pt = std::bit_cast<pte_t*>(0xff001000);
-    auto* const mapped_start = std::bit_cast<void*>(0xff000000);
-
-    auto iter = __physmapper::mapped.find(pg);
-    if (iter) {
-        auto [ idx, area ] = *iter;
-        ++area.ref;
-        return area.ptr;
-    }
-
-    for (int i = 2; i < 0x400; ++i) {
-        if (__physmapper::freebm.test(i) == 0) {
-            auto* pte = pmap_pt + i;
-            if (cached)
-                pte->v = 0x3;
-            else
-                pte->v = 0x13;
-            pte->in.page = pg;
-
-            void* ptr = vptradd(mapped_start, 0x1000 * i);
-            invalidate_tlb(ptr);
-
-            __physmapper::freebm.set(i);
-            __physmapper::mapped.emplace(pg,
-                __physmapper::mapped_area { 1, ptr });
-            return ptr;
-        }
-    }
-
     return nullptr;
     return nullptr;
+    // TODO: LONG MODE
+    // auto* const pmap_pt = std::bit_cast<pte_t*>(0xff001000);
+    // auto* const mapped_start = std::bit_cast<void*>(0xff000000);
+
+    // auto iter = __physmapper::mapped.find(pg);
+    // if (iter) {
+    //     auto [ idx, area ] = *iter;
+    //     ++area.ref;
+    //     return area.ptr;
+    // }
+
+    // for (int i = 2; i < 0x400; ++i) {
+    //     if (__physmapper::freebm.test(i) == 0) {
+    //         auto* pte = pmap_pt + i;
+    //         if (cached)
+    //             pte->v = 0x3;
+    //         else
+    //             pte->v = 0x13;
+    //         pte->in.page = pg;
+
+    //         void* ptr = vptradd(mapped_start, 0x1000 * i);
+    //         invalidate_tlb(ptr);
+
+    //         __physmapper::freebm.set(i);
+    //         __physmapper::mapped.emplace(pg,
+    //             __physmapper::mapped_area { 1, ptr });
+    //         return ptr;
+    //     }
+    // }
+
+    // return nullptr;
 }
 }
 void kernel::pfree(page_t pg)
 void kernel::pfree(page_t pg)
 {
 {
-    auto* const pmap_pt = std::bit_cast<pte_t*>(0xff001000);
-    auto* const mapped_start = std::bit_cast<void*>(0xff000000);
+    // TODO: LONG MODE
+    // auto* const pmap_pt = std::bit_cast<pte_t*>(0xff001000);
+    // auto* const mapped_start = std::bit_cast<void*>(0xff000000);
 
 
-    auto iter = __physmapper::mapped.find(pg);
-    if (!iter)
-        return;
-    auto& [ ref, ptr ] = iter->second;
+    // auto iter = __physmapper::mapped.find(pg);
+    // if (!iter)
+    //     return;
+    // auto& [ ref, ptr ] = iter->second;
 
 
-    if (ref > 1) {
-        --ref;
-        return;
-    }
+    // if (ref > 1) {
+    //     --ref;
+    //     return;
+    // }
 
 
-    int i = vptrdiff(ptr, mapped_start);
-    i /= 0x1000;
+    // int i = vptrdiff(ptr, mapped_start);
+    // i /= 0x1000;
 
 
-    auto* pte = pmap_pt + i;
-    pte->v = 0;
-    invalidate_tlb(ptr);
+    // auto* pte = pmap_pt + i;
+    // pte->v = 0;
+    // invalidate_tlb(ptr);
 
 
-    __physmapper::freebm.clear(i);
-    __physmapper::mapped.remove(iter);
+    // __physmapper::freebm.clear(i);
+    // __physmapper::mapped.remove(iter);
 }
 }

+ 59 - 58
src/kernel/process.cpp

@@ -286,8 +286,9 @@ proclist::proclist()
 
 
     kernel::task::dispatcher::enqueue(current_thread);
     kernel::task::dispatcher::enqueue(current_thread);
 
 
-    tss.ss0 = KERNEL_DATA_SEGMENT;
-    tss.esp0 = (uint32_t)current_thread->kstack.esp;
+    // TODO: LONG MODE
+    // tss.ss0 = KERNEL_DATA_SEGMENT;
+    // tss.esp0 = (uint32_t)current_thread->kstack.esp;
 
 
     current_process->mms.switch_pd();
     current_process->mms.switch_pd();
 
 
@@ -300,25 +301,26 @@ proclist::proclist()
         auto& thd = *proc.thds.begin();
         auto& thd = *proc.thds.begin();
         thd.name.assign("[kernel thread daemon]");
         thd.name.assign("[kernel thread daemon]");
 
 
-        auto* esp = &thd.kstack.esp;
-        auto old_esp = (uint32_t)thd.kstack.esp;
-
-        // return(start) address
-        push_stack(esp, (uint32_t)kernel_threadd_main);
-        // ebx
-        push_stack(esp, 0);
-        // edi
-        push_stack(esp, 0);
-        // esi
-        push_stack(esp, 0);
-        // ebp
-        push_stack(esp, 0);
-        // eflags
-        push_stack(esp, 0x200);
-        // original esp
-        push_stack(esp, old_esp);
-
-        kernel::task::dispatcher::enqueue(&thd);
+        // TODO: LONG MODE
+        // auto* esp = &thd.kstack.esp;
+        // auto old_esp = (uint32_t)thd.kstack.esp;
+
+        // // return(start) address
+        // push_stack(esp, (uint32_t)kernel_threadd_main);
+        // // ebx
+        // push_stack(esp, 0);
+        // // edi
+        // push_stack(esp, 0);
+        // // esi
+        // push_stack(esp, 0);
+        // // ebp
+        // push_stack(esp, 0);
+        // // eflags
+        // push_stack(esp, 0x200);
+        // // original esp
+        // push_stack(esp, old_esp);
+
+        // kernel::task::dispatcher::enqueue(&thd);
     }
     }
 }
 }
 
 
@@ -391,9 +393,6 @@ void proclist::kill(pid_t pid, int exit_code)
 
 
 static void release_kinit()
 static void release_kinit()
 {
 {
-    extern char __stage1_start[];
-    extern char __kinit_end[];
-
     kernel::paccess pa(EARLY_KERNEL_PD_PAGE);
     kernel::paccess pa(EARLY_KERNEL_PD_PAGE);
     auto pd = (pd_t)pa.ptr();
     auto pd = (pd_t)pa.ptr();
     assert(pd);
     assert(pd);
@@ -403,10 +402,11 @@ static void release_kinit()
     __free_raw_page(0x00002);
     __free_raw_page(0x00002);
 
 
     // free .stage1 and .kinit
     // free .stage1 and .kinit
-    for (uint32_t i = ((uint32_t)__stage1_start >> 12);
-            i < ((uint32_t)__kinit_end >> 12); ++i) {
-        __free_raw_page(i);
-    }
+    // TODO: LONG MODE
+    // for (uint32_t i = ((uint32_t)__stage1_start >> 12);
+    //         i < ((uint32_t)__kinit_end >> 12); ++i) {
+    //     __free_raw_page(i);
+    // }
 }
 }
 
 
 void NORETURN _kernel_init(void)
 void NORETURN _kernel_init(void)
@@ -420,7 +420,7 @@ void NORETURN _kernel_init(void)
     // ------------------------------------------
     // ------------------------------------------
 
 
     // load kmods
     // load kmods
-    for (auto loader = kernel::module::kmod_loaders_start; *loader; ++loader) {
+    for (auto loader = kernel::module::KMOD_LOADERS_START; *loader; ++loader) {
         auto* mod = (*loader)();
         auto* mod = (*loader)();
         if (!mod)
         if (!mod)
             continue;
             continue;
@@ -474,17 +474,17 @@ void NORETURN _kernel_init(void)
     assert(ret == GB_OK);
     assert(ret == GB_OK);
 
 
     asm volatile(
     asm volatile(
-        "movw $0x23, %%ax\n"
-        "movw %%ax, %%ds\n"
-        "movw %%ax, %%es\n"
-        "movw %%ax, %%fs\n"
-        "movw %%ax, %%gs\n"
-
-        "pushl $0x23\n"
-        "pushl %0\n"
-        "pushl $0x200\n"
-        "pushl $0x1b\n"
-        "pushl %1\n"
+        "mov $0x23, %%ax\n"
+        "mov %%ax, %%ds\n"
+        "mov %%ax, %%es\n"
+        "mov %%ax, %%fs\n"
+        "mov %%ax, %%gs\n"
+
+        "push $0x23\n"
+        "push %0\n"
+        "push $0x200\n"
+        "push $0x1b\n"
+        "push %1\n"
 
 
         "iret\n"
         "iret\n"
         :
         :
@@ -507,22 +507,22 @@ void NORETURN init_scheduler(void)
     procs = new proclist;
     procs = new proclist;
 
 
     asm volatile(
     asm volatile(
-        "movl %0, %%esp\n"
-        "pushl %=f\n"
-        "pushl %1\n"
+        "mov %0, %%rsp\n"
+        "push %=f\n"
+        "push %1\n"
 
 
-        "movw $0x10, %%ax\n"
-        "movw %%ax, %%ss\n"
-        "movw %%ax, %%ds\n"
-        "movw %%ax, %%es\n"
-        "movw %%ax, %%fs\n"
-        "movw %%ax, %%gs\n"
+        "mov $0x10, %%ax\n"
+        "mov %%ax, %%ss\n"
+        "mov %%ax, %%ds\n"
+        "mov %%ax, %%es\n"
+        "mov %%ax, %%fs\n"
+        "mov %%ax, %%gs\n"
 
 
-        "xorl %%ebp, %%ebp\n"
-        "xorl %%edx, %%edx\n"
+        "xor %%ebp, %%ebp\n"
+        "xor %%edx, %%edx\n"
 
 
-        "pushl $0x0\n"
-        "popfl\n"
+        "push $0x0\n"
+        "popf\n"
 
 
         "ret\n"
         "ret\n"
 
 
@@ -556,13 +556,14 @@ bool schedule()
 
 
     curr_thd = current_thread;
     curr_thd = current_thread;
 
 
-    current_thread = next_thd;
-    tss.esp0 = (uint32_t)next_thd->kstack.esp;
+    // TODO: LONG MODE
+    // current_thread = next_thd;
+    // tss.esp0 = (uint32_t)next_thd->kstack.esp;
 
 
-    next_thd->load_thread_area();
+    // next_thd->load_thread_area();
 
 
-    asm_ctx_switch(&curr_thd->kstack.esp, &next_thd->kstack.esp);
-    tss.esp0 = (uint32_t)curr_thd->kstack.esp;
+    // asm_ctx_switch(&curr_thd->kstack.esp, &next_thd->kstack.esp);
+    // tss.esp0 = (uint32_t)curr_thd->kstack.esp;
 
 
 _end:
 _end:
 
 

+ 24 - 23
src/kernel/signal.cpp

@@ -178,29 +178,30 @@ void signal_list::handle(interrupt_stack* context, mmx_registers* mmxregs)
     if (!(handler.sa_flags & SA_RESTORER))
     if (!(handler.sa_flags & SA_RESTORER))
         raise(SIGSYS);
         raise(SIGSYS);
 
 
-    uint32_t esp = (uint32_t)context->esp;
-    esp -= (sizeof(mmx_registers) + sizeof(interrupt_stack) + 16);
-    esp &= 0xfffffff0;
-
-    auto tmpesp = esp;
-    *(uint32_t*)tmpesp = signal; // signal handler argument: int signo
-    tmpesp += 4;
-    *(uint32_t*)tmpesp = context->esp; // original esp
-    tmpesp += 4;
-
-    tmpesp += 8; // padding to align to 16 bytes
-
-    memcpy((void*)tmpesp, mmxregs, sizeof(mmx_registers));
-    tmpesp += sizeof(mmx_registers); // mmx registers
-    memcpy((void*)tmpesp, context, sizeof(interrupt_stack));
-    tmpesp += sizeof(interrupt_stack); // context
-
-    esp -= sizeof(void*);
-    // signal handler return address: restorer
-    *(uint32_t*)esp = (uint32_t)handler.sa_restorer;
-
-    context->esp = esp;
-    context->v_eip = (void*)handler.sa_handler;
+    // TODO: LONG MODE
+    // uint32_t esp = (uint32_t)context->esp;
+    // esp -= (sizeof(mmx_registers) + sizeof(interrupt_stack) + 16);
+    // esp &= 0xfffffff0;
+
+    // auto tmpesp = esp;
+    // *(uint32_t*)tmpesp = signal; // signal handler argument: int signo
+    // tmpesp += 4;
+    // *(uint32_t*)tmpesp = context->esp; // original esp
+    // tmpesp += 4;
+
+    // tmpesp += 8; // padding to align to 16 bytes
+
+    // memcpy((void*)tmpesp, mmxregs, sizeof(mmx_registers));
+    // tmpesp += sizeof(mmx_registers); // mmx registers
+    // memcpy((void*)tmpesp, context, sizeof(interrupt_stack));
+    // tmpesp += sizeof(interrupt_stack); // context
+
+    // esp -= sizeof(void*);
+    // // signal handler return address: restorer
+    // *(uint32_t*)esp = (uint32_t)handler.sa_restorer;
+
+    // context->esp = esp;
+    // context->v_eip = (void*)handler.sa_handler;
 }
 }
 
 
 void signal_list::after_signal(signo_type signal)
 void signal_list::after_signal(signo_type signal)

+ 12 - 11
src/kernel/syscall.cpp

@@ -72,21 +72,22 @@ int _syscall_fork(interrupt_stack* data)
 
 
     // create fake interrupt stack
     // create fake interrupt stack
     push_stack(esp, data->ss);
     push_stack(esp, data->ss);
-    push_stack(esp, data->esp);
-    push_stack(esp, data->eflags);
+    push_stack(esp, data->rsp);
+    push_stack(esp, data->flags);
     push_stack(esp, data->cs);
     push_stack(esp, data->cs);
-    push_stack(esp, (uint32_t)data->v_eip);
+    push_stack(esp, (uint64_t)data->v_rip);
 
 
+    // TODO: LONG MODE
     // eax
     // eax
-    push_stack(esp, 0);
-    push_stack(esp, data->s_regs.ecx);
+    // push_stack(esp, 0);
+    // push_stack(esp, data->s_regs.ecx);
     // edx
     // edx
-    push_stack(esp, 0);
-    push_stack(esp, data->s_regs.ebx);
-    push_stack(esp, data->s_regs.esp);
-    push_stack(esp, data->s_regs.ebp);
-    push_stack(esp, data->s_regs.esi);
-    push_stack(esp, data->s_regs.edi);
+    // push_stack(esp, 0);
+    // push_stack(esp, data->s_regs.ebx);
+    // push_stack(esp, data->s_regs.esp);
+    // push_stack(esp, data->s_regs.ebp);
+    // push_stack(esp, data->s_regs.esi);
+    // push_stack(esp, data->s_regs.edi);
 
 
     // ctx_switch stack
     // ctx_switch stack
     // return address
     // return address

+ 35 - 12
src/kinit.cpp

@@ -27,18 +27,19 @@ typedef void (*constructor)(void);
 extern constructor const SECTION(".rodata.kinit") start_ctors;
 extern constructor const SECTION(".rodata.kinit") start_ctors;
 extern constructor const SECTION(".rodata.kinit") end_ctors;
 extern constructor const SECTION(".rodata.kinit") end_ctors;
 
 
-extern struct mem_size_info SECTION(".stage1") asm_mem_size_info;
-extern uint8_t SECTION(".stage1") asm_e820_mem_map[1024];
-extern uint32_t SECTION(".stage1") asm_e820_mem_map_count;
-extern uint32_t SECTION(".stage1") asm_e820_mem_map_entry_size;
+// TODO: LONG MODE
+// extern struct mem_size_info SECTION(".stage1") asm_mem_size_info;
+// extern uint8_t SECTION(".stage1") asm_e820_mem_map[1024];
+// extern uint32_t SECTION(".stage1") asm_e820_mem_map_count;
+// extern uint32_t SECTION(".stage1") asm_e820_mem_map_entry_size;
 
 
 SECTION(".text.kinit")
 SECTION(".text.kinit")
 static inline void save_loader_data(void)
 static inline void save_loader_data(void)
 {
 {
-    memcpy(e820_mem_map, asm_e820_mem_map, sizeof(e820_mem_map));
-    e820_mem_map_count = asm_e820_mem_map_count;
-    e820_mem_map_entry_size = asm_e820_mem_map_entry_size;
-    memcpy(&mem_size_info, &asm_mem_size_info, sizeof(struct mem_size_info));
+    // memcpy(e820_mem_map, asm_e820_mem_map, sizeof(e820_mem_map));
+    // e820_mem_map_count = asm_e820_mem_map_count;
+    // e820_mem_map_entry_size = asm_e820_mem_map_entry_size;
+    // memcpy(&mem_size_info, &asm_mem_size_info, sizeof(struct mem_size_info));
 }
 }
 
 
 SECTION(".text.kinit")
 SECTION(".text.kinit")
@@ -49,7 +50,7 @@ static inline void load_new_gdt(void)
     create_segment_descriptor(gdt + 2, 0, ~0, 0b1100, SD_TYPE_DATA_SYSTEM);
     create_segment_descriptor(gdt + 2, 0, ~0, 0b1100, SD_TYPE_DATA_SYSTEM);
     create_segment_descriptor(gdt + 3, 0, ~0, 0b1100, SD_TYPE_CODE_USER);
     create_segment_descriptor(gdt + 3, 0, ~0, 0b1100, SD_TYPE_CODE_USER);
     create_segment_descriptor(gdt + 4, 0, ~0, 0b1100, SD_TYPE_DATA_USER);
     create_segment_descriptor(gdt + 4, 0, ~0, 0b1100, SD_TYPE_DATA_USER);
-    create_segment_descriptor(gdt + 5, (uint32_t)&tss, sizeof(tss), 0b0000, SD_TYPE_TSS);
+    create_segment_descriptor(gdt + 5, (std::size_t)&tss, sizeof(tss), 0b0000, SD_TYPE_TSS);
     create_segment_descriptor(gdt + 6, 0, 0, 0b1100, SD_TYPE_DATA_USER);
     create_segment_descriptor(gdt + 6, 0, 0, 0b1100, SD_TYPE_DATA_USER);
 
 
     asm_load_gdt((7 * 8 - 1) << 16, (pptr_t)gdt);
     asm_load_gdt((7 * 8 - 1) << 16, (pptr_t)gdt);
@@ -104,9 +105,30 @@ static void init_uname()
 
 
 } // namespace kernel::kinit
 } // namespace kernel::kinit
 
 
-extern "C" SECTION(".text.kinit") void NORETURN kernel_init(void)
+struct PACKED bootloader_data {
+    uint32_t meminfo_entry_count;
+    uint32_t meminfo_entry_size;
+    std::byte data[1024 - 2*4];
+};
+
+extern "C" SECTION(".text.kinit")
+void NORETURN kernel_init(bootloader_data* data)
 {
 {
-    asm_enable_sse();
+    // enable SSE
+    asm volatile(
+            "mov %%cr0, %%rax\n\t"
+            "and $(~0xc), %%rax\n\t"
+            "or $0x22, %%rax\n\t"
+            "mov %%rax, %%cr0\n\t"
+            "\n\t"
+            "mov %%cr4, %%rax\n\t"
+            "or $0x600, %%rax\n\t"
+            "mov %%rax, %%cr4\n\t"
+            "fninit\n\t"
+            ::: "rax"
+            );
+
+    int a = data->meminfo_entry_count;
 
 
     init_bss_section();
     init_bss_section();
 
 
@@ -137,7 +159,8 @@ extern "C" SECTION(".text.kinit") void NORETURN kernel_init(void)
 
 
     kernel::kinit::init_pci();
     kernel::kinit::init_pci();
     init_vfs();
     init_vfs();
-    init_syscall();
+    // TODO: LONG MODE
+    // init_syscall();
 
 
     kmsg("switching execution to the scheduler...\n");
     kmsg("switching execution to the scheduler...\n");
     init_scheduler();
     init_scheduler();

+ 152 - 59
src/mbr.S

@@ -1,79 +1,172 @@
-.section .text.bootsect
+.section .mbr
 .code16
 .code16
 
 
-.globl mbr_start
-mbr_start:
-    movw %cs, %ax
-    movw %ax, %ds
-    movw %ax, %es
-    movw %ax, %ss
-
-# perform a temporary stack
-    movw $stack_base, %ax
-    movw %ax, %bp
-    movw %ax, %sp
-
-# read the first 64k
-    call read_data
-
-# read the following 128k
-    addw $(0x100 * 16), read_data_segment
-    addl $(8 * 16), read_data_lba
-    call read_data
-
-    addw $(0x100 * 16), read_data_segment
-    addl $(8 * 16), read_data_lba
-    call read_data
-
-# read the 128k more
-    addw $(0x100 * 16), read_data_segment
-    addl $(8 * 16), read_data_lba
-    call read_data
-
-    addw $(0x100 * 16), read_data_segment
-    addl $(8 * 16), read_data_lba
-    call read_data
-
-# read 64k more
-    addw $(0x100 * 16), read_data_segment
-    addl $(8 * 16), read_data_lba
-    call read_data
-
-# loader start
-    jmp 0x8000
-
-read_data:
-    movw $read_data_pack, %si
+move_mbr:
+    xor %ax, %ax
+    mov %ax, %ds
+    mov %ax, %es
+    mov %ax, %ss
+
+    # build a temporary stack
+    mov $0x0e00, %esp
+    mov %esp, %ebp
+
+    mov $128, %cx # 512 / 4
+    mov $0x7c00, %si
+    mov $0x0e00, %di
+    rep movsl
+
+    ljmp $0x00, $mbr_start
+
+# %eax: lba lower 4bytes
+# %edx: destination address
+read_disk:
+	push %eax
+	push %edx
+	push %ecx
+
+	mov %eax, read_data_lba
+	shr $4, %edx
+	mov %dx, read_data_segment
+
+    mov $read_data_pack, %si
     mov $0x42, %ah
     mov $0x42, %ah
     mov $0x80, %dl
     mov $0x80, %dl
     int $0x13
     int $0x13
-    jc read_data_error
-    ret
+    jc halt
+
+	pop %ecx
+	pop %edx
+	pop %eax
+	ret
+
+mbr_start:
+    # clear screen
+    mov $0x00, %ah
+    mov $0x03, %al
+    int $0x10
+
+    # read kernel image: 32K * 15 = 480K
+	xor %eax, %eax
+	inc %eax # %eax = 1
+	mov %eax, %edx
+	shl $12, %edx # %edx = 0x1000
+
+	mov $15, %ecx
+_loop_read_kernel:
+	call read_disk
+	add $64, %eax # %eax += 64
+
+	shr $12, %edx
+	add $8, %edx
+	shl $12, %edx # %edx += 32K
+
+	loop _loop_read_kernel
+
+    # get memory size info and storage it
+    xor %ecx, %ecx
+    xor %edx, %edx
+	xor %eax, %eax
+    mov $0xe801, %ax
+
+    int $0x15
+    jc halt
+
+    cmp $0x86, %ah # unsupported function
+    je halt
+    cmp $0x80, %ah # invalid command
+    je halt
+
+    jcxz _get_memory_size_use_ax
+    mov %cx, %ax
+    mov %dx, %bx
+
+_get_memory_size_use_ax:
+    sub $1024, %esp
+    movzwl %ax, %eax
+    mov %eax, 8(%esp)  # 1k blocks
+    movzwl %bx, %ebx
+    mov %ebx, 12(%esp) # 64k blocks
+
+    # save the destination address to es:di
+    lea 16(%esp), %di # buffer is 1024 - 16 bytes
 
 
-read_data_error:
+    # clear %ebx, len
+    xor %ebx, %ebx
+    mov %ebx, (%esp)
+
+    # set default entry size
+    movl $20, 4(%esp)
+
+_e820_mem_map_load_loop:
+    # set the magic number to edx
+    mov $0x534D4150, %edx
+
+    # set function number to eax
+    mov $0xe820, %eax
+
+    # set default entry size
+    mov $24, %ecx
+
+    int $0x15
+
+    incl (%esp)
+    add $24, %edi
+
+    jc _e820_mem_map_load_fin
+    cmp $0, %ebx
+    jz _e820_mem_map_load_fin
+
+    cmp $24, %ecx
+    cmovnz 4(%esp), %ecx
+    mov %ecx, 4(%esp)
+
+    jmp _e820_mem_map_load_loop
+
+_e820_mem_map_load_fin:
+    # load GDT and IDT
+    cli
+    lidt null_idt_descriptor
+    lgdt _32bit_gdt_descriptor
+
+    # enable protection enable (PE) bit
+    mov %cr0, %eax
+    or $1, %eax
+    mov %eax, %cr0
+
+    ljmp $0x08, $start_32bit
+
+halt:
     hlt
     hlt
-    jmp read_data_error
+    jmp halt
 
 
-.align 4
+.align 16
 read_data_pack:
 read_data_pack:
     .byte 0x10, 0
     .byte 0x10, 0
 read_data_count:
 read_data_count:
-    .word 128    # sector count (read 64k)
+    .word 64     # sector count (read 32k)
 read_data_offset:
 read_data_offset:
     .word 0x0000 # offset address
     .word 0x0000 # offset address
 read_data_segment:
 read_data_segment:
-    .word 0x0800 # segment address
+    .word 0x0100 # segment address
 read_data_lba:
 read_data_lba:
     .long 1      # lower 4 bytes of the LBA to read
     .long 1      # lower 4 bytes of the LBA to read
     .long 0      # higher 2 bytes of the LBA to read
     .long 0      # higher 2 bytes of the LBA to read
 
 
-__mbr_code_border__:
-    .long 0xffffffff
+# null IDT descriptor
+# so that exceptions will cause the system to reset
+.align 4
+null_idt_descriptor:
+    .word 0 # size
+    .long 0 # base
 
 
-.align 16
-stack_edge:
-.space 128
-stack_base:
+.align 4
+_32bit_gdt_descriptor:
+    .word (3 * 8) - 1 # size
+    .long _32bit_gdt  # address
 
 
-. = 510
-.byte 0x55, 0xaa
+.align 16
+_32bit_gdt:
+    .8byte 0x0                # null selector
+    .8byte 0x00cf9a000000ffff # code selector
+    .8byte 0x00cf92000000ffff # data selector

+ 0 - 15
src/mbr.ld

@@ -1,15 +0,0 @@
-OUTPUT_FORMAT(binary)
-OUTPUT_ARCH(i386:i386)
-
-SECTIONS
-{
-    .text 0x7c00 :
-    {
-        *(.text.bootsect)
-    }
-
-    /DISCARD/ :
-    {
-        *(.note*)
-    }
-}

+ 4 - 1
src/types/elf.cpp

@@ -26,7 +26,10 @@ inline void _user_push(char** sp, const char* str)
 {
 {
     size_t len = strlen(str);
     size_t len = strlen(str);
     *sp -= (len + 1);
     *sp -= (len + 1);
-    align16_down(*sp);
+    size_t nsp = (size_t)sp;
+    size_t mask = 0xf;
+    nsp &= ~mask;
+    *sp = std::bit_cast<char*>(nsp);
     memcpy(*sp, str, len + 1);
     memcpy(*sp, str, len + 1);
 }
 }
 
 

+ 2 - 3
user-space-program/CMakeLists.txt

@@ -1,11 +1,10 @@
 cmake_minimum_required(VERSION 3.15)
 cmake_minimum_required(VERSION 3.15)
 project(user_space_program C ASM)
 project(user_space_program C ASM)
 
 
-set(CMAKE_C_FLAGS "-nostdlib -nostdinc -static -m32 -W -Wall -Wextra -Werror -mstack-protector-guard=global")
-set(CMAKE_ASM_FLAGS "-nostdlib -m32 -static -mstack-protector-guard=global -g0")
+set(CMAKE_C_FLAGS "-nostdlib -nostdinc -static -W -Wall -mstack-protector-guard=global")
+set(CMAKE_ASM_FLAGS "-nostdlib -static -mstack-protector-guard=global")
 
 
 link_libraries(gblibc crt0)
 link_libraries(gblibc crt0)
-add_link_options("LINKER:-melf_i386")
 
 
 set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "")
 set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "")
 set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "")
 set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "")