Skip to content

Commit 912f7ef

Browse files
committed
boot: Implement module parsing and finding kernel
1 parent 8fbb499 commit 912f7ef

11 files changed

Lines changed: 210 additions & 6 deletions

File tree

boot/boot.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,48 @@
1+
#include <gdt.h>
12
#include <multiboot.h>
3+
#include <string.h>
4+
#include <elf.h>
5+
6+
void setup_longmode()
7+
{
8+
// TODO(coditva):
9+
}
10+
11+
void jump_to_kernel(void *kernel_entry, multiboot_info_t *multiboot_info)
12+
{
13+
// TODO(coditva):
14+
(void)(kernel_entry);
15+
(void)(multiboot_info);
16+
}
217

318
void lmain(multiboot_info_t *multiboot_info, uint32_t multiboot_magic)
419
{
520
if (multiboot_magic != MULTIBOOT_EAX_MAGIC) {
621
return;
722
}
823

9-
(void)(multiboot_info);
24+
gdt_init();
25+
26+
void *kernel_entry = 0x0;
27+
char *kernel_mod_name = "kernel";
28+
29+
if (multiboot_info->flags & MULTIBOOT_FLAG_MODS) {
30+
for (uint32_t i = 0; i < multiboot_info->mods_count; i++) {
31+
32+
multiboot_mod_t *module = (multiboot_mod_t *)
33+
(multiboot_info->mods_addr + (i * sizeof(multiboot_mod_t)));
34+
35+
if (strcmp((char *)&module->string, kernel_mod_name) == 0) {
36+
kernel_entry = elf_load((void *)(uintptr_t)module->mod_start,
37+
(void *)(uintptr_t)module->mod_end);
38+
(void)(kernel_entry);
39+
40+
}
41+
}
42+
}
43+
44+
setup_longmode();
45+
jump_to_kernel(kernel_entry, multiboot_info);
1046

1147
while (1) {
1248
; /* nop */

boot/elf.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include <elf.h>
2+
3+
void * elf_load(void *start_address, void *end_address)
4+
{
5+
// TODO(coditva):
6+
(void)(start_address);
7+
(void)(end_address);
8+
return 0x0;
9+
}
10+

boot/gdt.asm

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
; vi:filetype=nasm
2+
3+
gdtr dw 0
4+
dd 0
5+
6+
; TODO: Think about moving to "higher half kernel"
7+
8+
global gdt_load
9+
gdt_load:
10+
mov eax, [esp + 4] ; load gdt address
11+
mov [gdtr + 2], eax
12+
mov ax, [esp + 8] ; load gdt size
13+
mov [gdtr], ax
14+
lgdt [gdtr] ; load idt
15+
ret
16+
17+
global reload_segments
18+
reload_segments:
19+
jmp 0x08:complete_reload_segments ; load 0x08 into code selector (CS)
20+
21+
complete_reload_segments:
22+
mov ax, 0x10 ; load 0x10 into data selector
23+
mov ds, ax
24+
mov es, ax
25+
mov fs, ax
26+
mov gs, ax
27+
mov ss, ax
28+
ret

boot/gdt.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include <gdt.h>
2+
3+
gdt_entry_t gdt[GDT_SIZE];
4+
extern void gdt_load(gdt_entry_t *, uint16_t size);
5+
6+
void gdt_set_entry(uint32_t offset, uint32_t base, uint32_t limit,
7+
uint8_t access_byte)
8+
{
9+
if (limit > 65536) { /* adjust granularity */
10+
limit = limit >> 12;
11+
gdt[offset].flags_limit_1 = 0xc0;
12+
} else {
13+
gdt[offset].flags_limit_1 = 0x40;
14+
}
15+
16+
gdt[offset].base_0 = (uint16_t)base & 0xff;
17+
gdt[offset].base_1 = (uint8_t)(base >> 16) & 0xff;
18+
gdt[offset].base_2 = (uint8_t)(base >> 24) & 0xff;
19+
20+
gdt[offset].limit_0 = (uint16_t)limit & 0xff;
21+
gdt[offset].flags_limit_1 |= (uint16_t)(limit >> 16) & 0xf;
22+
23+
gdt[offset].access_byte = access_byte;
24+
}
25+
26+
void gdt_init(void)
27+
{
28+
/* first entry is NULL entry */
29+
gdt_set_entry(0, 0, 0, 0);
30+
31+
/* TODO: Remove sepecial numbers from these statements */
32+
/* kernel code and data segments */
33+
gdt_set_entry(1, CODE_SEGMENT_OFFSET, CODE_SEGMENT_SIZE, 0x9a);
34+
gdt_set_entry(2, DATA_SEGMENT_OFFSET, DATA_SEGMENT_SIZE, 0x92);
35+
36+
/* user code and data segments */
37+
gdt_set_entry(3, CODE_SEGMENT_OFFSET, CODE_SEGMENT_SIZE, 0xfa);
38+
gdt_set_entry(4, DATA_SEGMENT_OFFSET, DATA_SEGMENT_SIZE, 0xf2);
39+
40+
/* TODO: Setup tss (what?) */
41+
/* TODO: Setup ldt? */
42+
43+
gdt_load(gdt, GDT_SIZE * sizeof(gdt_entry_t) - 1);
44+
reload_segments();
45+
}

boot/include/elf.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef LOAD_ELF_H_O54VNAX7
2+
#define LOAD_ELF_H_O54VNAX7
3+
4+
void * elf_load(void *, void *);
5+
6+
#endif /* end of include guard: LOAD_ELF_H_O54VNAX7 */

boot/include/gdt.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#ifndef GDT_H_9RIWT3SN
2+
#define GDT_H_9RIWT3SN
3+
4+
#include <types.h>
5+
6+
/**
7+
* The structure of the entries in the GDT.
8+
*/
9+
typedef struct _gdt_entry_t {
10+
uint16_t limit_0;
11+
uint16_t base_0;
12+
uint8_t base_1;
13+
uint8_t access_byte;
14+
uint8_t flags_limit_1;
15+
uint8_t base_2;
16+
} __attribute__((packed)) gdt_entry_t;
17+
18+
#define GDT_SIZE 3
19+
20+
typedef struct _gdt_ptr_t {
21+
uint16_t limit;
22+
uint32_t base;
23+
} __attribute__((packed)) gdt_ptr_t;
24+
25+
void gdt_init(void);
26+
void reload_segments(void);
27+
28+
/* Using flat setup. TODO: Separate code and data segments(?) */
29+
#define CODE_SEGMENT_OFFSET 0x0
30+
#define CODE_SEGMENT_SIZE 0xffffffff
31+
#define DATA_SEGMENT_OFFSET 0x0
32+
#define DATA_SEGMENT_SIZE 0xffffffff
33+
34+
#endif /* end of include guard: GDT_H_9RIWT3SN */

boot/include/multiboot.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
11
#ifndef MULTIBOOT_H_RKNBOMGQ
22
#define MULTIBOOT_H_RKNBOMGQ
33

4-
typedef unsigned long uint32_t;
5-
typedef unsigned int uint16_t;
6-
typedef unsigned long long uint64_t;
7-
typedef unsigned char uint8_t;
8-
4+
#include <types.h>
95

106
/* magic numbers for multiboot. these help us verify that multiboot structure is
117
* indeed valid. */
@@ -128,6 +124,14 @@ typedef struct _multiboot_memory_map_t {
128124
} __attribute__((packed)) multiboot_memory_map_t;
129125

130126

127+
typedef struct _multiboot_mod_t {
128+
uint16_t mod_start;
129+
uint16_t mod_end;
130+
uint16_t string;
131+
uint16_t reserved;
132+
} __attribute__((packed)) multiboot_mod_t;
133+
134+
131135
#define FOREACH_MEMORY_MAP(MMAP, INFO) \
132136
for(multiboot_memory_map_t *(MMAP) = \
133137
(multiboot_memory_map_t *)(uintptr_t)((INFO)->mmap_addr); \

boot/include/string.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef STRING_H_UQGSNPBM
2+
#define STRING_H_UQGSNPBM
3+
4+
int strcmp(const char*, const char*);
5+
6+
#endif /* end of include guard: STRING_H_UQGSNPBM */

boot/include/types.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#ifndef TYPES_H_AO8U0VTC
2+
#define TYPES_H_AO8U0VTC
3+
4+
typedef unsigned char uint8_t;
5+
typedef unsigned short uint16_t;
6+
typedef unsigned long uint32_t;
7+
typedef unsigned long long uint64_t;
8+
9+
typedef uint32_t uintptr_t;
10+
11+
#endif /* end of include guard: TYPES_H_AO8U0VTC */

boot/load_elf.c

Whitespace-only changes.

0 commit comments

Comments
 (0)