Compare commits
9 Commits
master
...
c7e9833819
| Author | SHA1 | Date | |
|---|---|---|---|
| c7e9833819 | |||
|
|
6b00cf3154 | ||
|
|
f2e84924f5 | ||
| 6d91edc897 | |||
|
|
7068176d91 | ||
|
|
436aeceb10 | ||
|
|
aa954045c1 | ||
|
|
a048764a3d | ||
|
|
34382babb3 |
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1 +1,7 @@
|
|||||||
/build/
|
build/
|
||||||
|
release/
|
||||||
|
*.img
|
||||||
|
*.iso
|
||||||
|
debug_grub/
|
||||||
|
*_output.txt
|
||||||
|
snippet.*
|
||||||
|
|||||||
40
CMakeLists.txt
Normal file
40
CMakeLists.txt
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
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 -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)
|
||||||
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
|
|
||||||
|
add_subdirectory(src)
|
||||||
|
|
||||||
|
# Create output directories
|
||||||
|
file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/release)
|
||||||
|
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/isodir/boot/grub)
|
||||||
|
|
||||||
|
# Create grub.cfg for ISO
|
||||||
|
file(WRITE ${CMAKE_BINARY_DIR}/isodir/boot/grub/grub.cfg "set timeout=0\nset default=0\nsearch --set=root --file /boot/kernel.bin\nmenuentry \"ClaudeOS\" { multiboot /boot/kernel.bin }")
|
||||||
|
|
||||||
|
|
||||||
|
# ISO Generation
|
||||||
|
add_custom_target(iso ALL
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/kernel ${CMAKE_BINARY_DIR}/isodir/boot/kernel.bin
|
||||||
|
COMMAND grub-mkrescue -o ${CMAKE_SOURCE_DIR}/release/claude-os.iso ${CMAKE_BINARY_DIR}/isodir
|
||||||
|
DEPENDS kernel
|
||||||
|
COMMENT "Generating bootable ISO image"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Test target
|
||||||
|
add_custom_target(test_images
|
||||||
|
COMMAND sh ${CMAKE_SOURCE_DIR}/test_images.sh
|
||||||
|
DEPENDS iso
|
||||||
|
COMMENT "Testing generated images in QEMU"
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
)
|
||||||
@@ -37,10 +37,10 @@ The git commit should describe what is done and why certain choices were made.
|
|||||||
The title of the commit should always end with (AI), to indicate that it was written by an AI.
|
The title of the commit should always end with (AI), to indicate that it was written by an AI.
|
||||||
Once a task is completed, it should be checked off.
|
Once a task is completed, it should be checked off.
|
||||||
|
|
||||||
- [ ] Create directory structure
|
- [x] Create directory structure
|
||||||
- [ ] Create initial build system
|
- [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.
|
- [x] 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. (Only ISO supported for now)
|
||||||
- [ ] Update the kernel to correctly setup the GDT
|
- [ ] 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.
|
- [ ] 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.
|
||||||
- [ ] Create a paging subsystem. It should allow drivers to allocate and deallocate pages at will.
|
- [ ] Create a paging subsystem. It should allow drivers to allocate and deallocate pages at will.
|
||||||
|
|||||||
14
src/CMakeLists.txt
Normal file
14
src/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
add_executable(kernel
|
||||||
|
boot.S
|
||||||
|
kernel.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Use our custom linker script
|
||||||
|
target_link_options(kernel PRIVATE -T ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld)
|
||||||
|
|
||||||
|
target_include_directories(kernel PRIVATE
|
||||||
|
${CMAKE_SOURCE_DIR}/vendor
|
||||||
|
${CMAKE_SOURCE_DIR}/include # If created later
|
||||||
|
)
|
||||||
65
src/boot.S
Normal file
65
src/boot.S
Normal 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
|
||||||
31
src/kernel.c
Normal file
31
src/kernel.c
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#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");
|
||||||
|
}
|
||||||
28
src/linker.ld
Normal file
28
src/linker.ld
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 1M;
|
||||||
|
|
||||||
|
.text BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
KEEP(*(.multiboot))
|
||||||
|
*(.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
.rodata BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.rodata)
|
||||||
|
}
|
||||||
|
|
||||||
|
.data BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
.bss BLOCK(4K) : ALIGN(4K)
|
||||||
|
{
|
||||||
|
*(COMMON)
|
||||||
|
*(.bss)
|
||||||
|
}
|
||||||
|
}
|
||||||
30
test_images.sh
Executable file
30
test_images.sh
Executable file
@@ -0,0 +1,30 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Build directory
|
||||||
|
BUILD_DIR=build
|
||||||
|
BIN_DIR=$BUILD_DIR/bin
|
||||||
|
RELEASE_DIR=release
|
||||||
|
|
||||||
|
# Check if images exist
|
||||||
|
if [ ! -f "$RELEASE_DIR/claude-os.iso" ]; then
|
||||||
|
echo "Error: claude-os.iso not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$RELEASE_DIR/claude-os.img" ]; then
|
||||||
|
echo "Error: claude-os.img not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Testing ISO image..."
|
||||||
|
timeout 5s qemu-system-i386 -cdrom "$RELEASE_DIR/claude-os.iso" -debugcon file:iso_output.txt -display none -no-reboot || true
|
||||||
|
if grep -q "Hello, world" iso_output.txt; then
|
||||||
|
echo "ISO Test Passed!"
|
||||||
|
else
|
||||||
|
echo "ISO Test Failed!"
|
||||||
|
cat iso_output.txt
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "All tests passed!"
|
||||||
Reference in New Issue
Block a user