summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordzwdz2021-07-17 19:03:45 +0200
committerdzwdz2021-07-17 19:03:45 +0200
commitf84c55f194df088c291fc4359ccec1305be456ce (patch)
tree0476907b089c174adc6e72cfe780134cbd9cbe89
parent895108bbba356aa39920a42df1587211e424ef8b (diff)
basic boot module support
This loads a file from the boot disk into memory. Currently it just gets printed, but it's going to become a real executable soon.
-rw-r--r--Makefile6
-rw-r--r--grub.cfg1
-rw-r--r--src/arch/i386/boot.c20
-rw-r--r--src/arch/i386/boot.s1
-rw-r--r--src/arch/i386/multiboot.h31
-rw-r--r--src/kernel/main.c4
-rw-r--r--src/kernel/main.h10
-rw-r--r--src/test_module1
8 files changed, 69 insertions, 5 deletions
diff --git a/Makefile b/Makefile
index 666c226..4b9ab02 100644
--- a/Makefile
+++ b/Makefile
@@ -9,13 +9,17 @@ QFLAGS = -no-reboot -d guest_errors,int,pcall,cpu_reset
OBJ = $(patsubst src/%.s,out/obj/%.s.o,$(shell find src/ -type f -name '*.s'))
OBJ += $(patsubst src/%.c,out/obj/%.c.o,$(shell find src/ -type f -name '*.c'))
-out/boot.iso: out/fs/boot/kernel.bin out/fs/boot/grub/grub.cfg
+out/boot.iso: out/fs/boot/kernel.bin out/fs/boot/grub/grub.cfg out/fs/boot/init
grub-mkrescue -o $@ out/fs/
out/fs/boot/grub/grub.cfg: grub.cfg
@mkdir -p $(@D)
cp $< $@
+out/fs/boot/init: src/test_module
+ @mkdir -p $(@D)
+ cp $< $@
+
out/fs/boot/kernel.bin: $(OBJ)
@mkdir -p $(@D)
$(CC) $(LFLAGS) -T linker.ld $^ -o $@
diff --git a/grub.cfg b/grub.cfg
index 5f66c18..36f116d 100644
--- a/grub.cfg
+++ b/grub.cfg
@@ -2,4 +2,5 @@ set timeout=0
menuentry "Camellia" {
multiboot /boot/kernel.bin
+ module /boot/init
}
diff --git a/src/arch/i386/boot.c b/src/arch/i386/boot.c
index 37e1aff..242d070 100644
--- a/src/arch/i386/boot.c
+++ b/src/arch/i386/boot.c
@@ -1,11 +1,16 @@
#include <arch/generic.h>
#include <arch/i386/gdt.h>
#include <arch/i386/interrupts/idt.h>
+#include <arch/i386/multiboot.h>
#include <arch/i386/sysenter.h>
#include <arch/i386/tty.h>
#include <kernel/main.h>
+#include <kernel/panic.h>
-void kmain_early() {
+void kmain_early(struct multiboot_info *multiboot) {
+ struct kmain_info info;
+
+ // setup some basic stuff
tty_clear();
log_const("gdt...");
gdt_init();
@@ -13,5 +18,16 @@ void kmain_early() {
idt_init();
log_const("sysenter...");
sysenter_setup();
- kmain();
+
+ { // find the init module
+ struct multiboot_mod *module = &multiboot->mods[0];
+ if (multiboot->mods_count < 1) {
+ log_const("can't find init! ");
+ panic();
+ }
+ info.init.at = module->start;
+ info.init.size = module->end - module->start;
+ }
+
+ kmain(info);
}
diff --git a/src/arch/i386/boot.s b/src/arch/i386/boot.s
index 2578e87..74de9b7 100644
--- a/src/arch/i386/boot.s
+++ b/src/arch/i386/boot.s
@@ -3,6 +3,7 @@
.type _start, @function
_start:
mov $stack_top, %esp
+ push %ebx // address of the Multiboot struct
call kmain_early
.global halt_cpu
diff --git a/src/arch/i386/multiboot.h b/src/arch/i386/multiboot.h
new file mode 100644
index 0000000..f030247
--- /dev/null
+++ b/src/arch/i386/multiboot.h
@@ -0,0 +1,31 @@
+#pragma once
+#include <stdint.h>
+
+// TODO assert that pointers have 4 bytes.
+
+struct multiboot_mod {
+ void *start;
+ void *end;
+ const char *str;
+ uint32_t _reserved;
+} __attribute__((packed));
+
+struct multiboot_info {
+ uint32_t flag_mem : 1;
+ uint32_t flag_boot_device : 1;
+ uint32_t flag_cmdline : 1;
+ uint32_t flag_mods : 1;
+ uint32_t _flag_other : 28; // unimplemented
+
+ uint32_t mem_lower;
+ uint32_t mem_upper;
+
+ uint32_t boot_device;
+
+ const char *cmdline;
+
+ uint32_t mods_count;
+ struct multiboot_mod *mods;
+
+ // [...]
+} __attribute__((packed));
diff --git a/src/kernel/main.c b/src/kernel/main.c
index d2d7dda..d2f2e7f 100644
--- a/src/kernel/main.c
+++ b/src/kernel/main.c
@@ -1,11 +1,13 @@
#include <arch/generic.h>
+#include <kernel/main.h>
#include <kernel/mem.h>
#include <kernel/panic.h>
#include <kernel/proc.h>
void r3_test();
-void kmain() {
+void kmain(struct kmain_info info) {
+ log_write(info.init.at, info.init.size);
log_const("mem...");
mem_init();
diff --git a/src/kernel/main.h b/src/kernel/main.h
index 6f27386..f7f5f04 100644
--- a/src/kernel/main.h
+++ b/src/kernel/main.h
@@ -1,3 +1,11 @@
#pragma once
+#include <stddef.h>
-void kmain();
+struct kmain_info {
+ struct {
+ void *at; // page aligned
+ size_t size;
+ } init; // a boot module loaded by GRUB, containing the initrd driver
+};
+
+void kmain(struct kmain_info);
diff --git a/src/test_module b/src/test_module
new file mode 100644
index 0000000..4e809fd
--- /dev/null
+++ b/src/test_module
@@ -0,0 +1 @@
+[init binary goes here]