-
Notifications
You must be signed in to change notification settings - Fork 66
/
Copy pathmain.c
190 lines (154 loc) · 5.13 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
#include <stdio.h>
#include <stdlib.h>
#include <sys/cdefs.h>
#include <sys/fcntl.h>
#include <kernel/fs.h>
#include <kernel/kernel.h>
#include <kernel/mm/page.h>
#include <kernel/mm/slab.h>
#include <kernel/sched.h>
#include <kernel/task.h>
#include <kernel/thread.h>
#include <kernel/compiler.h>
#include <kernel/softirq.h>
#include "platform.h"
extern char __early_stack_start__;
extern char __early_stack_end__;
extern char __text_start__;
extern char __text_end__;
extern char __rodata_start__;
extern char __rodata_end__;
extern char __data_start__;
extern char __data_end__;
extern char __bss_start__;
extern char __bss_end__;
extern char __pgmem_start__;
extern char __pgmem_end__;
extern char __pgmem_size__;
extern char __heap_start__;
extern char __heap_end__;
extern char __heap_size__;
void __do_idle(void);
void *do_idle(void *);
void mtdram_init(void);
void __printk_init(void);
int minishell(void *options);
void memdev_init(void);
void kernel_heap_init(void *heap_start, size_t heap_size);
void early_irq_init(void);
void init_IRQ(void);
struct task_info idle_task;
struct task_info main_task;
/* Select scheduler */
#ifndef SCHED_CLASS
#define SCHED_CLASS SCHED_CLASS_BITMAP
#endif
void print_version(void)
{
char buf[] = {0, 0};
int fd = open("/proc/version", 0);
while (read(fd, &buf, 1))
printk("%s", buf);
close(fd);
printk("\n");
}
void __weak *main(__unused void *arg)
{
print_version();
minishell(NULL);
return 0;
}
struct thread_info *thread_idle;
/* Cortex-M3/4 system initialization */
static void v7m_init(void)
{
/* enable UsageFault, BusFault, MemManage faults */
SCB->SHCSR |= (SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk |
SCB_SHCSR_MEMFAULTENA_Msk);
/* Configure the System Control Register to ensure 8-byte stack
alignment */
SCB->CCR |= SCB_CCR_STKALIGN_Msk;
// NVIC_SetPriority(DebugMonitor_IRQn, 0x0, 0);
NVIC_SetPriority(MemoryManagement_IRQn, 0x1);
NVIC_SetPriority(BusFault_IRQn, 0x1);
NVIC_SetPriority(UsageFault_IRQn, 0x1);
NVIC_SetPriority(SysTick_IRQn, 0x3);
/* Priority 0xF - debug_uart */
NVIC_SetPriority(SVCall_IRQn, 0xF);
NVIC_SetPriority(PendSV_IRQn, 0xF);
/* follow the architectural requirements */
__DSB();
}
void print_linker_sections(void)
{
printk("Memory map:\n");
printk(" .text = %08x--%08x %6d Bytes\n", &__text_start__,
&__text_end__, &__text_end__ - &__text_start__);
printk(" .rodata = %08x--%08x %6d Bytes\n", &__rodata_start__,
&__rodata_end__, &__rodata_end__ - &__rodata_start__);
printk(" .data = %08x--%08x %6d Bytes\n", &__data_start__,
&__data_end__, &__data_end__ - &__data_start__);
printk(" .bss = %08x--%08x %6d Bytes\n", &__bss_start__, &__bss_end__,
&__bss_end__ - &__bss_start__);
printk(" .heap = %08x--%08x %6d Bytes\n", &__heap_start__,
&__heap_end__, &__heap_end__ - &__heap_start__);
printk(" .pgmem = %08x--%08x %6d Bytes\n", &__pgmem_start__,
&__pgmem_end__, &__pgmem_end__ - &__pgmem_start__);
}
struct thread_info *start_kernel(void)
{
v7m_init();
early_irq_init();
init_IRQ();
/* TODO: Early console */
__printk_init();
/* initialize the kernel's malloc */
kernel_heap_init(&__heap_start__, (size_t) &__heap_size__);
print_linker_sections();
/* initialize the physical memory allocator */
show_page_bitmap(); // init_pages();
kmem_cache_init();
/* idle_thread is not added to the runqueue */
task_init(&idle_task);
thread_idle =
thread_create(do_idle, NULL, THREAD_PRIV_SUPERVISOR, 1024, &idle_task);
if (!thread_idle) {
printk("[!] Could not create system idle thread.\n");
return NULL;
}
printk("Created idle_thread at <%p>\n", thread_idle);
/* The main_thread is the user's entry-point to the system. It is not
* added to the runqueue because it has been implicitly "elected" when
* start_kernel() returns. */
task_init(&main_task);
struct thread_info *thread_main =
thread_create(main, NULL, THREAD_PRIV_USER, 1024, &main_task);
if (!thread_main) {
printk("[!] Could not create user main thread.\n");
return NULL;
}
printk("Created main_thread at <%p> with priority=%d\n", thread_main,
thread_main->ti_priority);
/* select a scheduling policy */
sched_select(SCHED_CLASS, thread_main);
/* Reclaim the early-stack physical memory. In the current context, no
* page allocation after this point are allowed. */
printk("Reclaim early stack's physical memory (%d Bytes, order=%d).\n",
&__early_stack_start__ - &__early_stack_end__,
size_to_page_order(2048));
free_pages((unsigned long) &__early_stack_end__, size_to_page_order(2048));
tmpfs_init();
proc_init();
memdev_init();
mtdram_init(); /* create a test mtdram device */
/* do the platform-specific inits */
__platform_init();
init_softirq();
printk("Kernel bootstrap done.\n--\n");
return thread_main;
}
void *do_idle(__unused void *arg)
{
for (;;)
__do_idle();
}