[amd64] Add initrd loading support

This commit is contained in:
Mark
2019-09-24 18:15:17 +03:00
parent 131f6963ab
commit b0b7667ec3
5 changed files with 64 additions and 6 deletions
+1
View File
@@ -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
View File
@@ -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)
+5
View File
@@ -0,0 +1,5 @@
menuentry "yggdrasil" {
multiboot /boot/loader
module /boot/kernel kernel
module /boot/test-mod.img initrd
}
+35 -2
View File
@@ -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');
+11
View File
@@ -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;