AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
init.c
Go to the documentation of this file.
1
12
13#include <core/system.h>
14#include <core/string.h>
15#include <cpu/cpu.h>
16#include <mm/mm.h>
17#include <boot/multiboot.h>
18#include <boot/boot.h>
19
20/* The boot CPU's first page directory, just enough to map the kernel. */
22
23#define P _BV(0)
24#define RW _BV(1)
25#define PCD _BV(4)
26
27extern char kernel_end;
28char scratch[1024 * 1024] __aligned(PAGE_SIZE); /* 1 MiB for the boot page tables */
29
31static inline void enable_paging(uintptr_t page_directory)
32{
33 write_cr3(page_directory);
34 uint32_t cr0 = read_cr0();
35
36 /* without WP the kernel writes through read-only pages, e.g. into a
37 * copy-on-write page still shared with another process after fork */
38 write_cr0(cr0 | CR0_PG | CR0_WP);
39}
40
44static void switch_to_higher_half(void)
45{
46 uint32_t i;
47 uintptr_t entries;
48
49 /* clear the page directory */
50 memset((void *) _BSP_PD, 0, sizeof(_BSP_PD));
51
52 /* how many page tables it takes to map the kernel and what follows */
53 entries = ARCH_BOOT_MAPPED / TABLE_SIZE;
54
55 uint32_t *_BSP_PT = (uint32_t *) scratch;
56
57 /* each page mapped to itself */
58 for (i = 0; i < entries * 1024; ++i)
59 _BSP_PT[i] = (i * PAGE_SIZE) | P | RW;
60
61 /* the tables at 0, where the code runs now */
62 for (i = 0; i < entries; ++i)
63 _BSP_PD[i] = ((uint32_t) _BSP_PT + i * PAGE_SIZE) | P | RW;
64
65 /* the same tables in the higher half (3 GiB), where it runs next */
66 for (i = 0; i < entries; ++i)
67 _BSP_PD[768 + i] = ((uint32_t) _BSP_PT + i * PAGE_SIZE) | P | RW;
68
69 /* turn paging on with the boot CPU's page directory */
71}
72
78{
79 /* The segments are the boot loader's until x86_cpu_init() loads our
80 * GDT: Multiboot leaves them flat, 0 to 4 GiB (x86_64's bootstrap
81 * loads its own). First, map the kernel in the higher half. */
83
84 /* move the stack pointer to the higher half too */
85 extern void early_init_fix_stack(uintptr_t);
86 early_init_fix_stack(VMA((uintptr_t) 0));
87
88 /* set up the CPU and go on to the kernel */
89 extern void x86_cpu_init(void);
91
92 /* not reached; halt if it ever is */
93 for (;;)
94 asm volatile ("hlt;");
95}
#define PAGE_SIZE
Definition system.h:7
#define ARCH_BOOT_MAPPED
Definition mm.h:23
#define VMA(obj)
Definition mm.h:36
#define TABLE_SIZE
Definition system.h:15
#define CR0_WP
Definition cpu.h:156
#define CR0_PG
Definition cpu.h:155
#define P
Definition init.c:23
static void switch_to_higher_half(void)
Builds the boot page tables, which map the first ARCH_BOOT_MAPPED bytes of physical memory both at 0 ...
Definition init.c:44
char kernel_end
void x86_bootstrap()
Moves the kernel to the higher half and goes on to x86_cpu_init().
Definition init.c:77
char scratch[1024 *1024]
Definition init.c:28
volatile uint32_t _BSP_PD[1024]
Definition init.c:21
static void enable_paging(uintptr_t page_directory)
Loads the page directory into CR3, and turns paging on.
Definition init.c:31
#define RW
Definition init.c:24
void x86_cpu_init(void)
Sets up the boot CPU, memory and the platform, and starts the kernel (kmain()).
Definition init.c:34
#define __aligned(n)
Definition system.h:31
void * memset(void *dst, int c, size_t n)
Sets n bytes to c.
Definition libc.c:23
multiboot.h - Multiboot header file.
__SIZE_TYPE__ uintptr_t
Definition stddef.h:12
unsigned int uint32_t
Definition stddef.h:22