initial commit

This commit is contained in:
2026-06-09 23:16:25 -05:00
commit 20fd32f978
8 changed files with 439 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
*.iso
isodir
sysroot
.idea
.vscode

14
boot.ld Normal file
View File

@@ -0,0 +1,14 @@
ENTRY(_start)
SECTIONS
{
. = 0x7C00;
.text : {
*(.text)
}
.data : {
*(.data)
}
}

129
boot.s Normal file
View File

@@ -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

45
compile_commands.json Normal file
View File

@@ -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"
}
]

24
kernel.ld Normal file
View File

@@ -0,0 +1,24 @@
ENTRY(_start)
SECTIONS
{
. = 0x10000;
.text : {
*(.text)
}
.rodata : {
*(.rodata)
}
.data : {
*(.data)
}
.bss : {
*(.bss)
}
_end = .;
}

26
kmain.c Normal file
View File

@@ -0,0 +1,26 @@
#include <stdint.h>
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();
}

42
makefile Normal file
View File

@@ -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

153
prekernel.s Normal file
View File

@@ -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