[amd64] Add initrd loading support
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
void *memset(void *blk, int v, size_t sz);
|
||||
void *memcpy(void *dst, const void *src, size_t sz);
|
||||
int strcmp(const char *a, const char *b);
|
||||
int strncmp(const char *a, const char *b, size_t lim);
|
||||
|
||||
// Debug utils
|
||||
void panic(const char *s);
|
||||
|
||||
+12
-4
@@ -56,7 +56,8 @@ kernel_CFLAGS=-ffreestanding \
|
||||
DIRS+=$(O)/sys/amd64/mm \
|
||||
$(O)/sys/amd64/hw \
|
||||
$(O)/sys/amd64/acpi \
|
||||
$(O)/sys/amd64/sys
|
||||
$(O)/sys/amd64/sys \
|
||||
$(O)/sys/amd64/image/boot/grub
|
||||
# add .inc includes for asm
|
||||
HEADERS+=$(shell find include -name "*.inc")
|
||||
|
||||
@@ -73,7 +74,7 @@ $(O)/sys/%.o: sys/%.c $(HEADERS)
|
||||
@$(CC64) $(kernel_CFLAGS) -c -o $@ $<
|
||||
|
||||
### Kernel loader build
|
||||
TARGETS+=$(O)/sys/amd64/loader.elf $(O)/sys/amd64/kernel.elf
|
||||
TARGETS+=$(O)/sys/amd64/image.iso
|
||||
DIRS+=$(O)/sys/amd64/loader
|
||||
loader_OBJS+=$(O)/sys/amd64/loader/boot.o \
|
||||
$(O)/sys/amd64/loader/loader.o \
|
||||
@@ -109,7 +110,14 @@ QEMU_OPTS?=-nographic \
|
||||
-serial mon:stdio \
|
||||
-m 512
|
||||
|
||||
$(O)/sys/amd64/image.iso: $(O)/sys/amd64/kernel.elf $(O)/sys/amd64/loader.elf sys/amd64/grub.cfg
|
||||
@printf " ISO\t%s\n" $(@:$(O)/%=%)
|
||||
@cp sys/amd64/grub.cfg $(O)/sys/amd64/image/boot/grub/grub.cfg
|
||||
@cp $(O)/sys/amd64/kernel.elf $(O)/sys/amd64/image/boot/kernel
|
||||
@cp $(O)/sys/amd64/loader.elf $(O)/sys/amd64/image/boot/loader
|
||||
@grub-mkrescue -o $(O)/sys/amd64/image.iso $(O)/sys/amd64/image 2>/dev/null
|
||||
|
||||
qemu: all
|
||||
@$(QEMU_BIN) \
|
||||
-kernel $(O)/sys/amd64/loader.elf \
|
||||
-initrd $(O)/sys/amd64/kernel.elf $(QEMU_OPTS)
|
||||
-cdrom $(O)/sys/amd64/image.iso \
|
||||
$(QEMU_OPTS)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
menuentry "yggdrasil" {
|
||||
multiboot /boot/loader
|
||||
module /boot/kernel kernel
|
||||
module /boot/test-mod.img initrd
|
||||
}
|
||||
@@ -91,9 +91,37 @@ void loader_main(uint32_t magic, struct multiboot_info *mb_info) {
|
||||
loader_data.multiboot_info_ptr = (uintptr_t) mb_info;
|
||||
|
||||
struct multiboot_mod_list *mod_list = (struct multiboot_mod_list *) (uintptr_t) mb_info->mods_addr;
|
||||
const char *kernel_cmdline = NULL;
|
||||
uintptr_t kernel_mod = 0;
|
||||
uintptr_t initrd_mod = 0;
|
||||
|
||||
if (mb_info->mods_count != 1) {
|
||||
panic("Expected 1 module");
|
||||
if (mb_info->mods_count == 1) {
|
||||
// Only kernel is provided, ignore cmdline
|
||||
kernel_mod = mod_list[0].mod_start;
|
||||
} else if (mb_info->mods_count == 2) {
|
||||
// initrd and kernel provided
|
||||
// Find out which is which
|
||||
|
||||
for (size_t i = 0; i < mb_info->mods_count; ++i) {
|
||||
if (!strncmp((const char *) (uintptr_t) mod_list[i].cmdline, "kernel", 6)) {
|
||||
if (kernel_mod) {
|
||||
panic("Two \"kernel\"s provided!");
|
||||
}
|
||||
kernel_mod = mod_list[i].mod_start;
|
||||
kernel_cmdline = (const char *) (uintptr_t) mod_list[i].cmdline;
|
||||
} else {
|
||||
if (initrd_mod) {
|
||||
panic("Two \"initrd\"s provided!");
|
||||
}
|
||||
initrd_mod = mod_list[i].mod_start;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
panic("More than two modules provided");
|
||||
}
|
||||
|
||||
if (!kernel_mod) {
|
||||
panic("No kernel to load");
|
||||
}
|
||||
|
||||
// Calculate boundaries so we don't overwrite something accidentally
|
||||
@@ -103,6 +131,11 @@ void loader_main(uint32_t magic, struct multiboot_info *mb_info) {
|
||||
}
|
||||
}
|
||||
|
||||
if (kernel_cmdline) {
|
||||
puts("Kernel cmdline: ");
|
||||
puts(kernel_cmdline);
|
||||
putc('\n');
|
||||
}
|
||||
puts("Modules end addr: ");
|
||||
putx(modules_end);
|
||||
putc('\n');
|
||||
|
||||
@@ -23,6 +23,16 @@ int strcmp(const char *a, const char *b) {
|
||||
return *a != *b;
|
||||
}
|
||||
|
||||
int strncmp(const char *a, const char *b, size_t n) {
|
||||
size_t c = 0;
|
||||
for (; c < n && (*a || *b); ++c, ++a, ++b) {
|
||||
if (*a != *b) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void outb(uint16_t addr, uint8_t v) {
|
||||
asm volatile("outb %0, %1"::"a"(v), "Nd"(addr));
|
||||
}
|
||||
@@ -74,6 +84,7 @@ void putx(uint64_t v) {
|
||||
|
||||
void panic(const char *s) {
|
||||
memset((void *) 0xB8000, 0, 80 * 25 * 2);
|
||||
puts(s);
|
||||
|
||||
for (size_t i = 0; *s; ++i, ++s) {
|
||||
((uint16_t *) 0xB8000)[i] = *s | 0x700;
|
||||
|
||||
Reference in New Issue
Block a user