Working on loading modules from filesystem & Creating symbol file for modules to link against
This commit is contained in:
parent
41ef288243
commit
7fba027497
|
|
@ -2,13 +2,13 @@
|
||||||
|
|
||||||
## Basic Information
|
## Basic Information
|
||||||
|
|
||||||
Kimi's Bootloader is a custom booting solution and the default bootloader for Kimi's OS on legacy BIOS systems. It loads the default x86 GDT to be used by the Kernel.
|
Kimi's Bootloader is a custom booting solution and the default bootloader for Kimi's OS on legacy BIOS systems. It loads the default x86 GDT to be used by the Kernel, and maps the kernel to any address as specified in it's ELF program header.
|
||||||
|
|
||||||
The bootloader also sets the video mode to the closest mode present to Standard definition, and obtains the BIOS memory map to be passed to the Kernel.
|
The bootloader also sets the video mode to the closest mode present to Standard definition, and obtains the BIOS memory map to be passed to the Kernel.
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
It's not very feature rich, cause it's whole purpose was to do the bare minimum for what i needed for my own project. While I've made bootloaders before, they've typically only consisted of some code that gets a memory map, sets up a gdt, and says "fuck it, i'll load these next 64 sectors, why not?" however i wanted to do everything a bit better, make things easier on me in the long run, and now i have a bootloader that does the same thing but
|
It's not very feature rich, cause it's whole purpose was to do the bare minimum for what i needed for my own project. While I've made bootloaders before, they've typically only consisted of some code that gets a memory map, sets up a gdt, and says "screw it, i'll load these next 64 sectors, why not?" however i wanted to do everything a bit better, make things easier on me in the long run, and now i have a bootloader that does the same thing but
|
||||||
|
|
||||||
- searches and loads any file named "kernel.elf" into memory (only supports legacy filenames for now, LFNs to be supported at a later date
|
- searches and loads any file named "kernel.elf" into memory (only supports legacy filenames for now, LFNs to be supported at a later date
|
||||||
|
|
||||||
|
|
@ -44,6 +44,8 @@ It's not very feature rich, cause it's whole purpose was to do the bare minimum
|
||||||
- Selecting better load/copy addresses
|
- Selecting better load/copy addresses
|
||||||
|
|
||||||
On loading the kernel file, I just pick some arbitrary, pre-chosen spot and say "yeah, this is good enough", but in reality i have on average only 400-ish kb until i start to overwrite the EBDA (which is bad, i do enjoy having ACPI). Instead, I want to implement a function to actually look for a continuous point in memory that is large enough to hold the entire kernel (ELF headers and all) without accidentally overwriting important information or running into memory barriers/holes.
|
On loading the kernel file, I just pick some arbitrary, pre-chosen spot and say "yeah, this is good enough", but in reality i have on average only 400-ish kb until i start to overwrite the EBDA (which is bad, i do enjoy having ACPI). Instead, I want to implement a function to actually look for a continuous point in memory that is large enough to hold the entire kernel (ELF headers and all) without accidentally overwriting important information or running into memory barriers/holes.
|
||||||
|
|
||||||
|
Edit (11/21/24) I actually added this a *while* ago, but never updated the docs cause I'm forgetful
|
||||||
|
|
||||||
### A20 Line
|
### A20 Line
|
||||||
|
|
||||||
|
|
@ -66,6 +68,7 @@ If all else fails, the bootloader will attempt to enable the a20 line by using t
|
||||||
While any GDT loaded for the Kernel will work, once the Kernel wants to load user processes, it will fail to locate user segments in the GDT if the one loaded is not the one expected. Because of this, the Kernel will need to load it's own if the one it wants is not loaded by this bootloader. To allow for detection, the key "0xaa55" is written at the end of the GDT, marking the last segment invalid, but allowing for the detection of the correct GDT being pre-loaded. This detection will only occurr during boot time, and unexpected writes will cause the Kernel to crash.
|
While any GDT loaded for the Kernel will work, once the Kernel wants to load user processes, it will fail to locate user segments in the GDT if the one loaded is not the one expected. Because of this, the Kernel will need to load it's own if the one it wants is not loaded by this bootloader. To allow for detection, the key "0xaa55" is written at the end of the GDT, marking the last segment invalid, but allowing for the detection of the correct GDT being pre-loaded. This detection will only occurr during boot time, and unexpected writes will cause the Kernel to crash.
|
||||||
|
|
||||||
#### GDT Layout:
|
#### GDT Layout:
|
||||||
|
|
||||||
|INDEX|ENTRY TYPE|
|
|INDEX|ENTRY TYPE|
|
||||||
|-----|----------|
|
|-----|----------|
|
||||||
|0x00 |Null Entry|
|
|0x00 |Null Entry|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
OUTPUT_FORMAT(elf32-i386)
|
OUTPUT_FORMAT(elf32-i386)
|
||||||
/* OUTPUT_FORMAT(binary) */
|
/* OUTPUT_FORMAT(binary) */
|
||||||
OUTPUT(kernel.elf)
|
/* OUTPUT(kernel.elf) */
|
||||||
/* SEARCH_DIR(bin/kernel) */
|
/* SEARCH_DIR(bin/kernel) */
|
||||||
SECTIONS{
|
SECTIONS{
|
||||||
. = 0xc0000000;
|
. = 0xc0000000;
|
||||||
|
|
|
||||||
3
makefile
3
makefile
|
|
@ -22,7 +22,8 @@ kernel:
|
||||||
sh c_build_helper.sh
|
sh c_build_helper.sh
|
||||||
nasm src/kernel/arch_i386/idt.s -o bin/kernel/idt.o -felf32
|
nasm src/kernel/arch_i386/idt.s -o bin/kernel/idt.o -felf32
|
||||||
# ld -T linker.ld bin/kernel/entry.o bin/kernel/*.o -melf_i386
|
# ld -T linker.ld bin/kernel/entry.o bin/kernel/*.o -melf_i386
|
||||||
ld -T linker.ld bin/kernel/*.o -melf_i386
|
ld -T linker.ld bin/kernel/*.o -melf_i386 -o kernel.elf
|
||||||
|
ld -T linker.ld -o kernel_interface.elf -r -R kernel.elf -melf_i386
|
||||||
# %.o: $(SRCS)
|
# %.o: $(SRCS)
|
||||||
# mkdir -p bin/kernel/$(shell dirname $@)
|
# mkdir -p bin/kernel/$(shell dirname $@)
|
||||||
# $(CC) $(CFLAGS) $< -o $@
|
# $(CC) $(CFLAGS) $< -o $@
|
||||||
|
|
|
||||||
|
|
@ -306,6 +306,7 @@ part_2:
|
||||||
; debug
|
; debug
|
||||||
mov edi, kernel_file
|
mov edi, kernel_file
|
||||||
call open_file
|
call open_file
|
||||||
|
add edx, 0x40000;is 200 kb enough for a filesystem diver and a disk driver?
|
||||||
call find_kpaddr
|
call find_kpaddr
|
||||||
; debug
|
; debug
|
||||||
mov esi, eax
|
mov esi, eax
|
||||||
|
|
@ -317,6 +318,7 @@ part_2:
|
||||||
; debug
|
; debug
|
||||||
mov esi, [kload_paddr]
|
mov esi, [kload_paddr]
|
||||||
call load_elf
|
call load_elf
|
||||||
|
|
||||||
; debug
|
; debug
|
||||||
push eax
|
push eax
|
||||||
cli
|
cli
|
||||||
|
|
@ -705,7 +707,9 @@ load_elf:
|
||||||
je .map_next
|
je .map_next
|
||||||
xor edx, edx
|
xor edx, edx
|
||||||
shr ecx, 12
|
shr ecx, 12
|
||||||
|
add dword [kload_paddr], 0x1000
|
||||||
.mloop:
|
.mloop:
|
||||||
|
add dword [kload_paddr], 0x1000;
|
||||||
call map_addr
|
call map_addr
|
||||||
add edi, 0x1000
|
add edi, 0x1000
|
||||||
add esi, 0x1000
|
add esi, 0x1000
|
||||||
|
|
@ -768,7 +772,28 @@ map_addr:
|
||||||
pop ebp
|
pop ebp
|
||||||
ret
|
ret
|
||||||
jmp $
|
jmp $
|
||||||
|
map_pages_id:
|
||||||
|
;edx = page count
|
||||||
|
;eax = addr
|
||||||
|
push esi
|
||||||
|
push edi
|
||||||
|
push edx
|
||||||
|
cmp eax, 1 << 22
|
||||||
|
je .ret
|
||||||
|
mov esi, eax
|
||||||
|
.loop:
|
||||||
|
cmp edx, 0
|
||||||
|
je .ret
|
||||||
|
mov edi, esi
|
||||||
|
call map_addr
|
||||||
|
add esi, 0x1000
|
||||||
|
dec edx
|
||||||
|
jmp .loop
|
||||||
|
.ret:
|
||||||
|
pop edx
|
||||||
|
pop edi
|
||||||
|
pop esi
|
||||||
|
ret;
|
||||||
;kernel info
|
;kernel info
|
||||||
k_info:
|
k_info:
|
||||||
.memory_map_ptr: dd 0x2000
|
.memory_map_ptr: dd 0x2000
|
||||||
|
|
@ -778,13 +803,16 @@ k_info:
|
||||||
.xres: dw 80
|
.xres: dw 80
|
||||||
.yres: dw 25
|
.yres: dw 25
|
||||||
.framebuffer_ptr: dd 0xb8000
|
.framebuffer_ptr: dd 0xb8000
|
||||||
.loaded_modules: dd 0
|
.loaded_modules: dd disk_module_struct
|
||||||
.loaded_module_c: dd 0
|
|
||||||
;loaded_modules points to a struct array containing a ptr to the entry point of each pre-loaded module to be executed during startup
|
;loaded_modules points to a struct array containing a ptr to the entry point of each pre-loaded module to be executed during startup
|
||||||
;module_struct:
|
disk_module_struct:
|
||||||
;.entry_point: dd 0
|
.ptr: dd 0
|
||||||
; cr3_load: dd 0
|
.type: dd 1
|
||||||
;.type: db 0
|
.next_entry: dd fs_module_struct
|
||||||
|
fs_module_struct:
|
||||||
|
.ptr: dd 0
|
||||||
|
.type: dd 2
|
||||||
|
.next_entry: dd 0
|
||||||
kernel_file: db "kernel", 0x0, 0x0, "elf"
|
kernel_file: db "kernel", 0x0, 0x0, "elf"
|
||||||
loaded_fat_block: dd 0
|
loaded_fat_block: dd 0
|
||||||
last_allocated_pgtb: dd 0x10000
|
last_allocated_pgtb: dd 0x10000
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ extern void kmain(kernel_info_t *kernel_info){
|
||||||
pic_setmask(0xfe, PIC1_DATA);
|
pic_setmask(0xfe, PIC1_DATA);
|
||||||
//TODO: Map and load filesystem and disk modules
|
//TODO: Map and load filesystem and disk modules
|
||||||
//TODO: Start Initial Process
|
//TODO: Start Initial Process
|
||||||
|
|
||||||
init_scheduler();
|
init_scheduler();
|
||||||
thread_start(pid0);
|
thread_start(pid0);
|
||||||
enable_interrupts();
|
enable_interrupts();
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,12 @@
|
||||||
#include "../drivers/serial.h"
|
#include "../drivers/serial.h"
|
||||||
#include "interrupts.h"
|
#include "interrupts.h"
|
||||||
|
|
||||||
|
typedef struct module_linked_list{
|
||||||
|
void *ptr;
|
||||||
|
uint32_t type;
|
||||||
|
struct module_linked_list *link;
|
||||||
|
}__attribute__((packed)) kernel_module_t;
|
||||||
|
|
||||||
typedef struct kernel_info{
|
typedef struct kernel_info{
|
||||||
void *mmap_ptr;
|
void *mmap_ptr;
|
||||||
uint16_t mmap_entry_count;
|
uint16_t mmap_entry_count;
|
||||||
|
|
@ -11,8 +17,14 @@ typedef struct kernel_info{
|
||||||
uint16_t monitor_x_resolution;
|
uint16_t monitor_x_resolution;
|
||||||
uint16_t monitor_y_resolution;
|
uint16_t monitor_y_resolution;
|
||||||
void *framebuffer;
|
void *framebuffer;
|
||||||
void *loaded_modues;
|
kernel_module_t *loaded_modules;
|
||||||
uint32_t loaded_module_count;
|
// uint32_t loaded_module_count;
|
||||||
}__attribute__((packed)) kernel_info_t;
|
}__attribute__((packed)) kernel_info_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define MODULE_TYPE_DISK 1
|
||||||
|
#define MODULE_TYPE_FS 2
|
||||||
|
#define MODULE_TYPE_EXT 3
|
||||||
|
#define MODULE_TYPE_VIDEO 4
|
||||||
|
|
||||||
#define PANIC(m) kernel_panic(m, 0)
|
#define PANIC(m) kernel_panic(m, 0)
|
||||||
Loading…
Reference in New Issue