diff options
author | Raghuram Subramani <raghus2247@gmail.com> | 2025-02-02 10:37:08 -0500 |
---|---|---|
committer | Raghuram Subramani <raghus2247@gmail.com> | 2025-02-02 10:38:56 -0500 |
commit | 6b76eb48066a5fb0c45b108fd3eed1743029da4f (patch) | |
tree | 126a4263c395a2b83e117fd8703e1dbeb96edcbc | |
parent | c216a2000179a133e1e38852f55261f4bf9f08f6 (diff) |
build: Use the custom linker and nasm
-rw-r--r-- | cmake/toolchain.cmake | 12 | ||||
-rw-r--r-- | kernel/CMakeLists.txt | 33 | ||||
-rw-r--r-- | kernel/boot/gdt/gdt.s | 49 | ||||
-rw-r--r-- | kernel/boot/init/boot.s | 192 | ||||
-rw-r--r-- | kernel/boot/init/crti.s | 54 | ||||
-rw-r--r-- | kernel/boot/init/crtn.s | 44 |
6 files changed, 183 insertions, 201 deletions
diff --git a/cmake/toolchain.cmake b/cmake/toolchain.cmake index 716b5e7..5107848 100644 --- a/cmake/toolchain.cmake +++ b/cmake/toolchain.cmake @@ -1,8 +1,18 @@ set(CMAKE_C_COMPILER clang) set(CMAKE_CXX_COMPILER clang++) +set(CMAKE_LINKER ld.lld) set(CMAKE_ASM_COMPILER nasm) +# Hacky, yes. +set(CMAKE_CXX_LINK_EXECUTABLE + "<CMAKE_LINKER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>" +) + +set(CMAKE_ASM_NASM_COMPILER /usr/bin/nasm) +set(CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS s) +set(CMAKE_ASM_NASM_OBJECT_FORMAT elf) -set(CMAKE_SYSTEM_PROCESSOR i686) set(CMAKE_C_COMPILER_TARGET i686-elf) set(CMAKE_CXX_COMPILER_TARGET i686-elf) set(CMAKE_ASM_COMPILER_TARGET i686-elf) + +set(CMAKE_SYSTEM_PROCESSOR i686) diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index bab610e..3af9102 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -1,7 +1,9 @@ cmake_minimum_required(VERSION 3.21) -project(kernel C ASM) +project(kernel C ASM_NASM) set(SRC + boot/init/crti.s + boot/gdt/gdt.cc boot/gdt/gdt.s boot/init/boot.s @@ -25,6 +27,8 @@ set(SRC mm/physical_mm/physical_mm.cc mm/virtual_mm/virtual_mm.cc mm/virtual_mm/pages.cc + + boot/init/crtn.s ) add_executable(kernel ${SRC}) @@ -62,32 +66,7 @@ target_compile_options(kernel PRIVATE ) set(LINKER_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/boot/linker.ld") -set(LINKER_FLAGS +target_link_options(kernel PRIVATE -T ${LINKER_SCRIPT} -nostdlib - -fuse-ld=lld - --target=i686-elf ) - -add_library(crti OBJECT boot/init/crti.s) -add_library(crtn OBJECT boot/init/crtn.s) -add_dependencies(kernel crti crtn) - -get_target_property(CRTI_SRC crti SOURCES) -get_target_property(CRTN_SRC crtn SOURCES) -get_target_property(CRTI_OUT crti BINARY_DIR) -get_target_property(CRTN_OUT crtn BINARY_DIR) - -set(CRTI_O "${CRTI_OUT}/CMakeFiles/crti.dir/${CRTI_SRC}.o") -set(CRTN_O "${CRTN_OUT}/CMakeFiles/crtn.dir/${CRTN_SRC}.o") - -# FIXME: This isn't a good way of setting the link order. -set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_COMPILER} <CMAKE_CXX_LINK_FLAGS> <FLAGS> <LINK_FLAGS> \ - ${CRTI_O} \ - <OBJECTS> \ - ${CRTN_O} \ - -o <TARGET> <LINK_LIBRARIES>" -) - -target_link_options(kernel PRIVATE ${LINKER_FLAGS}) -target_link_libraries(kernel PRIVATE gcc) diff --git a/kernel/boot/gdt/gdt.s b/kernel/boot/gdt/gdt.s index d1d768c..73ebed1 100644 --- a/kernel/boot/gdt/gdt.s +++ b/kernel/boot/gdt/gdt.s @@ -1,24 +1,41 @@ -.global _GDT_flush -.type _GDT_flush, @function +;; +;; bubbl +;; Copyright (C) 2024-2025 Raghuram Subramani <raghus2247@gmail.com> +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. +;; + +global _GDT_flush _GDT_flush: - /* First Argument (Pointer to the GDT) */ - movl 4(%esp), %eax + ;; First Argument (Pointer to the GDT) + mov eax, [esp + 4] - /* Load GDT */ - lgdt (%eax) + ;; Load GDT + lgdt [eax] - /* Offset For Kernel Data Segment (16 bits) */ - mov $0x10, %eax + ;; Offset For Kernel Data Segment (16 bits) + mov eax, 0x10 - /* Set the Data Segment Selectors */ - mov %ax, %ds - mov %ax, %es - mov %ax, %fs - mov %ax, %gs - mov %ax, %ss + ;; Set the Data Segment Selectors + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax - /* Set the Code Segment Selector */ - jmp $0x08, $.flush + ;; Set the Code Segment Selector + jmp 0x08:.flush .flush: ret diff --git a/kernel/boot/init/boot.s b/kernel/boot/init/boot.s index 8a134c4..c558c97 100644 --- a/kernel/boot/init/boot.s +++ b/kernel/boot/init/boot.s @@ -1,120 +1,102 @@ -/* - * bubbl - * Copyright (C) 2024-2025 Raghuram Subramani <raghus2247@gmail.com> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ +;; +;; bubbl +;; Copyright (C) 2024-2025 Raghuram Subramani <raghus2247@gmail.com> +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. +;; -/* Adapted from https://wiki.osdev.org/Bare_Bones */ +;; Adapted from https://wiki.osdev.org/Bare_Bones -/* Declare constants for the multiboot header. */ -.set ALIGN, 1<<0 /* align loaded modules on page boundaries */ -.set MEMINFO, 1<<1 /* provide memory map */ -.set FLAGS, ALIGN | MEMINFO /* this is the Multiboot 'flag' field */ -.set MAGIC, 0x1BADB002 /* 'magic number' lets bootloader find the header */ -.set CHECKSUM, -(MAGIC + FLAGS) /* checksum of above, to prove we are multiboot */ +MBALIGN equ 1 << 0 ;; align loaded modules on page boundaries +MEMINFO equ 1 << 1 ;; provide memory map +MBFLAGS equ MBALIGN | MEMINFO ;; this is the Multiboot 'flag' field +MAGIC equ 0x1BADB002 ;; 'magic number' lets bootloader find the header +CHECKSUM equ -(MAGIC + MBFLAGS) ;; checksum of above, to prove we are multiboot -/* - Declare a multiboot header that marks the program as a kernel. These are magic - values that are documented in the multiboot standard. The bootloader will - search for this signature in the first 8KiB of the kernel file, aligned at a - 32-bit boundary. The signature is in its own section so the header can be - forced to be within the first 8KiB of the kernel file. -*/ -.section .multiboot -.align 4 -.long MAGIC -.long FLAGS -.long CHECKSUM +; Declare a multiboot header that marks the program as a kernel. These are magic +; values that are documented in the multiboot standard. The bootloader will +; search for this signature in the first 8 KiB of the kernel file, aligned at a +; 32-bit boundary. The signature is in its own section so the header can be +; forced to be within the first 8 KiB of the kernel file. +section .multiboot +align 4 +dd MAGIC +dd MBFLAGS +dd CHECKSUM -/* - The multiboot standard does not define the value of the stack pointer register - (esp) and it is up to the kernel to provide a stack. This allocates room for a - small stack by creating a symbol at the bottom of it, then allocating 16384 - bytes for it, and finally creating a symbol at the top. The stack grows - downwards on x86. The stack is in its own section so it can be marked nobits, - which means the kernel file is smaller because it does not contain an - uninitialized stack. The stack on x86 must be 16-byte aligned according to the - System V ABI standard and de-facto extensions. The compiler will assume the - stack is properly aligned and failure to align the stack will result in - undefined behavior. -*/ -.section .bss -.align 16 +;; The multiboot standard does not define the value of the stack pointer register +;; (esp) and it is up to the kernel to provide a stack. This allocates room for a +;; small stack by creating a symbol at the bottom of it, then allocating 16384 +;; bytes for it, and finally creating a symbol at the top. The stack grows +;; downwards on x86. The stack is in its own section so it can be marked nobits, +;; which means the kernel file is smaller because it does not contain an +;; uninitialized stack. The stack on x86 must be 16-byte aligned according to the +;; System V ABI standard and de-facto extensions. The compiler will assume the +;; stack is properly aligned and failure to align the stack will result in +;; undefined behavior. + +section .bss +align 16 stack_bottom: -.skip 16384 # 16KiB +resb 16384 ;;16KiB stack_top: -/* - The linker script specifies _start as the entry point to the kernel and the - bootloader will jump to this position once the kernel has been loaded. It - doesn't make sense to return from this function as the bootloader is gone. -*/ -.section .text -.global _start -.type _start, @function +;; The linker script specifies _start as the entry point to the kernel and the +;; bootloader will jump to this position once the kernel has been loaded. It +;; doesn't make sense to return from this function as the bootloader is gone. +section .text +global _start _start: - /* - The bootloader has loaded us into 32-bit protected mode on a x86 - machine. Interrupts are disabled. Paging is disabled. The processor - state is as defined in the multiboot standard. The kernel has full - control of the CPU. The kernel can only make use of hardware features - and any code it provides as part of itself. There's no printf - function, unless the kernel provides its own <stdio.h> header and a - printf implementation. There are no security restrictions, no - safeguards, no debugging mechanisms, only what the kernel provides - itself. It has absolute and complete power over the - machine. - */ + ;; The bootloader has loaded us into 32-bit protected mode on a x86 + ;; machine. Interrupts are disabled. Paging is disabled. The processor + ;; state is as defined in the multiboot standard. The kernel has full + ;; control of the CPU. The kernel can only make use of hardware features + ;; and any code it provides as part of itself. There's no printf + ;; function, unless the kernel provides its own <stdio.h> header and a + ;; printf implementation. There are no security restrictions, no + ;; safeguards, no debugging mechanisms, only what the kernel provides + ;; itself. It has absolute and complete power over the + ;; machine. - /* - To set up a stack, we set the esp register to point to the top of the - stack (as it grows downwards on x86 systems). This is necessarily done - in assembly as languages such as C cannot function without a stack. - */ - movl $stack_top, %esp + ;; To set up a stack, we set the esp register to point to the top of the + ;; stack (as it grows downwards on x86 systems). This is necessarily done + ;; in assembly as languages such as C cannot function without a stack. + mov esp, stack_top - /* Push Multiboot values to stack for kernel_main */ - push %ebx - push %eax + ;; Push Multiboot values to stack for kernel_main + push ebx + push eax - /* - This is a good place to initialize crucial processor state before the - high-level kernel is entered. It's best to minimize the early - environment where crucial features are offline. Note that the - processor is not fully initialized yet: Features such as floating - point instructions and instruction set extensions are not initialized - yet. The GDT should be loaded here. Paging should be enabled here. - C++ features such as global constructors and exceptions will require - runtime support to work as well. - */ + ;; + ;; This is a good place to initialize crucial processor state before the + ;; high-level kernel is entered. It's best to minimize the early + ;; environment where crucial features are offline. Note that the + ;; processor is not fully initialized yet: Features such as floating + ;; point instructions and instruction set extensions are not initialized + ;; yet. The GDT should be loaded here. Paging should be enabled here. + ;; C++ features such as global constructors and exceptions will require + ;; runtime support to work as well. - /* Call the global constructors. */ + ;; Call the global constructors. + extern _init call _init - /* - Enter the high-level kernel. The ABI requires the stack is 16-byte - aligned at the time of the call instruction (which afterwards pushes - the return pointer of size 4 bytes). The stack was originally 16-byte - aligned above and we've pushed a multiple of 16 bytes to the - stack since (pushed 0 bytes so far), so the alignment has thus been - preserved and the call is well defined. - */ + ;; Enter the high-level kernel. The ABI requires the stack is 16-byte + ;; aligned at the time of the call instruction (which afterwards pushes + ;; the return pointer of size 4 bytes). The stack was originally 16-byte + ;; aligned above and we've pushed a multiple of 16 bytes to the + ;; stack since (pushed 0 bytes so far), so the alignment has thus been + ;; preserved and the call is well defined. + extern kernel_main call kernel_main - -/* -Set the size of the _start symbol to the current location '.' minus its start. -This is useful when debugging or when you implement call tracing. -*/ -.size _start, . - _start diff --git a/kernel/boot/init/crti.s b/kernel/boot/init/crti.s index 8f86ffa..e3ddc32 100644 --- a/kernel/boot/init/crti.s +++ b/kernel/boot/init/crti.s @@ -1,33 +1,29 @@ -/* - * bubbl - * Copyright (C) 2024-2025 Raghuram Subramani <raghus2247@gmail.com> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ +;; +;; bubbl +;; Copyright (C) 2024-2025 Raghuram Subramani <raghus2247@gmail.com> +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. +;; -.section .init -.global _init -.type _init, @function +section .init +global _init _init: - push %ebp - mov %esp, %ebp - /* gcc will nicely put the contents of crtbegin.o's .init section here. */ + push ebp + mov ebp, esp -.section .fini -.global _fini -.type _fini, @function +section .fini +global _fini _fini: - push %ebp - mov %esp, %ebp - /* gcc will nicely put the contents of crtbegin.o's .fini section here. */ + push ebp + mov ebp, esp diff --git a/kernel/boot/init/crtn.s b/kernel/boot/init/crtn.s index 8a20b9e..d585bfe 100644 --- a/kernel/boot/init/crtn.s +++ b/kernel/boot/init/crtn.s @@ -1,27 +1,25 @@ -/* - * bubbl - * Copyright (C) 2024-2025 Raghuram Subramani <raghus2247@gmail.com> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ +;; +;; bubbl +;; Copyright (C) 2024-2025 Raghuram Subramani <raghus2247@gmail.com> +;; +;; This program is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. +;; -.section .init - /* gcc will nicely put the contents of crtend.o's .init section here. */ - popl %ebp +section .init + pop ebp ret -.section .fini - /* gcc will nicely put the contents of crtend.o's .fini section here. */ - popl %ebp +section .fini + pop ebp ret |