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:
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;
+}