Compare commits
8 Commits
7c45406c23
...
attempt-1
| Author | SHA1 | Date | |
|---|---|---|---|
| cd0e1cafae | |||
| f42d65267b | |||
| 6d9ab26423 | |||
| e8fa7e1f28 | |||
| 1cf39a70cf | |||
| bbd7d3725b | |||
| f3ef92be4f | |||
| 34e24c9979 |
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,9 +1,3 @@
|
||||
build/
|
||||
release/
|
||||
*.img
|
||||
*.iso
|
||||
debug_grub/
|
||||
*_output.txt
|
||||
snippet.*
|
||||
qemu.log
|
||||
iso_output.txt
|
||||
*.img
|
||||
|
||||
@@ -1,40 +1,9 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
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 -mno-sse -mno-mmx -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)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
||||
# Kernel
|
||||
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}
|
||||
)
|
||||
|
||||
7
PROMPT.md
Normal file
7
PROMPT.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Prompt
|
||||
|
||||
The following prompt was given to GitHub Copilot (Claude Sonnet 4.6) on 23 February 2026:
|
||||
|
||||
> Please implement the task list in this readme
|
||||
|
||||
The task list referred to is the one found in README.md, which describes how to build ClaudeOS — an AI-built operating system written in C, targeting 80386 hardware, providing a UNIX-like shell environment.
|
||||
12
README.md
12
README.md
@@ -37,13 +37,11 @@ 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.
|
||||
Once a task is completed, it should be checked off.
|
||||
|
||||
- [x] Create directory structure
|
||||
- [x] Create initial build system
|
||||
- [x] Setup a simple kernel that writes `Hello, world` to Qemu debug port
|
||||
- [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)
|
||||
- [x] Update the kernel to correctly setup the GDT
|
||||
- [x] Create an interrupt handler.
|
||||
- [ ] Implement a PIC handler
|
||||
- [ ] Create directory structure
|
||||
- [ ] Create initial build system
|
||||
- [ ] 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.
|
||||
- [ ] 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 paging subsystem. It should allow drivers to allocate and deallocate pages at will.
|
||||
- [ ] Create a memory allocator. This should provide the kernel with `malloc` and `free`. Internally, it should use the paging subsystem to ensure that the address it returns have actual RAM paged to them.
|
||||
|
||||
0
apps/.gitkeep
Normal file
0
apps/.gitkeep
Normal file
59
cmake/toolchain-i386-clang.cmake
Normal file
59
cmake/toolchain-i386-clang.cmake
Normal file
@@ -0,0 +1,59 @@
|
||||
# Cross-compilation toolchain for i386-elf using Clang + LLD.
|
||||
#
|
||||
# This targets a bare-metal i386 (80386) environment with no host OS
|
||||
# libraries. lld is used as the linker because the macOS system ld does
|
||||
# not support the ELF32 output format required for a GRUB-bootable kernel.
|
||||
|
||||
set(CMAKE_SYSTEM_NAME Generic)
|
||||
set(CMAKE_SYSTEM_PROCESSOR i386)
|
||||
|
||||
# Use Clang for both C and assembly.
|
||||
set(CMAKE_C_COMPILER clang)
|
||||
set(CMAKE_ASM_COMPILER clang)
|
||||
|
||||
# Prevent CMake from trying to run the cross-compiled test binaries.
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||
|
||||
# Target triple and architecture flags shared by all compilation steps.
|
||||
set(CROSS_TARGET "i386-elf")
|
||||
set(CROSS_ARCH_FLAGS "-target ${CROSS_TARGET} -m32 -march=i386 -mtune=i386")
|
||||
|
||||
# C compiler flags:
|
||||
# - ffreestanding : no hosted C runtime assumptions
|
||||
# - fno-stack-protector : no __stack_chk_fail dependency
|
||||
# - fno-builtin : avoid implicit replacements of standard functions
|
||||
set(CMAKE_C_FLAGS_INIT
|
||||
"${CROSS_ARCH_FLAGS} -ffreestanding -fno-stack-protector -fno-builtin -Wall -Wextra"
|
||||
)
|
||||
|
||||
# Assembler flags: only the flags the assembler front-end actually accepts.
|
||||
# C-only flags like -ffreestanding, -fno-stack-protector, etc. must NOT be
|
||||
# passed here — clang treats them as unused and errors out with -Werror.
|
||||
# -Wno-unused-command-line-argument suppresses CMake's auto-added -MD/-MT/-MF
|
||||
# dependency-tracking flags that clang ignores in pure assembler mode.
|
||||
set(CMAKE_ASM_FLAGS_INIT
|
||||
"-target ${CROSS_TARGET} -m32 -march=i386 -Wno-unused-command-line-argument"
|
||||
)
|
||||
|
||||
# Linking:
|
||||
# On aarch64 Alpine the clang driver delegates link steps to the host gcc,
|
||||
# which does not support -m32 and therefore fails. Bypass the driver entirely
|
||||
# and call ld.lld directly. The CMake rule variables below replace the normal
|
||||
# "compile-with-compiler-driver" link invocation.
|
||||
#
|
||||
# Rule variables use these placeholders:
|
||||
# <TARGET> — output binary path
|
||||
# <OBJECTS> — all compiled object files
|
||||
# <LINK_FLAGS> — extra flags from target_link_options / CMAKE_EXE_LINKER_FLAGS
|
||||
# <LINK_LIBRARIES> — libraries to link (empty for a freestanding kernel)
|
||||
set(CMAKE_LINKER "ld.lld")
|
||||
set(CMAKE_C_LINK_EXECUTABLE
|
||||
"ld.lld -m elf_i386 <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
|
||||
set(CMAKE_ASM_LINK_EXECUTABLE
|
||||
"ld.lld -m elf_i386 <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
|
||||
|
||||
# Keep CMake from accidentally picking up host system headers/libraries.
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
0
docs/.gitkeep
Normal file
0
docs/.gitkeep
Normal file
0
libs/.gitkeep
Normal file
0
libs/.gitkeep
Normal file
0
src/.gitkeep
Normal file
0
src/.gitkeep
Normal file
@@ -1,18 +1,33 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
add_executable(kernel
|
||||
boot.S
|
||||
gdt_flush.S
|
||||
gdt.c
|
||||
idt.c
|
||||
interrupts.S
|
||||
set(KERNEL_SOURCES
|
||||
boot/boot.s
|
||||
kernel.c
|
||||
debugport.c
|
||||
)
|
||||
|
||||
# Use our custom linker script
|
||||
target_link_options(kernel PRIVATE -T ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld)
|
||||
add_executable(kernel ${KERNEL_SOURCES})
|
||||
|
||||
target_include_directories(kernel PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/vendor
|
||||
${CMAKE_SOURCE_DIR}/include # If created later
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
|
||||
target_compile_options(kernel PRIVATE
|
||||
# C-only flags — not valid for the assembler front-end.
|
||||
$<$<COMPILE_LANGUAGE:C>:-Werror>
|
||||
$<$<COMPILE_LANGUAGE:C>:-ffreestanding>
|
||||
$<$<COMPILE_LANGUAGE:C>:-fno-stack-protector>
|
||||
$<$<COMPILE_LANGUAGE:C>:-fno-exceptions>
|
||||
# Suppress the harmless "argument unused" warnings that clang emits
|
||||
# when CMake passes -MD/-MT/-MF to the assembler.
|
||||
$<$<COMPILE_LANGUAGE:ASM>:-Wno-unused-command-line-argument>
|
||||
)
|
||||
|
||||
set_target_properties(kernel PROPERTIES
|
||||
OUTPUT_NAME "claudeos.elf"
|
||||
SUFFIX ""
|
||||
)
|
||||
|
||||
target_link_options(kernel PRIVATE
|
||||
# Pass the linker script directly to ld.lld (CMAKE_C_LINK_EXECUTABLE
|
||||
# calls ld.lld directly, so these are raw ld flags, not clang driver flags).
|
||||
-T ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld
|
||||
)
|
||||
|
||||
65
src/boot.S
65
src/boot.S
@@ -1,65 +0,0 @@
|
||||
#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
|
||||
92
src/boot/boot.s
Normal file
92
src/boot/boot.s
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* boot.s — Multiboot-compliant bootstrap for ClaudeOS.
|
||||
*
|
||||
* This file is the very first code executed by GRUB after the kernel is
|
||||
* loaded. Its responsibilities are:
|
||||
*
|
||||
* 1. Provide a valid Multiboot header so that GRUB recognises the image.
|
||||
* 2. Zero the BSS segment (the C runtime requires it to start at zero).
|
||||
* 3. Set up a small temporary stack.
|
||||
* 4. Forward the Multiboot magic value and info-structure pointer to
|
||||
* kernel_main() as its first and second arguments.
|
||||
* 5. Halt the CPU if kernel_main() ever returns (it should not).
|
||||
*
|
||||
* Multiboot flags used:
|
||||
* Bit 0 — 4 KiB-align all boot modules.
|
||||
* Bit 1 — Include memory map in the Multiboot info structure.
|
||||
*/
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Multiboot header
|
||||
* ------------------------------------------------------------------------- */
|
||||
.set MULTIBOOT_MAGIC, 0x1BADB002
|
||||
.set MULTIBOOT_FLAGS, (1 << 0) | (1 << 1)
|
||||
.set MULTIBOOT_CHECKSUM, -(MULTIBOOT_MAGIC + MULTIBOOT_FLAGS)
|
||||
|
||||
.section .multiboot, "a"
|
||||
.align 4
|
||||
.long MULTIBOOT_MAGIC
|
||||
.long MULTIBOOT_FLAGS
|
||||
.long MULTIBOOT_CHECKSUM
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Bootstrap stack — 16 KiB, 16-byte aligned (required by the i386 ABI).
|
||||
* ------------------------------------------------------------------------- */
|
||||
.section .bss
|
||||
.align 16
|
||||
stack_bottom:
|
||||
.skip 16384
|
||||
stack_top:
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* Kernel entry point
|
||||
* ------------------------------------------------------------------------- */
|
||||
.section .text
|
||||
.global _start
|
||||
.type _start, @function
|
||||
_start:
|
||||
/* Set up the temporary kernel stack. */
|
||||
mov $stack_top, %esp
|
||||
|
||||
/* Preserve the Multiboot magic before the BSS-clearing loop clobbers EAX.
|
||||
*
|
||||
* Registers on entry (Multiboot spec §3.2):
|
||||
* eax — 0x2BADB002 (magic)
|
||||
* ebx — multiboot_info_t* (physical address of info structure)
|
||||
*
|
||||
* 'rep stosb' only modifies EAX, EDI and ECX, so EBX survives intact.
|
||||
* We park EAX in ESI (callee-saved, not used by the BSS loop). */
|
||||
mov %eax, %esi /* save Multiboot magic */
|
||||
|
||||
/* Zero the BSS segment.
|
||||
* The C standard requires that all static storage is zero-initialised.
|
||||
* The linker script exports _bss_start and _bss_end for this purpose. */
|
||||
mov $_bss_start, %edi
|
||||
mov $_bss_end, %ecx
|
||||
sub %edi, %ecx /* byte count */
|
||||
xor %eax, %eax
|
||||
rep stosb
|
||||
|
||||
/* Restore magic; EBX (info pointer) is still intact. */
|
||||
mov %esi, %eax
|
||||
|
||||
/*
|
||||
* Call kernel_main(uint32_t multiboot_magic, uint32_t multiboot_info).
|
||||
*
|
||||
* The Multiboot specification passes:
|
||||
* eax — 0x2BADB002 (bootloader magic)
|
||||
* ebx — physical address of the multiboot_info_t structure
|
||||
*
|
||||
* We push them in reverse order to match the C calling convention.
|
||||
*/
|
||||
push %ebx /* arg1: multiboot_info pointer */
|
||||
push %eax /* arg0: multiboot magic */
|
||||
call kernel_main
|
||||
|
||||
/* kernel_main should never return; halt the machine if it does. */
|
||||
.L_halt:
|
||||
cli
|
||||
hlt
|
||||
jmp .L_halt
|
||||
|
||||
.size _start, . - _start
|
||||
39
src/debugport.c
Normal file
39
src/debugport.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @file debugport.c
|
||||
* @brief QEMU/Bochs debug port (I/O port 0xE9) implementation.
|
||||
*
|
||||
* Writing a byte to I/O port 0xE9 causes QEMU (when run with
|
||||
* `-debugcon stdio`) to echo that byte verbatim to the host's stdout.
|
||||
* This requires no peripheral initialisation and is available from the
|
||||
* very first instruction after the bootloader hands control to the kernel.
|
||||
*/
|
||||
|
||||
#include <debugport.h>
|
||||
#include <io.h>
|
||||
|
||||
/** I/O port address of the QEMU/Bochs debug console. */
|
||||
#define DEBUG_PORT 0xE9U
|
||||
|
||||
/**
|
||||
* @brief Write a single character to the QEMU debug port.
|
||||
*
|
||||
* @param c Character to transmit.
|
||||
*/
|
||||
void debugport_putc(char c)
|
||||
{
|
||||
outb((uint16_t)DEBUG_PORT, (uint8_t)c);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a NUL-terminated string to the QEMU debug port.
|
||||
*
|
||||
* Each character is transmitted individually via debugport_putc().
|
||||
*
|
||||
* @param s Pointer to the NUL-terminated string. Must not be NULL.
|
||||
*/
|
||||
void debugport_puts(const char *s)
|
||||
{
|
||||
while (*s) {
|
||||
debugport_putc(*s++);
|
||||
}
|
||||
}
|
||||
68
src/gdt.c
68
src/gdt.c
@@ -1,68 +0,0 @@
|
||||
#include "gdt.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* GDT Pointer Structure */
|
||||
struct gdt_ptr gp;
|
||||
/* GDT entries */
|
||||
struct gdt_entry gdt[5];
|
||||
|
||||
extern void gdt_flush(uint32_t);
|
||||
|
||||
/* Setup a descriptor in the Global Descriptor Table */
|
||||
void gdt_set_gate(int32_t num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran)
|
||||
{
|
||||
/* Setup the descriptor base address */
|
||||
gdt[num].base_low = (base & 0xFFFF);
|
||||
gdt[num].base_middle = (base >> 16) & 0xFF;
|
||||
gdt[num].base_high = (base >> 24) & 0xFF;
|
||||
|
||||
/* Setup the descriptor limits */
|
||||
gdt[num].limit_low = (limit & 0xFFFF);
|
||||
gdt[num].granularity = ((limit >> 16) & 0x0F);
|
||||
|
||||
/* Finally, set up the granularity and access flags */
|
||||
gdt[num].granularity |= (gran & 0xF0);
|
||||
gdt[num].access = access;
|
||||
}
|
||||
|
||||
/* Should be called by main. This will setup the special GDT
|
||||
* pointer, set up the first 3 entries in our GDT, and then
|
||||
* call gdt_flush() in our assembler file in order to tell
|
||||
* the processor where the new GDT is and update the
|
||||
* internal registers */
|
||||
void init_gdt()
|
||||
{
|
||||
/* Setup the GDT pointer and limit */
|
||||
gp.limit = (sizeof(struct gdt_entry) * 5) - 1;
|
||||
gp.base = (uint32_t)&gdt;
|
||||
|
||||
/* Our NULL descriptor */
|
||||
gdt_set_gate(0, 0, 0, 0, 0);
|
||||
|
||||
/* The second entry is our Code Segment. The base address
|
||||
* is 0, the limit is 4GBytes, it uses 4KByte granularity,
|
||||
* uses 32-bit opcodes, and is a Code Segment descriptor.
|
||||
* Please check the table above in the tutorial in order
|
||||
* to see exactly what each value means */
|
||||
/* 0x9A = 1001 1010
|
||||
P=1, DPL=00, S=1 (Code/Data), Type=1010 (Code, Exec/Read) */
|
||||
/* 0xCF = 1100 1111
|
||||
G=1 (4k), DB=1 (32bit), L=0, AVL=0, LimitHigh=0xF */
|
||||
gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);
|
||||
|
||||
/* The third entry is our Data Segment. It's EXACTLY the
|
||||
* same as our code segment, but the descriptor type in
|
||||
* this entry's access byte says it's a Data Segment */
|
||||
/* 0x92 = 1001 0010
|
||||
P=1, DPL=00, S=1, Type=0010 (Data, Read/Write) */
|
||||
gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);
|
||||
|
||||
/* User mode code segment */
|
||||
gdt_set_gate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF);
|
||||
|
||||
/* User mode data segment */
|
||||
gdt_set_gate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF);
|
||||
|
||||
/* Flush out the old GDT and install the new changes! */
|
||||
gdt_flush((uint32_t)&gp);
|
||||
}
|
||||
25
src/gdt.h
25
src/gdt.h
@@ -1,25 +0,0 @@
|
||||
#ifndef GDT_H
|
||||
#define GDT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* GDT Entry Structure */
|
||||
struct gdt_entry {
|
||||
uint16_t limit_low;
|
||||
uint16_t base_low;
|
||||
uint8_t base_middle;
|
||||
uint8_t access;
|
||||
uint8_t granularity;
|
||||
uint8_t base_high;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* GDT Pointer Structure */
|
||||
struct gdt_ptr {
|
||||
uint16_t limit;
|
||||
uint32_t base;
|
||||
} __attribute__((packed, aligned(1)));
|
||||
|
||||
/* Initialize GDT */
|
||||
void init_gdt(void);
|
||||
|
||||
#endif // GDT_H
|
||||
@@ -1,18 +0,0 @@
|
||||
.section .text
|
||||
.global gdt_flush
|
||||
.type gdt_flush, @function
|
||||
gdt_flush:
|
||||
mov 4(%esp), %eax
|
||||
lgdt (%eax)
|
||||
|
||||
mov $0x10, %ax
|
||||
mov %ax, %ds
|
||||
mov %ax, %es
|
||||
mov %ax, %fs
|
||||
mov %ax, %gs
|
||||
mov %ax, %ss
|
||||
|
||||
ljmp $0x08, $flush
|
||||
|
||||
flush:
|
||||
ret
|
||||
46
src/idt.c
46
src/idt.c
@@ -1,46 +0,0 @@
|
||||
#include "idt.h"
|
||||
#include <stdint.h>
|
||||
#include <stddef.h> /* for memset */
|
||||
|
||||
idt_entry_t idt_entries[256];
|
||||
idt_ptr_t idt_ptr;
|
||||
|
||||
extern void idt_load();
|
||||
|
||||
static void idt_set_gate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags)
|
||||
{
|
||||
idt_entries[num].base_lo = base & 0xFFFF;
|
||||
idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
|
||||
|
||||
idt_entries[num].sel = sel;
|
||||
idt_entries[num].always0 = 0;
|
||||
// We must uncomment the OR below when we get to using user-mode.
|
||||
// It sets the interrupt gate's privilege level to 3.
|
||||
idt_entries[num].flags = flags /* | 0x60 */;
|
||||
}
|
||||
|
||||
/* Note: memset implementation because we don't link with libc */
|
||||
static void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
unsigned char *p = s;
|
||||
while(n--)
|
||||
*p++ = (unsigned char)c;
|
||||
return s;
|
||||
}
|
||||
|
||||
void init_idt()
|
||||
{
|
||||
idt_ptr.limit = sizeof(idt_entry_t) * 256 - 1;
|
||||
idt_ptr.base = (uint32_t)&idt_entries;
|
||||
|
||||
memset(&idt_entries, 0, sizeof(idt_entry_t) * 256);
|
||||
|
||||
/* Determine valid flags:
|
||||
* 0x8E = 1000 1110
|
||||
* P=1, DPL=00, S=0 (System), Type=1110 (32-bit Interrupt Gate) */
|
||||
|
||||
/* For now, just load the IDT without any entries to verify loading works without crashing.
|
||||
Later we will set up ISRs. */
|
||||
|
||||
idt_load((uint32_t)&idt_ptr);
|
||||
}
|
||||
33
src/idt.h
33
src/idt.h
@@ -1,33 +0,0 @@
|
||||
#ifndef IDT_H
|
||||
#define IDT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* A struct describing an interrupt gate. */
|
||||
struct idt_entry_struct {
|
||||
uint16_t base_lo; // The lower 16 bits of the address to jump to when this interrupt fires.
|
||||
uint16_t sel; // Kernel segment selector.
|
||||
uint8_t always0; // This must always be zero.
|
||||
uint8_t flags; // More flags. See documentation.
|
||||
uint16_t base_hi; // The upper 16 bits of the address to jump to.
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct idt_entry_struct idt_entry_t;
|
||||
|
||||
/* A struct describing a pointer to an array of interrupt handlers.
|
||||
* This is in a format suitable for giving to 'lidt'. */
|
||||
struct idt_ptr_struct {
|
||||
uint16_t limit;
|
||||
uint32_t base; // The address of the first element in our idt_entry_t array.
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct idt_ptr_struct idt_ptr_t;
|
||||
|
||||
// These extern directives let us access the addresses of our ASM ISR handlers.
|
||||
extern void isr0();
|
||||
extern void isr1();
|
||||
// ... we will add more later ...
|
||||
|
||||
void init_idt();
|
||||
|
||||
#endif
|
||||
34
src/include/debugport.h
Normal file
34
src/include/debugport.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @file debugport.h
|
||||
* @brief QEMU/Bochs debug port (I/O port 0xE9) output interface.
|
||||
*
|
||||
* Port 0xE9 is a de-facto standard "debug port" supported by both Bochs and
|
||||
* QEMU (when launched with `-debugcon stdio`). Any byte written to this port
|
||||
* is immediately forwarded to the host's standard output, making it the
|
||||
* simplest possible kernel logging mechanism — no interrupt handling, VGA, or
|
||||
* serial initialisation is required.
|
||||
*
|
||||
* Usage in QEMU:
|
||||
* qemu-system-i386 -debugcon stdio ...
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @brief Write a single character to the QEMU debug port.
|
||||
*
|
||||
* Issues a single OUT instruction to port 0xE9.
|
||||
*
|
||||
* @param c Character to transmit.
|
||||
*/
|
||||
void debugport_putc(char c);
|
||||
|
||||
/**
|
||||
* @brief Write a NUL-terminated string to the QEMU debug port.
|
||||
*
|
||||
* Iterates over every character in @p s and calls debugport_putc() for each
|
||||
* one. The terminating NUL byte is not transmitted.
|
||||
*
|
||||
* @param s Pointer to the NUL-terminated string. Must not be NULL.
|
||||
*/
|
||||
void debugport_puts(const char *s);
|
||||
41
src/include/io.h
Normal file
41
src/include/io.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* @file io.h
|
||||
* @brief Low-level x86 port I/O helpers.
|
||||
*
|
||||
* Provides thin wrappers around the x86 IN/OUT instructions so that C code
|
||||
* throughout the kernel can read from and write to I/O ports without
|
||||
* resorting to inline assembly at every call site.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Write an 8-bit value to an I/O port.
|
||||
*
|
||||
* Issues an x86 OUT instruction. Execution halts until the peripheral
|
||||
* acknowledges the write (the CPU inserts appropriate bus wait-states).
|
||||
*
|
||||
* @param port 16-bit I/O port address.
|
||||
* @param value 8-bit value to send.
|
||||
*/
|
||||
static inline void outb(uint16_t port, uint8_t value)
|
||||
{
|
||||
__asm__ volatile("outb %0, %1" : : "a"(value), "Nd"(port));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read an 8-bit value from an I/O port.
|
||||
*
|
||||
* Issues an x86 IN instruction.
|
||||
*
|
||||
* @param port 16-bit I/O port address.
|
||||
* @return The 8-bit value returned by the peripheral.
|
||||
*/
|
||||
static inline uint8_t inb(uint16_t port)
|
||||
{
|
||||
uint8_t value;
|
||||
__asm__ volatile("inb %1, %0" : "=a"(value) : "Nd"(port));
|
||||
return value;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
.section .text
|
||||
.global idt_load
|
||||
.type idt_load, @function
|
||||
idt_load:
|
||||
mov 4(%esp), %eax /* Turn the argument into the EAX register */
|
||||
lidt (%eax) /* Load the IDT pointer */
|
||||
ret
|
||||
0
src/it/.gitkeep
Normal file
0
src/it/.gitkeep
Normal file
82
src/kernel.c
82
src/kernel.c
@@ -1,51 +1,45 @@
|
||||
#include <multiboot2.h>
|
||||
/**
|
||||
* @file kernel.c
|
||||
* @brief Kernel entry point.
|
||||
*
|
||||
* Called by the Multiboot bootstrap (boot/boot.s) after the BSS has been
|
||||
* zeroed and a temporary stack has been established. The bootloader passes
|
||||
* the Multiboot magic value and a pointer to the Multiboot info structure.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include "gdt.h"
|
||||
#include "idt.h"
|
||||
#include <debugport.h>
|
||||
|
||||
static inline void outb(uint16_t port, uint8_t val)
|
||||
/** Magic value the bootloader stores in EAX before jumping to _start. */
|
||||
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002U
|
||||
|
||||
/**
|
||||
* @brief Main kernel entry point.
|
||||
*
|
||||
* Validates the Multiboot magic so we know the bootloader handed us a proper
|
||||
* info structure, then writes a greeting to the QEMU debug port so the host
|
||||
* can confirm the kernel reached C code successfully.
|
||||
*
|
||||
* @param multiboot_magic 0x2BADB002 when booted by a Multiboot-compliant
|
||||
* bootloader (e.g. GRUB).
|
||||
* @param multiboot_info Physical address of the multiboot_info_t structure
|
||||
* provided by the bootloader.
|
||||
*/
|
||||
void kernel_main(uint32_t multiboot_magic, uint32_t multiboot_info)
|
||||
{
|
||||
asm volatile ( "outb %b0, %w1" : : "a"(val), "Nd"(port) );
|
||||
}
|
||||
(void)multiboot_info;
|
||||
|
||||
void offset_print(const char *str)
|
||||
{
|
||||
while (*str) {
|
||||
outb(0xE9, *str);
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
|
||||
|
||||
void print_hex(uint32_t val)
|
||||
{
|
||||
const char *hex = "0123456789ABCDEF";
|
||||
outb(0xE9, '0');
|
||||
outb(0xE9, 'x');
|
||||
for (int i = 28; i >= 0; i -= 4) {
|
||||
outb(0xE9, hex[(val >> i) & 0xF]);
|
||||
}
|
||||
outb(0xE9, '\n');
|
||||
}
|
||||
|
||||
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: ");
|
||||
print_hex(magic);
|
||||
return;
|
||||
/* Announce ourselves on the QEMU debug port.
|
||||
* QEMU must be launched with -debugcon stdio for this to appear. */
|
||||
if (multiboot_magic == MULTIBOOT_BOOTLOADER_MAGIC) {
|
||||
debugport_puts("Hello, World!\n");
|
||||
debugport_puts("ClaudeOS kernel booted successfully.\n");
|
||||
} else {
|
||||
debugport_puts("ERROR: bad Multiboot magic — not booted by GRUB?\n");
|
||||
}
|
||||
|
||||
offset_print("Booting...\n");
|
||||
|
||||
init_gdt();
|
||||
offset_print("GDT initialized\n");
|
||||
|
||||
init_idt();
|
||||
offset_print("IDT initialized\n");
|
||||
|
||||
offset_print("Hello, world\n");
|
||||
/* Spin forever. Subsequent commits will add real work here. */
|
||||
for (;;) {
|
||||
__asm__ volatile("hlt");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,53 @@
|
||||
/*
|
||||
* Linker script for the ClaudeOS kernel.
|
||||
*
|
||||
* The kernel is loaded by GRUB at physical address 0x00100000 (1 MiB).
|
||||
* All kernel sections follow immediately after the multiboot header so that
|
||||
* GRUB can locate it within the first 8 KiB of the ELF image as required by
|
||||
* the Multiboot specification.
|
||||
*
|
||||
* Symbol _bss_start / _bss_end are exported so the bootstrap can zero the
|
||||
* BSS segment before jumping to C code. _kernel_end marks the first byte
|
||||
* after the kernel image, which the physical memory allocator will use as
|
||||
* its starting address.
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT(elf32-i386)
|
||||
OUTPUT_ARCH(i386)
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 1M;
|
||||
. = 0x00100000;
|
||||
|
||||
.text BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
KEEP(*(.multiboot))
|
||||
*(.text)
|
||||
}
|
||||
/* The multiboot header must appear within the first 8 KiB. */
|
||||
.multiboot ALIGN(4) :
|
||||
{
|
||||
KEEP(*(.multiboot))
|
||||
}
|
||||
|
||||
.rodata BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.rodata)
|
||||
}
|
||||
.text ALIGN(4096) :
|
||||
{
|
||||
*(.text*)
|
||||
}
|
||||
|
||||
.data BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
.rodata ALIGN(4096) :
|
||||
{
|
||||
*(.rodata*)
|
||||
}
|
||||
|
||||
.bss BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
}
|
||||
.data ALIGN(4096) :
|
||||
{
|
||||
*(.data*)
|
||||
}
|
||||
|
||||
.bss ALIGN(4096) :
|
||||
{
|
||||
_bss_start = .;
|
||||
*(COMMON)
|
||||
*(.bss*)
|
||||
_bss_end = .;
|
||||
}
|
||||
|
||||
_kernel_end = .;
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
#!/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
|
||||
|
||||
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!"
|
||||
0
vendor/.gitkeep
vendored
Normal file
0
vendor/.gitkeep
vendored
Normal file
417
vendor/multiboot2.h
vendored
417
vendor/multiboot2.h
vendored
@@ -1,417 +0,0 @@
|
||||
/* multiboot2.h - Multiboot 2 header file. */
|
||||
/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
|
||||
* DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef MULTIBOOT_HEADER
|
||||
#define MULTIBOOT_HEADER 1
|
||||
|
||||
/* How many bytes from the start of the file we search for the header. */
|
||||
#define MULTIBOOT_SEARCH 32768
|
||||
#define MULTIBOOT_HEADER_ALIGN 8
|
||||
|
||||
/* The magic field should contain this. */
|
||||
#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
|
||||
|
||||
/* This should be in %eax. */
|
||||
#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
|
||||
|
||||
/* Alignment of multiboot modules. */
|
||||
#define MULTIBOOT_MOD_ALIGN 0x00001000
|
||||
|
||||
/* Alignment of the multiboot info structure. */
|
||||
#define MULTIBOOT_INFO_ALIGN 0x00000008
|
||||
|
||||
/* Flags set in the 'flags' member of the multiboot header. */
|
||||
|
||||
#define MULTIBOOT_TAG_ALIGN 8
|
||||
#define MULTIBOOT_TAG_TYPE_END 0
|
||||
#define MULTIBOOT_TAG_TYPE_CMDLINE 1
|
||||
#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2
|
||||
#define MULTIBOOT_TAG_TYPE_MODULE 3
|
||||
#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4
|
||||
#define MULTIBOOT_TAG_TYPE_BOOTDEV 5
|
||||
#define MULTIBOOT_TAG_TYPE_MMAP 6
|
||||
#define MULTIBOOT_TAG_TYPE_VBE 7
|
||||
#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8
|
||||
#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9
|
||||
#define MULTIBOOT_TAG_TYPE_APM 10
|
||||
#define MULTIBOOT_TAG_TYPE_EFI32 11
|
||||
#define MULTIBOOT_TAG_TYPE_EFI64 12
|
||||
#define MULTIBOOT_TAG_TYPE_SMBIOS 13
|
||||
#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14
|
||||
#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15
|
||||
#define MULTIBOOT_TAG_TYPE_NETWORK 16
|
||||
#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17
|
||||
#define MULTIBOOT_TAG_TYPE_EFI_BS 18
|
||||
#define MULTIBOOT_TAG_TYPE_EFI32_IH 19
|
||||
#define MULTIBOOT_TAG_TYPE_EFI64_IH 20
|
||||
#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21
|
||||
|
||||
#define MULTIBOOT_HEADER_TAG_END 0
|
||||
#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1
|
||||
#define MULTIBOOT_HEADER_TAG_ADDRESS 2
|
||||
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3
|
||||
#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4
|
||||
#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5
|
||||
#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6
|
||||
#define MULTIBOOT_HEADER_TAG_EFI_BS 7
|
||||
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8
|
||||
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9
|
||||
#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10
|
||||
|
||||
#define MULTIBOOT_ARCHITECTURE_I386 0
|
||||
#define MULTIBOOT_ARCHITECTURE_MIPS32 4
|
||||
#define MULTIBOOT_HEADER_TAG_OPTIONAL 1
|
||||
|
||||
#define MULTIBOOT_LOAD_PREFERENCE_NONE 0
|
||||
#define MULTIBOOT_LOAD_PREFERENCE_LOW 1
|
||||
#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2
|
||||
|
||||
#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
|
||||
#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
|
||||
|
||||
#ifndef ASM_FILE
|
||||
|
||||
typedef unsigned char multiboot_uint8_t;
|
||||
typedef unsigned short multiboot_uint16_t;
|
||||
typedef unsigned int multiboot_uint32_t;
|
||||
typedef unsigned long long multiboot_uint64_t;
|
||||
|
||||
struct multiboot_header
|
||||
{
|
||||
/* Must be MULTIBOOT_MAGIC - see above. */
|
||||
multiboot_uint32_t magic;
|
||||
|
||||
/* ISA */
|
||||
multiboot_uint32_t architecture;
|
||||
|
||||
/* Total header length. */
|
||||
multiboot_uint32_t header_length;
|
||||
|
||||
/* The above fields plus this one must equal 0 mod 2^32. */
|
||||
multiboot_uint32_t checksum;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_information_request
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t requests[0];
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_address
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t header_addr;
|
||||
multiboot_uint32_t load_addr;
|
||||
multiboot_uint32_t load_end_addr;
|
||||
multiboot_uint32_t bss_end_addr;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_entry_address
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t entry_addr;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_console_flags
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t console_flags;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_framebuffer
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t width;
|
||||
multiboot_uint32_t height;
|
||||
multiboot_uint32_t depth;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_module_align
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
};
|
||||
|
||||
struct multiboot_header_tag_relocatable
|
||||
{
|
||||
multiboot_uint16_t type;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t min_addr;
|
||||
multiboot_uint32_t max_addr;
|
||||
multiboot_uint32_t align;
|
||||
multiboot_uint32_t preference;
|
||||
};
|
||||
|
||||
struct multiboot_color
|
||||
{
|
||||
multiboot_uint8_t red;
|
||||
multiboot_uint8_t green;
|
||||
multiboot_uint8_t blue;
|
||||
};
|
||||
|
||||
struct multiboot_mmap_entry
|
||||
{
|
||||
multiboot_uint64_t addr;
|
||||
multiboot_uint64_t len;
|
||||
#define MULTIBOOT_MEMORY_AVAILABLE 1
|
||||
#define MULTIBOOT_MEMORY_RESERVED 2
|
||||
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
|
||||
#define MULTIBOOT_MEMORY_NVS 4
|
||||
#define MULTIBOOT_MEMORY_BADRAM 5
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t zero;
|
||||
};
|
||||
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
|
||||
|
||||
struct multiboot_tag
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
};
|
||||
|
||||
struct multiboot_tag_string
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
char string[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_module
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t mod_start;
|
||||
multiboot_uint32_t mod_end;
|
||||
char cmdline[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_basic_meminfo
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t mem_lower;
|
||||
multiboot_uint32_t mem_upper;
|
||||
};
|
||||
|
||||
struct multiboot_tag_bootdev
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t biosdev;
|
||||
multiboot_uint32_t slice;
|
||||
multiboot_uint32_t part;
|
||||
};
|
||||
|
||||
struct multiboot_tag_mmap
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t entry_size;
|
||||
multiboot_uint32_t entry_version;
|
||||
struct multiboot_mmap_entry entries[0];
|
||||
};
|
||||
|
||||
struct multiboot_vbe_info_block
|
||||
{
|
||||
multiboot_uint8_t external_specification[512];
|
||||
};
|
||||
|
||||
struct multiboot_vbe_mode_info_block
|
||||
{
|
||||
multiboot_uint8_t external_specification[256];
|
||||
};
|
||||
|
||||
struct multiboot_tag_vbe
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
|
||||
multiboot_uint16_t vbe_mode;
|
||||
multiboot_uint16_t vbe_interface_seg;
|
||||
multiboot_uint16_t vbe_interface_off;
|
||||
multiboot_uint16_t vbe_interface_len;
|
||||
|
||||
struct multiboot_vbe_info_block vbe_control_info;
|
||||
struct multiboot_vbe_mode_info_block vbe_mode_info;
|
||||
};
|
||||
|
||||
struct multiboot_tag_framebuffer_common
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
|
||||
multiboot_uint64_t framebuffer_addr;
|
||||
multiboot_uint32_t framebuffer_pitch;
|
||||
multiboot_uint32_t framebuffer_width;
|
||||
multiboot_uint32_t framebuffer_height;
|
||||
multiboot_uint8_t framebuffer_bpp;
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
|
||||
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
|
||||
multiboot_uint8_t framebuffer_type;
|
||||
multiboot_uint16_t reserved;
|
||||
};
|
||||
|
||||
struct multiboot_tag_framebuffer
|
||||
{
|
||||
struct multiboot_tag_framebuffer_common common;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
multiboot_uint16_t framebuffer_palette_num_colors;
|
||||
struct multiboot_color framebuffer_palette[0];
|
||||
};
|
||||
struct
|
||||
{
|
||||
multiboot_uint8_t framebuffer_red_field_position;
|
||||
multiboot_uint8_t framebuffer_red_mask_size;
|
||||
multiboot_uint8_t framebuffer_green_field_position;
|
||||
multiboot_uint8_t framebuffer_green_mask_size;
|
||||
multiboot_uint8_t framebuffer_blue_field_position;
|
||||
multiboot_uint8_t framebuffer_blue_mask_size;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
struct multiboot_tag_elf_sections
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t num;
|
||||
multiboot_uint32_t entsize;
|
||||
multiboot_uint32_t shndx;
|
||||
char sections[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_apm
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint16_t version;
|
||||
multiboot_uint16_t cseg;
|
||||
multiboot_uint32_t offset;
|
||||
multiboot_uint16_t cseg_16;
|
||||
multiboot_uint16_t dseg;
|
||||
multiboot_uint16_t flags;
|
||||
multiboot_uint16_t cseg_len;
|
||||
multiboot_uint16_t cseg_16_len;
|
||||
multiboot_uint16_t dseg_len;
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi32
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t pointer;
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi64
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint64_t pointer;
|
||||
};
|
||||
|
||||
struct multiboot_tag_smbios
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint8_t major;
|
||||
multiboot_uint8_t minor;
|
||||
multiboot_uint8_t reserved[6];
|
||||
multiboot_uint8_t tables[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_old_acpi
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint8_t rsdp[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_new_acpi
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint8_t rsdp[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_network
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint8_t dhcpack[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi_mmap
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t descr_size;
|
||||
multiboot_uint32_t descr_vers;
|
||||
multiboot_uint8_t efi_mmap[0];
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi32_ih
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t pointer;
|
||||
};
|
||||
|
||||
struct multiboot_tag_efi64_ih
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint64_t pointer;
|
||||
};
|
||||
|
||||
struct multiboot_tag_load_base_addr
|
||||
{
|
||||
multiboot_uint32_t type;
|
||||
multiboot_uint32_t size;
|
||||
multiboot_uint32_t load_base_addr;
|
||||
};
|
||||
|
||||
#endif /* ! ASM_FILE */
|
||||
|
||||
#endif /* ! MULTIBOOT_HEADER */
|
||||
Reference in New Issue
Block a user