LF OS
Hobby operating system for amd64 with high ambitions
Loading...
Searching...
No Matches
main.c
Go to the documentation of this file.
1#include <config.h>
2
3#include <loader.h>
4
5#include <panic.h>
6#include <mm.h>
7#include <vm.h>
8#include <fbconsole.h>
9#include <sd.h>
10#include <sc.h>
11#include <elf.h>
12#include <scheduler.h>
13#include <string.h>
14#include <pic.h>
15#include <pit.h>
16#include <slab.h>
17#include <log.h>
18#include <efi.h>
19#include <mq.h>
20
22extern char build_id[];
23
24#define INIT_STEP(message, code) \
25 LAST_INIT_STEP = message; \
26 code \
27 logi("kernel", message);
28
29void nyi(int loop);
30void bootstrap_globals(void);
31void init_console(struct LoaderStruct* loaderStruct);
32void init_mm(struct LoaderStruct* loaderStruct);
33void init_symbols(struct LoaderStruct* loaderStruct);
34void init_init(struct LoaderStruct* loaderStruct);
35
36__attribute__ ((force_align_arg_pointer))
37void main(struct LoaderStruct* loaderStruct) {
38 logd("kernel", "Hello world!");
39
41 init_console(loaderStruct);
42
43 logi("kernel", "LF OS for amd64. Build: %s", build_id);
44 logi("kernel", "Initializing subsystems");
45
47 "Initialized physical memory management",
48 init_mm(loaderStruct);
49 )
50
52 "Initialized virtual memory management",
53 init_vm();
54 )
55
57 "Initialized framebuffer console backbuffer",
59 )
60
62 "Initialized UEFI runtime services",
63 init_efi(loaderStruct);
64 )
65
67 "Initialized service registry",
68 init_sd();
69 )
70
72 "Initialized mutex subsystem",
73 init_mutex();
75 )
76
78 "Initialized message queue subsystem",
80 )
81
83 "Initialized syscall interface",
84 init_gdt();
85 init_sc();
86 )
87
89 "Initialized scheduling and program execution",
91 )
92
94 "Initialized interrupt management",
95 init_pic();
96 init_pit();
97 )
98
100 "Read kernel symbols",
101 init_symbols(loaderStruct);
102 )
103
104 INIT_STEP(
105 "Cleaned bootup memory structures",
107 )
108
109 INIT_STEP(
110 "Prepared userspace",
111 init_init(loaderStruct);
112 )
113
114 logi("kernel", "Kernel initialization complete");
115
116 LAST_INIT_STEP = "Kernel initialization complete";
117 asm("sti");
118 while(1);
119}
120
121void init_console(struct LoaderStruct* loaderStruct) {
122 fbconsole_init(loaderStruct->fb_width, loaderStruct->fb_height, loaderStruct->fb_stride, (uint8_t*)loaderStruct->fb_location);
123
124 #include "../../bootlogo.c"
125 fbconsole_blt(lf_os_bootlogo.pixel_data, lf_os_bootlogo.width, lf_os_bootlogo.height, -(lf_os_bootlogo.width + 5), 5);
126}
127
128void init_mm(struct LoaderStruct* loaderStruct) {
129 logd("main.c", "loaderStruct->num_mem_desc: %lu", loaderStruct->num_mem_desc);
130
131 struct MemoryRegion* memoryRegions = (struct MemoryRegion*)((ptr_t)loaderStruct + loaderStruct->size);
132
133 SlabHeader* scratchpad_allocator = (SlabHeader*)ALLOCATOR_REGION_SCRATCHPAD.start;
135
136 mm_bootstrap(slab_alloc(scratchpad_allocator));
137
138 uint64_t pages_free = 0;
139 uint64_t pages_firmware = 0;
140
141 char desc_status[81];
142 memset(desc_status, 0, 81);
143
144 for(size_t i = 0; i < loaderStruct->num_mem_desc; ++i) {
145 struct MemoryRegion* desc = memoryRegions + i;
146
147 if(desc->flags & MEMORY_REGION_USABLE) {
148 desc_status[i % 80] = '-';
149 pages_free += desc->num_pages;
151 }
152 else if(desc->flags & MEMORY_REGION_FIRMWARE) {
153 desc_status[i % 80] = 'F';
154 pages_firmware += desc->num_pages;
155 }
156 else {
157 desc_status[i % 80] = 'X';
158 }
159
160 if((i % 80) == 79) {
161 logd("mm", "memory descriptor status: %s", desc_status);
162 memset(desc_status, 0, 81);
163 }
164 }
165
166 logd("mm", "memory descriptor status: %s", desc_status);
167
168 logi("mm", "%u pages (%B) free, %u (%B) firmware runtime memory",
169 pages_free, pages_free * 4096,
170 pages_firmware, pages_firmware* 4096
171 );
172}
173
174void init_symbols(struct LoaderStruct* loaderStruct) {
175 struct FileDescriptor* fileDescriptors = (struct FileDescriptor*)((ptr_t)loaderStruct + loaderStruct->size + (loaderStruct->num_mem_desc * sizeof(struct MemoryRegion)));
176
177 for(size_t i = 0; i < loaderStruct->num_files; ++i) {
178 struct FileDescriptor* desc = (fileDescriptors + i);
179 ptr_t kernel = (ptr_t)loaderStruct + desc->offset;
180
181 if(strcasecmp(desc->name, "kernel") == 0) {
183 }
184 }
185}
186
187void init_init(struct LoaderStruct* loaderStruct) {
188 struct FileDescriptor* fileDescriptors = (struct FileDescriptor*)(
189 (ptr_t)loaderStruct +
190 loaderStruct->size +
191 (loaderStruct->num_mem_desc * sizeof(struct MemoryRegion))
192 );
193
194 for(size_t i = 0; i < loaderStruct->num_files; ++i) {
195 struct FileDescriptor* desc = (fileDescriptors + i);
196 void* data = (uint8_t*)((ptr_t)loaderStruct + desc->offset);
197
198 if(strcasecmp(desc->name, "kernel") != 0) {
199 struct vm_table* context = vm_context_new();
200
201 ptr_t data_start = 0;
202 ptr_t data_end = 0;
203 ptr_t entrypoint = load_elf((ptr_t)data, context, &data_start, &data_end);
204
205 if(!entrypoint) {
206 logd("init" "Failed to run '%s'", desc->name);
207 }
208
209 start_task(context, entrypoint, data_start, data_end, desc->name);
210 }
211 }
212}
213
217
218/* noinline to have a default stop point for profiling */
219__attribute__((noinline)) void nyi(int loop) {
220 if(loop) {
221 panic_message("Not yet implemented");
222 }
223 else {
224 fbconsole_write("\n\x1b[38;5;9mNot yet implemented. Continuing");
225 }
226}
allocator_t kernel_alloc
Definition vm.c:737
uint64_t ptr_t
Definition arch.h:17
unsigned long uint64_t
Definition arch.h:14
unsigned char uint8_t
Definition arch.h:5
static const struct @2 lf_os_bootlogo
void init_condvar(void)
Definition condvar.c:16
void init_efi(struct LoaderStruct *loaderStruct)
Definition efi.c:53
ptr_t load_elf(ptr_t start, struct vm_table *context, ptr_t *data_start, ptr_t *data_end)
Definition elf.c:7
void * elf_load_symbols(ptr_t elf, allocator_t *alloc)
Definition elf.c:101
void fbconsole_init_backbuffer(void)
Definition fbconsole.c:85
void fbconsole_blt(const uint8_t *image, uint16_t width, uint16_t height, int16_t tx, int16_t ty)
Definition fbconsole.c:123
int fbconsole_write(char *string,...)
Definition fbconsole.c:223
void fbconsole_init(int width, int height, int stride, uint8_t *fb)
Definition fbconsole.c:31
char * LAST_INIT_STEP
Definition main.c:21
void init_symbols(struct LoaderStruct *loaderStruct)
Definition main.c:174
void init_console(struct LoaderStruct *loaderStruct)
Definition main.c:121
void bootstrap_globals(void)
Definition main.c:214
#define INIT_STEP(message, code)
Definition main.c:24
void init_init(struct LoaderStruct *loaderStruct)
Definition main.c:187
char build_id[]
Definition version.c:3
void nyi(int loop)
void init_mm(struct LoaderStruct *loaderStruct)
Definition main.c:128
#define ALLOCATOR_REGION_SCRATCHPAD
Definition vm.h:22
void * memset(void *dest, int c, size_t size)
Definition string.c:72
int strcasecmp(const char *s1, const char *s2)
Definition string.c:21
ptr_t entrypoint
Definition elf.h:15
uint16_t fb_stride
Pixels per scanline (including invisible pixels)
Definition loader.h:68
uint64_t offset
Offset where the file contents are located after LoaderStruct.
Definition loader.h:100
uint64_t flags
Flags for the memory region. See MEMORY_REGION_ defines.
Definition loader.h:89
uint64_t num_files
Number of loaded files.
Definition loader.h:74
uint16_t fb_width
Width of the framebuffer in visible pixels.
Definition loader.h:56
#define MEMORY_REGION_USABLE
memory is free to be used
Definition loader.h:10
size_t num_pages
Number of pages, where page size is 4096 bytes.
Definition loader.h:86
#define MEMORY_REGION_FIRMWARE
memory is in use by the firmware
Definition loader.h:12
ptr_t fb_location
Location of framebuffer as physical address.
Definition loader.h:53
uint64_t num_mem_desc
Number of memory descriptors.
Definition loader.h:71
uint16_t size
Definition loader.h:50
ptr_t start_address
Start of the region as physical address.
Definition loader.h:83
char name[256]
Zero terminated string with the name of the file.
Definition loader.h:94
uint16_t fb_height
Height of the framebuffer in pixels.
Definition loader.h:59
Main interface between loader and kernel.
Definition loader.h:44
Describes a single memory region.
Definition loader.h:81
#define logd(component, fmt,...)
Definition log.h:28
#define logi(component, fmt,...)
Definition log.h:36
void mm_bootstrap(ptr_t usable_page)
Definition mm.c:76
void mm_mark_physical_pages(ptr_t start, uint64_t count, mm_page_status_t status)
Definition mm.c:93
@ MM_FREE
Definition mm.h:13
void init_mq(allocator_t *alloc)
Definition mq.c:65
void init_mutex(void)
Definition mutex.c:20
void panic_message(const char *message)
Definition panic.c:64
void * kernel_symbols
Definition panic.c:14
void init_pic(void)
Definition pic.c:7
void init_pit(void)
Definition pit.c:4
int main(int argc, char *argv[])
Definition runner.cxx:50
void init_sc(void)
Definition sc.c:309
void init_gdt(void)
Definition sc.c:154
void start_task(struct vm_table *context, ptr_t entry, ptr_t data_start, ptr_t data_end, const char *name)
Definition scheduler.c:136
void init_scheduler(void)
Definition scheduler.c:87
void init_sd(void)
Definition sd.c:32
ptr_t slab_alloc(SlabHeader *slab)
Definition slab.c:22
void init_slab(ptr_t mem_start, ptr_t mem_end, size_t allocation_size)
Definition slab.c:6
Header of a Slab region.
Definition slab.h:10
static void ** data_end
Definition syscalls.h:82
void cleanup_boot_vm(void)
Definition vm.c:334
struct vm_table * vm_current_context(void)
Definition vm.c:743
struct vm_table * vm_context_new(void)
Definition vm.c:381
void init_vm(void)
Definition vm.c:228
struct vm_table * VM_KERNEL_CONTEXT
Definition vm.c:16
A paging table, when this is a PML4 it may also be called context.
Definition vm.c:42