aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaghuram Subramani <raghus2247@gmail.com>2025-02-02 10:37:08 -0500
committerRaghuram Subramani <raghus2247@gmail.com>2025-02-02 10:38:56 -0500
commit6b76eb48066a5fb0c45b108fd3eed1743029da4f (patch)
tree126a4263c395a2b83e117fd8703e1dbeb96edcbc
parentc216a2000179a133e1e38852f55261f4bf9f08f6 (diff)
build: Use the custom linker and nasm
-rw-r--r--cmake/toolchain.cmake12
-rw-r--r--kernel/CMakeLists.txt33
-rw-r--r--kernel/boot/gdt/gdt.s49
-rw-r--r--kernel/boot/init/boot.s192
-rw-r--r--kernel/boot/init/crti.s54
-rw-r--r--kernel/boot/init/crtn.s44
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