Setup simple kernel with Hello World output via debugcon (AI)

This commit is contained in:
AI
2026-02-23 08:24:50 +00:00
parent 34382babb3
commit a048764a3d
6 changed files with 101 additions and 6 deletions

View File

@@ -4,9 +4,9 @@ project(ClaudeOS C ASM)
set(CMAKE_C_STANDARD 99)
# We are building a kernel, so we don't want standard libraries
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffreestanding -m32 -g -O2 -Wall -Wextra")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -m32")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32 -nostdlib")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffreestanding -m32 -fno-pie -fno-pic -fno-builtin -fno-stack-protector -g -O2 -Wall -Wextra")
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -m32 -fno-pie -fno-pic")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32 -nostdlib -no-pie")
# Define build output directory
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

View File

@@ -39,7 +39,7 @@ Once a task is completed, it should be checked off.
- [x] Create directory structure
- [x] Create initial build system
- [ ] Setup a simple kernel that writes `Hello, world` to Qemu debug port
- [x] Setup a simple kernel that writes `Hello, world` to Qemu debug port
- [ ] Update the build system to create both ISO and Floppy images. Verify these work using a test script. The standard CMake build target should automatically generate both images.
- [ ] Update the kernel to correctly setup the GDT
- [ ] Create a physical memory allocator and mapper. The kernel should live in the upper last gigabyte of virtual memory. It should support different zones (e.g.: `SUB_16M`, `DEFAULT`, ...) These zones describe the region of memory that memory should be allocated in. If it is not possible to allocate in that region (because it is full, or has 0 capacity to begin with), it should fallback to another zone.

1
output.txt Normal file
View File

@@ -0,0 +1 @@
Hello, world

View File

@@ -1,6 +1,7 @@
cmake_minimum_required(VERSION 3.16)
add_executable(kernel
boot.S
kernel.c
)

65
src/boot.S Normal file
View File

@@ -0,0 +1,65 @@
#define ASM_FILE
#include <multiboot2.h>
/* Multiboot 1 header constants */
.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 */
.section .multiboot
.align 4
multiboot1_header:
.long MAGIC
.long FLAGS
.long CHECKSUM
.align 8
multiboot_header:
/* magic */
.long MULTIBOOT2_HEADER_MAGIC
/* architecture: 0 (protected mode i386) */
.long MULTIBOOT_ARCHITECTURE_I386
/* header length */
.long multiboot_header_end - multiboot_header
/* checksum */
.long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (multiboot_header_end - multiboot_header))
/* Tags here */
/* End tag */
.short MULTIBOOT_HEADER_TAG_END
.short 0
.long 8
multiboot_header_end:
.section .bss
.align 16
stack_bottom:
.skip 16384 # 16 KiB
stack_top:
.section .text
.global _start
.type _start, @function
_start:
/* Set up stack */
mov $stack_top, %esp
/* Reset EFLAGS */
push $0
popf
/* Push magic and multiboot info pointer onto stack for kernel_main */
/* Multiboot2 puts magic in EAX, pointer in EBX */
push %ebx
push %eax
call kernel_main
cli
1: hlt
jmp 1b
.size _start, . - _start

View File

@@ -1,3 +1,31 @@
void _start() {
while(1) {}
#include <multiboot2.h>
#include <stdint.h>
#include <stddef.h>
static inline void outb(uint16_t port, uint8_t val)
{
asm volatile ( "outb %b0, %w1" : : "a"(val), "Nd"(port) );
}
void offset_print(const char *str)
{
while (*str) {
outb(0xE9, *str);
str++;
}
}
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
void kernel_main(uint32_t magic, uint32_t addr) {
(void)addr; // Unused for now
if (magic != MULTIBOOT2_BOOTLOADER_MAGIC && magic != MULTIBOOT_BOOTLOADER_MAGIC) {
offset_print("Invalid magic number: ");
// I don't have hex print yet, but I can print something generic
offset_print("Unknown\n");
return;
}
offset_print("Hello, world\n");
}