os

Toy OS
git clone git://git.margiolis.net/os.git
Log | Files | Refs | README | LICENSE

commit a29e0f76250ff463373a8a83c2d47001abcda2ce
parent 629d6ca6128374bf9f62bac126465881fcda180a
Author: Christos Margiolis <christos@margiolis.net>
Date:   Wed,  8 Dec 2021 05:27:43 +0200

nothing important

Diffstat:
MMakefile | 4++--
Mi386/u.h | 3++-
Mkern/Makefile | 54+++++++++++++++++++++++++++++-------------------------
Mkern/boot.s | 18++++++++++++++----
Mkern/idt.c | 7++++---
Mkern/idt.h | 2+-
Mkern/kern_main.c | 4++++
Mkern/libk.c | 13+++++++------
Akern/link.ld | 24++++++++++++++++++++++++
Mkern/timer.c | 18++++++++++++------
Mkern/vga.c | 6+++---
11 files changed, 102 insertions(+), 51 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,10 +1,10 @@ -TGTDIR = build +TGTDIR= build all: cd kern && make install clean && cd - run: - qemu-system-i386 -hdd ${TGTDIR}/os.bin + qemu-system-i386 -hda ${TGTDIR}/os.bin -serial stdio clean: rm -rf ${TGTDIR} diff --git a/i386/u.h b/i386/u.h @@ -10,6 +10,7 @@ typedef unsigned long u_long; typedef unsigned long long u_vlong; typedef long long vlong; +/* FIXME: get rid of _t */ typedef signed char int8_t; typedef unsigned char u_int8_t; typedef unsigned short u_int16_t; @@ -19,7 +20,7 @@ typedef int int32_t; typedef unsigned long u_int64_t; typedef long int64_t; -//typedef u_int64_t size_t; +typedef u_int64_t u_size; typedef __va_list va_list; #define va_start(ap, last) __builtin_va_start((ap), (last)) diff --git a/kern/Makefile b/kern/Makefile @@ -1,33 +1,37 @@ -BIN = os.bin -BINDIR = ../build - -CC = cc -ASM = nasm -LD = ld -ARCH=i386 -ARCHINCDIR = ../${ARCH} -INCDIR=../include -CFLAGS = -g -m32 -nostdlib -ffreestanding -Wall -Wextra -std=c99 -O2 \ - -I${ARCHINCDIR} -I${INCDIR} -LDFLAGS = -Ttext 0x1000 --oformat binary - -BOOTFILE = boot.s -BOOT_BIN = boot.bin -KERNEL_BIN = kernel.bin -SRC = *.c *.s -OBJ = kern_main.o \ - libk.o \ - idt.o \ - intr.o \ - vga.o \ - kbd.o \ - timer.o \ - vm_page.o +BIN= os.bin +BINDIR= ../build + +CC= cc +ASM= nasm +LD= ld +ARCH= i386 # FIXME: make this automatic +ARCHINCDIR= ../${ARCH} +INCDIR= ../include +LINKSCRIPT= link.ld +CFLAGS= -g -m32 -Wall -Wextra -Werror -std=c99 -O2 \ + -nostdlib -nodefaultlibs \ + -ffreestanding -fno-stack-protector -fno-builtin \ + -I${ARCHINCDIR} -I${INCDIR} +LDFLAGS= -T${LINKSCRIPT} --oformat binary -melf_${ARCH} + +BOOTFILE= boot.s +BOOT_BIN= boot.bin +KERNEL_BIN= kernel.bin +SRC= *.c *.s +OBJ= kern_main.o \ + libk.o \ + idt.o \ + intr.o \ + vga.o \ + kbd.o \ + timer.o \ + vm_page.o all: options ${BIN} options: @echo ${BIN} build options + @echo ARCH = ${ARCH} @echo CC = ${CC} @echo ASM = ${ASM} @echo LD = ${LD} diff --git a/kern/boot.s b/kern/boot.s @@ -4,6 +4,7 @@ MAGICOFF equ (0x7c00 + 510) KERNOFF equ 0x1000 +STACKSIZE equ 0x1000 section .text global _start @@ -11,13 +12,15 @@ section .text ; Entry point. _start: cli ; Disable interrupts. + jmp 0x0000:zeroseg +zeroseg: xor ax, ax ; Clear segment registers. mov ds, ax mov es, ax mov fs, ax mov gs, ax - mov ss, ax - mov bp, 0x9000 ; Set the base and stack pointers. + mov ss, ax ; Stack starts at 0. + mov bp, _start ; Set the base and stack pointers. mov sp, bp cld ; Read strings from low to high. sti ; Enable interrupts back. @@ -195,7 +198,7 @@ diskerr: disk_packet: .size db 0x10 .zero db 0x00 - .count dw 0x0f + .count dw 0x0030 ; FIXME: i don't know why this works... .off16 dw KERNOFF .seg16 dw 0x0000 .lba dq 1 @@ -263,7 +266,7 @@ pm_init: mov gs, ax mov ss, ax - mov ebp, 0x90000 + mov ebp, kern_stack_top mov esp, ebp call kernel_exec @@ -294,9 +297,16 @@ putchar: str_diskerr: db "Error loading disk.", 0x0a, 0x0d, 0x00 str_a20_fail: db "The A20 Line is disabled", 0x0a, 0x0d, 0x00 +; Hard disk. BOOTDRV: db 0x80 ; Padding to 512 bytes. The last 2 bytes will come from the magic number. times 510 - ($ - $$) db 0 ; Magic number. dw 0xaa55 + +section .bss + align 4096 +kern_stack_bottom: equ $ + resb STACKSIZE +kern_stack_top: diff --git a/kern/idt.c b/kern/idt.c @@ -158,12 +158,13 @@ intr_handler(struct reg *r) } void -intr_register_handler(u_int8_t intrno, intrhand_t handler) +intr_register_handler(int intrno, intrhand_t handler) { + if (intrno < 0 || intrno >= NINT) + panic("invalid interrupt number: %d\n", intrno); isr[intrno] = handler; } -/* FIXME: not #08? */ void dump_regs(struct reg *r) { @@ -173,7 +174,7 @@ dump_regs(struct reg *r) r->r_esp, r->r_ebp, r->r_esi, r->r_edi); printf("ds=%#08x \tes=%#08x \tfs=%#08x \tgs=%#08x\n", r->r_ds, r->r_es, r->r_fs, r->r_gs); - printf("eip=%#08x\tcs=%#08x \tss=%#08x \teflags=%08x\n", + printf("eip=%#08x\tcs=%#08x \tss=%#08x \teflags=%#08x\n", r->r_eip, r->r_cs, r->r_ss, r->r_eflags); printf("int=%#08x\terr=%#08x\tuesp=%#08x\n", r->r_intrno, r->r_err, r->r_uesp); diff --git a/kern/idt.h b/kern/idt.h @@ -76,7 +76,7 @@ typedef void (*intrhand_t)(struct reg *); void idt_init(void); void intr_handler(struct reg *); -void intr_register_handler(u_int8_t, intrhand_t); +void intr_register_handler(int, intrhand_t); void dump_regs(struct reg *); /* FIXME: move elsewhere? */ #endif /* _IDT_H_ */ diff --git a/kern/kern_main.c b/kern/kern_main.c @@ -1,3 +1,4 @@ +#include <libc.h> #include "kbd.h" #include "idt.h" #include "io.h" @@ -5,6 +6,9 @@ #include "vm_page.h" #include "vga.h" +/* TODO: make kset/unsetenv */ +/* TODO: make device framework */ +/* TODO: add a config */ /* TODO: make sysctl */ void kern_main(void) diff --git a/kern/libk.c b/kern/libk.c @@ -62,12 +62,13 @@ itoa(char *str, long num, int base, int size, int precision, int flags) size--; } } - if (flags & SPECIAL) { - if (base == 8) - size--; - else if (base == 16) - size -= 2; - } + /* FIXME: what? */ + /*if (flags & SPECIAL) {*/ + /*if (base == 8)*/ + /*size--;*/ + /*else if (base == 16)*/ + /*size -= 2;*/ + /*}*/ i = 0; if (!num) tmp[i++] = '0'; diff --git a/kern/link.ld b/kern/link.ld @@ -0,0 +1,24 @@ +ENTRY(_start) +SECTIONS +{ + .text 0x1000 : { + *(.text) + . = ALIGN(4096); + } + + .rodata : { + *(.rodata) + . = ALIGN(4096); + } + + .data : { + *(.data) + . = ALIGN(4096); + } + + .bss : { + *(COMMON) + *(.bss) + . = ALIGN(4096); + } +} diff --git a/kern/timer.c b/kern/timer.c @@ -5,28 +5,34 @@ #define TIMER_CMD 0x43 #define TIMER_DATA 0x40 +#define SQUARE_WAVE 0x36 +#define FREQ 1193180 +#define HZ 100 static void timer_callback(struct reg *); -static u_int32_t timer_ticks = 0; +static u_int32_t ticks = 0; static void timer_callback(struct reg *r) { - timer_ticks++; + ticks++; UNUSED(r); } void timer_init(void) { - const u_int32_t hz = 100; - u_int32_t div = 1193180 / hz; + u_int32_t div = FREQ / HZ; intr_register_handler(IRQ0, timer_callback); /* Repating mode. */ - outb(TIMER_CMD, 0x36); + outb(TIMER_CMD, SQUARE_WAVE); outb(TIMER_DATA, (u_int8_t)(div & 0xff)); - outb(TIMER_DATA, (u_int8_t)((div >> 8) & 0xff)); + outb(TIMER_DATA, (u_int8_t)(div >> 8)); printf("timer on irq 0\n"); + + /*outb(TIMER_CMD, SQUARE_WAVE);*/ + /*outb(TIMER_DATA, 0);*/ + /*outb(TIMER_DATA, 0);*/ } diff --git a/kern/vga.c b/kern/vga.c @@ -9,14 +9,14 @@ #define CURS_CMD 0x3d4 #define CURS_DATA 0x3d5 -struct vga_info { +struct vga { volatile u_int16_t *buf; size_t row; size_t col; u_int8_t color; }; -static struct vga_info vga; +static struct vga vga; void vga_clear(u_int8_t fg, u_int8_t bg) @@ -56,7 +56,7 @@ vga_putc(char c) vga.col = 0; break; case '\t': - vga.col += 8; + vga.col += 4; break; default: vga.buf[vga.row * VGA_COLS + vga.col] = VGA_PUTC(c);