kernel

hobby kernel
git clone git://git.evenfri.duckdns.org/kernel.git
Log | Files | Refs | README | LICENSE

commit d6d3327785708026b67e49a0e674f9c48c10a9e4
parent 526b8472fe9bad12b6f433dcaedb0d595bf3a15f
Author: evenfri <evenfri256@gmail.com>
Date:   Sun,  2 Aug 2026 17:52:49 +0800

feat: mini vfs, change from GAS to NASM, update build

Diffstat:
Aboot.asm | 38++++++++++++++++++++++++++++++++++++++
Dboot.s | 38--------------------------------------
Mbuild/ar | 2+-
Mbuild/as | 35+++++++++++++++++++++++++++--------
Mbuild/cc | 2+-
Mbuild/ld | 3++-
Mbuild/mkcommon | 15+++++++++++----
Mbuild/mkhdr | 10+++++++++-
Mbuild/mklib | 10++++++----
Mbuild/mkmany | 2+-
Mbuild/mkone | 7++++---
Mdat.h | 14+++++++++-----
Mfns.h | 3+++
Agdt.asm | 42++++++++++++++++++++++++++++++++++++++++++
Dgdt.s | 39---------------------------------------
Minit.c | 40++++++++++++++++++++++++++++++----------
Aints.asm | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dints.s | 69---------------------------------------------------------------------
Akeyboard/keyboard_as.asm | 12++++++++++++
Dkeyboard/keyboard_as.s | 8--------
Mkeyboard/mkfile | 8+++-----
Mmkfile | 8+++++---
Avfs.c | 27+++++++++++++++++++++++++++
23 files changed, 304 insertions(+), 201 deletions(-)

diff --git a/boot.asm b/boot.asm @@ -0,0 +1,38 @@ +bits 32 + +mb_align equ 1 << 0 +mb_meminfo equ 1 << 1 +mb_flags equ mb_align | mb_meminfo +mb_magic equ 0x1badb002 +mb_checksum equ -(mb_magic + mb_flags) + +section .multiboot +align 4 + dd mb_magic + dd mb_flags + dd mb_checksum + +section .bss +align 16 +stack_bottom: + resb 16384 ; 16 KiB +stack_top: + +section .text +global _start +extern start_kernel + +_start: + ; setup stack + mov esp, stack_top + + ; enter the high-level kernel + push ebx + push eax + + call start_kernel + + cli +.loop: + hlt + jmp .loop diff --git a/boot.s b/boot.s @@ -1,38 +0,0 @@ -/* declare constants for the multiboot header. */ -.set ALIGN, 1<<0 -.set MEMINFO, 1<<1 -.set FLAGS, ALIGN | MEMINFO -.set MAGIC, 0x1BADB002 -.set CHECKSUM, -(MAGIC + FLAGS) - -.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: - /* setup stack */ - mov $stack_top, %esp - - /* enter the high-level kernel */ - - push %ebx - push %eax - - call start_kernel - - cli -1: hlt - jmp 1b - -.size _start, . - _start diff --git a/build/ar b/build/ar @@ -1,3 +1,3 @@ #!/bin/sh -exec i686-elf-ar "$@" +exec i686-elf-ar rsc "$@" diff --git a/build/as b/build/as @@ -1,16 +1,35 @@ #!/bin/sh + s_file="" -has_o="" +o_file="" -for arg; do - case "$arg" in - -o|-o*) has_o=1 ;; - *.s|*.S) s_file="$arg" ;; +while [ $# -gt 0 ]; do + case "$1" in + -o) + o_file="$2" + shift 2 + ;; + -o*) + o_file="${1#-o}" + shift 1 + ;; + *.s|*.S|*.asm) + s_file="$1" + shift 1 + ;; + *) + shift 1 + ;; esac done -if [ -n "$s_file" ] && [ -z "$has_o" ]; then - exec i686-elf-as "$@" -o "${s_file%.*}.o" +if [ -z "$s_file" ]; then + echo "as-wrapper error: no input assembly file provided" >&2 + exit 1 +fi + +if [ -z "$o_file" ]; then + o_file="${s_file%.*}.o" fi -exec i686-elf-as -c "$@" +exec nasm -f elf32 "$s_file" -o "$o_file" diff --git a/build/cc b/build/cc @@ -5,5 +5,5 @@ exec i686-elf-gcc -c \ -nostdlib \ -ffreestanding \ -fno-builtin \ - -I. \ + -I"$kernel" \ "$@" diff --git a/build/ld b/build/ld @@ -4,4 +4,5 @@ exec i686-elf-ld -T linker.ld \ -nostdlib \ -static \ -no-pie \ - "$@" + -o \ + "$@" \ diff --git a/build/mkcommon b/build/mkcommon @@ -1,13 +1,20 @@ %.$o: $hfiles # don't combine with following %.$o rules -%.$o: %.c +%.$o:Q: %.c + echo $qcc $cflags $stem.c $cc $cflags $stem.c -%.$o: %.cc +%.$o:Q: %.cc + echo $qcc $cflags $stem.cc $cc $cflags $stem.cc -%.$o: %.s - $as $aflags $stem.s +%.$o:Q: %.s + echo $qgas $gaflags $stem.s + $gas $gaflags $stem.s + +%.$o:Q: %.asm + echo $qas $aflags $stem.asm + $as $aflags $stem.asm nuke:V: nuke-common clean:V: clean-common diff --git a/build/mkhdr b/build/mkhdr @@ -2,13 +2,21 @@ o=o os=$o a=a +qcc=CC +qld=LD +qas=AS +qgas=AS +qar=AR + cc=cc ld=cc -as=as +as=nasm +gas=as ar=ar cflags= ldflags= aflags= +gaflags= cleanfiles= nukefiles= lib= diff --git a/build/mklib b/build/mklib @@ -1,11 +1,13 @@ default:V: $lib $lib(%):N: % -$lib: ${ofiles:%=$lib(%)} - $ar rsc $lib $newmember +$lib:Q: ${ofiles:%=$lib(%)} + echo $qar $lib + $ar $lib $newmember -&:n: &.$o - $ar rsc $lib $stem.$o +&:nQ: &.$o + echo $qar $lib $stem.$o + $ar $lib $stem.$o all install:V: $lib diff --git a/build/mkmany b/build/mkmany @@ -21,4 +21,4 @@ install:V: many-install cleanfiles=$cleanfiles $progs nukefiles=$nukefiles ${targ:%=$bin/%} -<build/mkcommon +<$kernel/build/mkcommon diff --git a/build/mkone b/build/mkone @@ -2,8 +2,9 @@ prog=$o.$targ all:V: $prog -$prog: $ofiles $lib # ${shortlib:%=$libdir/lib%.a} - $ld -o $target $prereq $ldflags +$prog:Q: $ofiles $lib # ${shortlib:%=$libdir/lib%.a} + echo $qld $target + $ld $target $prereq $ldflags install:V: $targ.install %.install:V: $bin/% @@ -14,4 +15,4 @@ $bin/%: $o.% cleanfiles=$cleanfiles $prog nukefiles=$nukefiles $bin/$targ -<build/mkcommon +<$kernel/build/mkcommon diff --git a/dat.h b/dat.h @@ -32,11 +32,11 @@ enum vga_color { /* idt */ typedef struct { - uint16_t isr_low; /* the lower 16 bits of the isr's address */ - uint16_t kernel_cs; /* the gdt segment selector that the cpu will load into cs before calling the isr */ - uint8_t reserved; /* set to zero */ - uint8_t attr; /* type and attributes; see the idt page */ - uint16_t isr_high; /* the higher 16 bits of the isr's address */ + uint16_t isr_low; /* the lower 16 bits of the isr's address */ + uint16_t kernel_cs; /* the gdt segment selector that the cpu will load into cs before calling the isr */ + uint8_t reserved; /* set to zero */ + uint8_t attr; /* type and attributes; see the idt page */ + uint16_t isr_high; /* the higher 16 bits of the isr's address */ } __attribute__((packed)) idt_entry_t; typedef struct { @@ -58,4 +58,8 @@ typedef void (*int_handler)(); #define irq_0 0x20 #define irq_8 0x28 +/* vfs */ +#define stdin 0 +#define stdout 1 + #endif /* dat_h */ diff --git a/fns.h b/fns.h @@ -53,5 +53,8 @@ void tty_clear(void); void tty_putchar(char c); void tty_write(const char* data, size_t size); +/* vfs */ +size_t vfs_read(unsigned int fd, void *buf, size_t size); +size_t vfs_write(unsigned int fd, void *buf, size_t size); #endif /* fns_h */ diff --git a/gdt.asm b/gdt.asm @@ -0,0 +1,42 @@ +bits 32 + +global gdt_init + +section .data +align 4 + +gdt_desc: + dw gdt_end - gdt - 1 ; limit + dd gdt ; start + +gdt: +gdt_null: + dd 0x00000000 + dd 0x00000000 + +gdt_code: + dd 0x0000ffff + dd 0x00cf9a00 + +gdt_data: + dd 0x0000ffff + dd 0x00cf9200 + +gdt_end: + +section .text + +gdt_init: + lgdt [gdt_desc] + + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + jmp 0x08:.clean_pipe + +.clean_pipe: + ret diff --git a/gdt.s b/gdt.s @@ -1,39 +0,0 @@ -.global gdt_init -.section .data -.align 4 - -gdt_desc: - .word gdt_end - gdt - 1 # limit - .long gdt # start - -gdt: -gdt_null: - .long 0x00000000 - .long 0x00000000 - -gdt_code: - .long 0x0000ffff - .long 0x00cf9a00 - -gdt_data: - .long 0x0000ffff - .long 0x00cf9200 - -gdt_end: - -.section .text - -gdt_init: - lgdt (gdt_desc) - - movw $0x10, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - movw %ax, %ss - - ljmp $0x08, $.clean_pipe - -.clean_pipe: - ret diff --git a/init.c b/init.c @@ -10,25 +10,45 @@ void multiboot(uint32_t magic, multiboot_info_t *mbi) { (void)*mbi; } -void start_kernel(uint32_t magic, multiboot_info_t *mbi){ - multiboot(magic, mbi); +void init() { + tty_init(); + vfs_write(stdout, "tty initialized\n", 16); gdt_init(); + vfs_write(stdout, "gdt initialized\n", 16); + idt_init(); - keyboard_init(); - + vfs_write(stdout, "idt initialized\n", 16); - tty_init(); - tty_write("Hello world\n", 12); + keyboard_init(); + vfs_write(stdout, "keyboard initialized\n", 21); +} +void bin_init_prog() { while(1) { - asm volatile("sti"); - char c = keyboard_read(); + char c; + size_t bytes = vfs_read(stdin, &c, 1); - if (c) { - tty_putchar(c); + if (bytes > 0) { + vfs_write(stdout, &c, 1); } else { asm volatile("hlt"); } } } + +void start_kernel(uint32_t magic, multiboot_info_t *mbi) { + multiboot(magic, mbi); + init(); + + bin_init_prog(); + + while(1) { + tty_clear(); + vfs_write(stdout, "kernel panic!\n", 14); + vfs_write(stdout, " no /bin/init program\n", 23); + + asm volatile("cli"); + asm volatile("hlt"); + } +} diff --git a/ints.asm b/ints.asm @@ -0,0 +1,73 @@ +bits 32 + +extern excp_handler + +%macro isr_no_err_stub 1 +global isr_stub_%1 +isr_stub_%1: + push dword 0 + push dword %1 + jmp isr_common_stub +%endmacro + +%macro isr_err_stub 1 +global isr_stub_%1 +isr_stub_%1: + push dword %1 + jmp isr_common_stub +%endmacro + +section .text + +isr_common_stub: + pusha + + mov ax, ds + push eax + + mov ax, 0x10 + mov ds, ax + mov es, ax + + call excp_handler + + pop eax + mov ds, ax + mov es, ax + + popa + add esp, 8 + iret + +isr_no_err_stub 0 +isr_no_err_stub 1 +isr_no_err_stub 2 +isr_no_err_stub 3 +isr_no_err_stub 4 +isr_no_err_stub 5 +isr_no_err_stub 6 +isr_no_err_stub 7 +isr_err_stub 8 +isr_no_err_stub 9 +isr_err_stub 10 +isr_err_stub 11 +isr_err_stub 12 +isr_err_stub 13 +isr_err_stub 14 +isr_no_err_stub 15 +isr_no_err_stub 16 +isr_err_stub 17 +isr_no_err_stub 18 +isr_no_err_stub 19 +isr_no_err_stub 20 +isr_no_err_stub 21 +isr_no_err_stub 22 +isr_no_err_stub 23 +isr_no_err_stub 24 +isr_no_err_stub 25 +isr_no_err_stub 26 +isr_no_err_stub 27 +isr_no_err_stub 28 +isr_no_err_stub 29 +isr_err_stub 30 +isr_no_err_stub 31 diff --git a/ints.s b/ints.s @@ -1,69 +0,0 @@ -.macro isr_no_err_stub num -.global isr_stub_\num - -isr_stub_\num: - pushl $0 - pushl $\num - jmp isr_common_stub -.endm - -.macro isr_err_stub num -.global isr_stub_\num - -isr_stub_\num: - pushl $\num /* interrupt number */ - jmp isr_common_stub -.endm - -isr_common_stub: - pusha - - movw %ds, %ax - pushl %eax - - movw $0x10, %ax - movw %ax, %ds - movw %ax, %es - - call excp_handler - - popl %eax - movw %ax, %ds - movw %ax, %es - - popa - addl $8, %esp - iret - -isr_no_err_stub 0 -isr_no_err_stub 1 -isr_no_err_stub 2 -isr_no_err_stub 3 -isr_no_err_stub 4 -isr_no_err_stub 5 -isr_no_err_stub 6 -isr_no_err_stub 7 -isr_err_stub 8 -isr_no_err_stub 9 -isr_err_stub 10 -isr_err_stub 11 -isr_err_stub 12 -isr_err_stub 13 -isr_err_stub 14 -isr_no_err_stub 15 -isr_no_err_stub 16 -isr_err_stub 17 -isr_no_err_stub 18 -isr_no_err_stub 19 -isr_no_err_stub 20 -isr_no_err_stub 21 -isr_no_err_stub 22 -isr_no_err_stub 23 -isr_no_err_stub 24 -isr_no_err_stub 25 -isr_no_err_stub 26 -isr_no_err_stub 27 -isr_no_err_stub 28 -isr_no_err_stub 29 -isr_err_stub 30 -isr_no_err_stub 31 diff --git a/keyboard/keyboard_as.asm b/keyboard/keyboard_as.asm @@ -0,0 +1,12 @@ +bits 32 + +global keyboard_asm +extern keyboard_handler + +section .text + +keyboard_asm: + pusha + call keyboard_handler + popa + iret diff --git a/keyboard/keyboard_as.s b/keyboard/keyboard_as.s @@ -1,8 +0,0 @@ -.global keyboard_asm -.extern keyboard_handler - -keyboard_asm: - pusha - call keyboard_handler - popa - iret diff --git a/keyboard/mkfile b/keyboard/mkfile @@ -1,11 +1,9 @@ -<../build/mkhdr +<$kernel/build/mkhdr as = ../build/as cc = ../build/cc ar = ../build/ar -cflags = -I.. - ofiles = keyboard_as.$o \ keyboard.$o @@ -13,5 +11,5 @@ hfiles = keyboard.h lib = built-in.a -<../build/mkcommon -<../build/mklib +<$kernel/build/mklib +<$kernel/build/mkcommon diff --git a/mkfile b/mkfile @@ -1,5 +1,6 @@ -<build/mkhdr -<build/mkdirs +kernel = `{pwd} +<$kernel/build/mkhdr +<$kernel/build/mkdirs as = ./build/as cc = ./build/cc @@ -15,6 +16,7 @@ ofiles = boot.$o \ idt.$o \ ints.$o \ tty.$o \ + vfs.$o \ init.$o \ strlen.$o @@ -23,4 +25,4 @@ hfiles = fns.h \ targ = kernel -<build/mkone +<$kernel/build/mkone diff --git a/vfs.c b/vfs.c @@ -0,0 +1,27 @@ +#include <dat.h> +#include <fns.h> +#include <keyboard/keyboard.h> + +size_t vfs_read(unsigned int fd, void *buf, size_t size) { + if (fd == stdin) { + char *ptr = (char *)buf; + size_t bytes_read = 0; + + for (size_t i = 0; i < size; i++) { + ptr[i] = keyboard_read(); + bytes_read++; + } + return bytes_read; + } + + return 0; +} + +size_t vfs_write(unsigned int fd, void *buf, size_t size) { + if (fd == stdout) { + tty_write((const char *)buf, size); + return size; + } + + return 0; +}