From 20fd32f97897ea95d53d1ebb21e6f9ee2ae45a40 Mon Sep 17 00:00:00 2001 From: slinky55 Date: Tue, 9 Jun 2026 23:16:25 -0500 Subject: [PATCH] initial commit --- .gitignore | 6 ++ boot.ld | 14 ++++ boot.s | 129 +++++++++++++++++++++++++++++++++++ compile_commands.json | 45 +++++++++++++ kernel.ld | 24 +++++++ kmain.c | 26 +++++++ makefile | 42 ++++++++++++ prekernel.s | 153 ++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 439 insertions(+) create mode 100644 .gitignore create mode 100644 boot.ld create mode 100644 boot.s create mode 100644 compile_commands.json create mode 100644 kernel.ld create mode 100644 kmain.c create mode 100644 makefile create mode 100644 prekernel.s diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..35f5f6c --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.iso +isodir +sysroot + +.idea +.vscode \ No newline at end of file diff --git a/boot.ld b/boot.ld new file mode 100644 index 0000000..a39690a --- /dev/null +++ b/boot.ld @@ -0,0 +1,14 @@ +ENTRY(_start) + +SECTIONS +{ + . = 0x7C00; + + .text : { + *(.text) + } + + .data : { + *(.data) + } +} diff --git a/boot.s b/boot.s new file mode 100644 index 0000000..1f41b08 --- /dev/null +++ b/boot.s @@ -0,0 +1,129 @@ +.code16 +.text +.global _start +_start: + ljmp $0x07C0, $something + +something: + cli + cld + + mov %cs, %ax + mov %ax, %ds + mov %ax, %es + + # stack stuff + mov $0x0000, %ax + mov %ax, %ss + mov $0xFFF0, %sp + + # copy the first 12 bytes of our MBR table entry + mov %dl, (disk_number) + mov $mbr_entry, %di + mov $12, %cx + rep movsb + + mov $0, %ah + int $0x13 + + mov $0x08, %ah + int $0x13 + and 0b00111111, %cl + mov %cl, (total_sectors) + mov %ch, (total_cylinders) + mov %dh, (total_heads) + + mov $0x1000, %ax + mov %ax, %es + mov $0x0000, %bx + + mov (disk_number), %dl + mov $0, %ch #cylinder + mov $0, %dh #head + mov $2, %cl #sector + +load_sector: + mov $1, %al + mov $0x02, %ah + int $0x13 + + mov (kernel_sectors), %ax + cmp $0xffff, %ax + jne check_last_sector + mov %es:20, %eax + shr $9, %eax + inc %eax + +check_last_sector: + dec %ax + mov %ax, kernel_sectors + cmp $0, %ax + je done + +move: # inc our offset. If it hits 0, we've moved a segment, inc that too. + add $512, %bx + cmp $0, %bx + jnz read_next_sector + mov %es, %ax + add $1000, %ax + mov %ax, %es + +read_next_sector: # find the next valid sector, head, cylinder combo on the disk + inc %cl + mov (total_sectors), %al + cmp %al, %cl + jle load_sector + mov $1, %cl #go back to sector 1.. of the next head + + inc %dh #next head + mov (total_heads), %al + cmp %al, %dh + jle load_sector + mov $0, %dh # go back to head 0.. of the next cylinder + + inc %ch # next cylinder + mov (total_cylinders), %al + cmp %al, %ch + jle load_sector + # no more disk... fall through +done: + mov $0, %ah + int $0x13 + + mov $0x1000, %ax + mov %ax, %ds + ljmp $0x1000, $0x0000 + +disk_number: + .byte 0 +total_cylinders: + .byte 0 +total_heads: + .byte 0 +total_sectors: + .byte 0 + +kernel_sectors: + .word 0xFFFF + +mbr_entry: +partition_status: + .byte 0 +partition_start_chs: + .byte 0 + .byte 0 + .byte 0 +partition_type: + .byte 0 +partition_stop_chs: + .byte 0 + .byte 0 + .byte 0 +partition_start_lba: + .long 0 +partition_start_length: + .long 0 + +.org 510 +magic: + .word 0xAA55 diff --git a/compile_commands.json b/compile_commands.json new file mode 100644 index 0000000..b3061a4 --- /dev/null +++ b/compile_commands.json @@ -0,0 +1,45 @@ +[ + { + "file": "boot.s", + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-m32", + "-c", + "boot.s", + "-o", + "boot.o" + ], + "directory": "/home/slinky/source/RockOS", + "output": "boot.o" + }, + { + "file": "prekernel.s", + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-m32", + "-c", + "prekernel.s", + "-o", + "prekernel.o" + ], + "directory": "/home/slinky/source/RockOS", + "output": "prekernel.o" + }, + { + "file": "kmain.c", + "arguments": [ + "/home/slinky/opt/cross/bin/i686-elf-gcc", + "-m32", + "-ffreestanding", + "-O2", + "-Wall", + "-Wextra", + "-c", + "kmain.c", + "-o", + "kmain.o" + ], + "directory": "/home/slinky/source/RockOS", + "output": "kmain.o" + } +] \ No newline at end of file diff --git a/kernel.ld b/kernel.ld new file mode 100644 index 0000000..02e196e --- /dev/null +++ b/kernel.ld @@ -0,0 +1,24 @@ +ENTRY(_start) + +SECTIONS +{ + . = 0x10000; + + .text : { + *(.text) + } + + .rodata : { + *(.rodata) + } + + .data : { + *(.data) + } + + .bss : { + *(.bss) + } + + _end = .; +} diff --git a/kmain.c b/kmain.c new file mode 100644 index 0000000..95dc8f6 --- /dev/null +++ b/kmain.c @@ -0,0 +1,26 @@ +#include + +extern void halt(); + +typedef struct { + uint16_t offset_low; + uint16_t selector; + uint8_t zero; + uint8_t flags; + uint16_t offset_high; +} idt_entry_t __attribute__((packed)); + +typedef struct { + uint16_t limit; + uint32_t base; +} idt_ptr_t; + +idt_entry_t idt[256]; +idt_ptr_t idtr; + +void load_idt() {} + +void kmain() { + load_idt(); + halt(); +} diff --git a/makefile b/makefile new file mode 100644 index 0000000..5c34316 --- /dev/null +++ b/makefile @@ -0,0 +1,42 @@ +CC = i686-elf-gcc +LD = i686-elf-ld +OBJCOPY = i686-elf-objcopy + +CFLAGS = -m32 -ffreestanding -O2 -Wall -Wextra -nostdlib +ASFLAGS = -m32 + +.PHONY: all clean run + +all: os.img + +boot.o: boot.s + $(CC) $(ASFLAGS) -c boot.s -o boot.o + +boot.elf: boot.o boot.ld + $(LD) -T boot.ld -o boot.elf boot.o + +boot.bin: boot.elf + $(OBJCOPY) -O binary boot.elf boot.bin + +prekernel.o: prekernel.s + $(CC) $(ASFLAGS) -c prekernel.s -o prekernel.o + +kmain.o: kmain.c + $(CC) $(CFLAGS) -c kmain.c -o kmain.o + +kernel.elf: prekernel.o kmain.o kernel.ld + $(LD) -T kernel.ld -o kernel.elf prekernel.o kmain.o + +kernel.bin: kernel.elf + $(OBJCOPY) -O binary kernel.elf kernel.bin + +os.img: boot.bin kernel.bin + dd if=boot.bin of=os.img bs=512 count=1 + dd if=kernel.bin of=os.img bs=512 seek=1 + truncate -s 1440k os.img + +run: os.img + qemu-system-i386 -drive format=raw,file=os.img + +clean: + rm -f *.o *.elf *.bin os.img diff --git a/prekernel.s b/prekernel.s new file mode 100644 index 0000000..bd24ae0 --- /dev/null +++ b/prekernel.s @@ -0,0 +1,153 @@ +.code16 +.text +.global _start +_start: + jmp everything + +.org 20 +.global kernel_size +kernel_size: + .long _end - _start + +everything: + mov $0x1000, %ax + mov %ax, %es + mov %ax, %ds + + # reset disk + mov $0, %ah + int $0x13 + + # stop the cursor + mov $1, %ah + mov $0,%cl + mov $0x20,%ch + int $0x11 + + # get the system memory, if this call fails then halt + clc + mov $0, %bx + mov $0xe801, %ax + int $0x15 + jc halt + shr $10, %ax + shr $4, %bx + add %ax, %bx + mov %bx, total_mem_mb-_start + + # vga text mode + mov $0x0003, %ax + int $0x10 + +enable_a20: + #enable the a20 gate + inb $0x92, %al + orb $2, %al + outb %al, $0x92 +prep_protected: + cli + lgdt (gdt_init-_start) + mov %cr0, %eax + or $0x01, %eax + mov %eax, %cr0 # protected bit set + ljmpl $8, $protected + +halt16: + jmp halt16 + +.code32 +protected: + mov $2*8, %ax + mov %ax, %es + mov %ax, %ds + mov %ax, %ss + mov $5*8, %ax + ltr %ax + mov $0, %ax + mov %ax, %fs + mov %ax, %gs + mov $0xFFF0, %sp + mov $0xFFF0, %bp + ljmpl $8, $kmain + +.align 4 +.global video_info_struct +video_info_struct: + .word 0 + .byte 0,0 + .word 0,0,0,0 + .long 0 +.global video_xbytes +video_xbytes: + .word 0 +.global video_xres +video_xres: + .word 0 +.global video_yres +video_yres: + .word 0 + .byte 0,0,0,0,0,0,0,0,0 + .byte 0,0,0,0,0,0,0,0,0 +.global video_buffer +video_buffer: + .long 0 + .long 0 + .word 0 + .word 0 + .byte 0,0,0,0,0,0,0,0,0,0 + .long 0 +.rept 190 + .byte 0 +.endr + +# some assembly stubs we can call from the kernel + +.global idt_load +.extern idtr +idt_load: + lidt (idtr) + ret + +.global gdt_load +gdt_load: + lgdt (gdt_init) + ret + +.global reboot +reboot: + cli + lidt reboot_struct + int $1 +reboot_struct: + .word 0 + .long 0 + +.global halt +halt: + cli + hlt + jmp halt + +# kernel data structures + +.align 16 +.global gdt +gdt: + .word 0,0,0,0 + .word 0xffff, 0x0000, 0x9a00, 0x00cf + .word 0xffff, 0x0000, 0x9200, 0x00cf + .word 0xffff, 0x0000, 0xfa00, 0x00cf + .word 0xffff, 0x0000, 0xf200, 0x00cf + .word 0x0068, (tss-_start), 0x8901, 0x00cf +gdt_init: + .word gdt_init-gdt + .long gdt + +.align 16 +.global tss +tss: + .long 0 + +.global total_mem_mb +total_mem_mb: + .word 0