rearraged files, set up to use grub bootloader

This commit is contained in:
2026-06-10 18:28:33 -05:00
parent 0f8d5f8ce7
commit eb1e096bac
19 changed files with 270 additions and 386 deletions

28
kernel/boot/boot.s Normal file
View File

@@ -0,0 +1,28 @@
.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
.long MAGIC
.long FLAGS
.long CHECKSUM
.section .bss
.align 16
stack_bottom:
.skip 16384 # 16 KiB
stack_top:
.section .text
.global _start
.type _start, @function
_start:
mov $stack_top, %esp
call kernel_main
cli
1: hlt
jmp 1b

View File

@@ -0,0 +1,72 @@
#include <stddef.h>
#include <stdint.h>
#include <lib/stream.h>
#define VGA_WIDTH 80
#define VGA_HEIGHT 25
#define VGA_MEMORY 0xB8000
enum vga_color {
VGA_COLOR_BLACK = 0,
VGA_COLOR_BLUE = 1,
VGA_COLOR_GREEN = 2,
VGA_COLOR_CYAN = 3,
VGA_COLOR_RED = 4,
VGA_COLOR_MAGENTA = 5,
VGA_COLOR_BROWN = 6,
VGA_COLOR_LIGHT_GREY = 7,
VGA_COLOR_DARK_GREY = 8,
VGA_COLOR_LIGHT_BLUE = 9,
VGA_COLOR_LIGHT_GREEN = 10,
VGA_COLOR_LIGHT_CYAN = 11,
VGA_COLOR_LIGHT_RED = 12,
VGA_COLOR_LIGHT_MAGENTA = 13,
VGA_COLOR_LIGHT_BROWN = 14,
VGA_COLOR_WHITE = 15,
};
size_t terminal_row;
size_t terminal_column;
uint8_t terminal_color;
uint16_t* terminal_buffer = (uint16_t*)VGA_MEMORY;
static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg)
{
return fg | bg << 4;
}
static inline uint16_t vga_entry(unsigned char uc, uint8_t color)
{
return (uint16_t) uc | (uint16_t) color << 8;
}
void vga_initialize()
{
terminal_row = 0;
terminal_column = 0;
terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
for (size_t y = 0; y < VGA_HEIGHT; y++) {
for (size_t x = 0; x < VGA_WIDTH; x++) {
const size_t index = y * VGA_WIDTH + x;
terminal_buffer[index] = vga_entry(' ', terminal_color);
}
}
}
void vga_putchar(char c)
{
const size_t index = terminal_row * VGA_WIDTH + terminal_column;
terminal_buffer[index] = vga_entry(c, terminal_color);
if (++terminal_column == VGA_WIDTH) {
terminal_column = 0;
if (++terminal_row == VGA_HEIGHT)
terminal_row = 0;
}
}
print_stream_t vga_print_stream = {
.putchar = vga_putchar,
.trunc = vga_initialize,
};

62
kernel/gdt.c Normal file
View File

@@ -0,0 +1,62 @@
#include <stdint.h>
#define SEG_DESCTYPE(x) ((x) << 0x04) // Descriptor type (0 for system, 1 for code/data)
#define SEG_PRES(x) ((x) << 0x07) // Present
#define SEG_SAVL(x) ((x) << 0x0C) // Available for system use
#define SEG_LONG(x) ((x) << 0x0D) // Long mode
#define SEG_SIZE(x) ((x) << 0x0E) // Size (0 for 16-bit, 1 for 32)
#define SEG_GRAN(x) ((x) << 0x0F) // Granularity (0 for 1B - 1MB, 1 for 4KB - 4GB)
#define SEG_PRIV(x) (((x) & 0x03) << 0x05) // Set privilege level (0 - 3)
#define SEG_DATA_RD 0x00 // Read-Only
#define SEG_DATA_RDA 0x01 // Read-Only, accessed
#define SEG_DATA_RDWR 0x02 // Read/Write
#define SEG_DATA_RDWRA 0x03 // Read/Write, accessed
#define SEG_DATA_RDEXPD 0x04 // Read-Only, expand-down
#define SEG_DATA_RDEXPDA 0x05 // Read-Only, expand-down, accessed
#define SEG_DATA_RDWREXPD 0x06 // Read/Write, expand-down
#define SEG_DATA_RDWREXPDA 0x07 // Read/Write, expand-down, accessed
#define SEG_CODE_EX 0x08 // Execute-Only
#define SEG_CODE_EXA 0x09 // Execute-Only, accessed
#define SEG_CODE_EXRD 0x0A // Execute/Read
#define SEG_CODE_EXRDA 0x0B // Execute/Read, accessed
#define SEG_CODE_EXC 0x0C // Execute-Only, conforming
#define SEG_CODE_EXCA 0x0D // Execute-Only, conforming, accessed
#define SEG_CODE_EXRDC 0x0E // Execute/Read, conforming
#define SEG_CODE_EXRDCA 0x0F // Execute/Read, conforming, accessed
#define GDT_CODE_PL0 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \
SEG_LONG(0) | SEG_SIZE(1) | SEG_GRAN(1) | \
SEG_PRIV(0) | SEG_CODE_EXRD
#define GDT_DATA_PL0 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \
SEG_LONG(0) | SEG_SIZE(1) | SEG_GRAN(1) | \
SEG_PRIV(0) | SEG_DATA_RDWR
#define GDT_CODE_PL3 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \
SEG_LONG(0) | SEG_SIZE(1) | SEG_GRAN(1) | \
SEG_PRIV(3) | SEG_CODE_EXRD
#define GDT_DATA_PL3 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \
SEG_LONG(0) | SEG_SIZE(1) | SEG_GRAN(1) | \
SEG_PRIV(3) | SEG_DATA_RDWR
uint64_t create_descriptor(uint32_t base, uint32_t limit, uint16_t flag)
{
uint64_t descriptor;
// Create the high 32 bit segment
descriptor = limit & 0x000F0000; // set limit bits 19:16
descriptor |= (flag << 8) & 0x00F0FF00; // set type, p, dpl, s, g, d/b, l and avl fields
descriptor |= (base >> 16) & 0x000000FF; // set base bits 23:16
descriptor |= base & 0xFF000000; // set base bits 31:24
// Shift by 32 to allow for low part of segment
descriptor <<= 32;
// Create the low 32 bit segment
descriptor |= base << 16; // set base bits 15:0
descriptor |= limit & 0x0000FFFF; // set limit bits 15:0
return descriptor;
}

3
kernel/globals.c Normal file
View File

@@ -0,0 +1,3 @@
#include <lib/stream.h>
print_stream_t* kout;

View File

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

View File

@@ -1,28 +1,12 @@
#include <stdint.h>
#include <lib/print.h>
#include <lib/stream.h>
extern void halt();
extern void idt_load();
extern void reboot();
void kernel_main(void)
{
extern print_stream_t vga_print_stream;
extern print_stream_t* kout;
kout = &vga_print_stream;
kout->trunc();
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();
kprint("RockOS booting...");
}

11
kernel/lib/print.c Normal file
View File

@@ -0,0 +1,11 @@
#include "print.h"
#include "stream.h"
extern print_stream_t* kout;
void kprint(const char *str) {
while (*str) {
kout->putchar(*str);
str++;
}
}

6
kernel/lib/print.h Normal file
View File

@@ -0,0 +1,6 @@
#ifndef KLIBPRINT_H
#define KLIBPRINT_H
void kprint(const char* str);
#endif

3
kernel/lib/stream.c Normal file
View File

@@ -0,0 +1,3 @@
#include "stream.h"
print_stream_t* pout;

9
kernel/lib/stream.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef KSTREAM_H
#define KSTREAM_H
typedef struct {
void (*putchar)(char c);
void (*trunc)();
} print_stream_t;
#endif

28
kernel/linker.ld Normal file
View File

@@ -0,0 +1,28 @@
ENTRY(_start)
SECTIONS
{
. = 2M;
.text BLOCK(4K) : ALIGN(4K)
{
*(.multiboot)
*(.text)
}
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.rodata)
}
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
}
.bss BLOCK(4K) : ALIGN(4K)
{
*(COMMON)
*(.bss)
}
}

View File

@@ -1,118 +0,0 @@
.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 $16, %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
# some assembly stubs we can call from the kernel
.global idt_load
.extern idtr
idt_load:
lidt idtr
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