Setup simple kernel with Hello World output via debugcon (AI)
This commit is contained in:
@@ -4,9 +4,9 @@ project(ClaudeOS C ASM)
|
|||||||
set(CMAKE_C_STANDARD 99)
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
|
||||||
# We are building a kernel, so we don't want standard libraries
|
# 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_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")
|
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -m32 -fno-pie -fno-pic")
|
||||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32 -nostdlib")
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32 -nostdlib -no-pie")
|
||||||
|
|
||||||
# Define build output directory
|
# Define build output directory
|
||||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ Once a task is completed, it should be checked off.
|
|||||||
|
|
||||||
- [x] Create directory structure
|
- [x] Create directory structure
|
||||||
- [x] 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.
|
- [ ] 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
|
- [ ] 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.
|
||||||
|
|||||||
1
output.txt
Normal file
1
output.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Hello, world
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
add_executable(kernel
|
add_executable(kernel
|
||||||
|
boot.S
|
||||||
kernel.c
|
kernel.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
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
|
||||||
32
src/kernel.c
32
src/kernel.c
@@ -1,3 +1,31 @@
|
|||||||
void _start() {
|
#include <multiboot2.h>
|
||||||
while(1) {}
|
#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");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user