-
Notifications
You must be signed in to change notification settings - Fork 3
/
zlox_kernel.c
209 lines (166 loc) · 5.41 KB
/
zlox_kernel.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
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/*zlox_kernel.c Defines the C-code kernel entry point, calls initialisation routines.*/
#include "zlox_monitor.h"
#include "zlox_descriptor_tables.h"
#include "zlox_time.h"
#include "zlox_paging.h"
#include "zlox_kheap.h"
#include "zlox_multiboot.h"
#include "zlox_fs.h"
#include "zlox_initrd.h"
#include "zlox_task.h"
#include "zlox_syscall.h"
#include "zlox_keyboard.h"
#include "zlox_elf.h"
#include "zlox_ata.h"
#include "zlox_iso.h"
#include "zlox_pci.h"
#include "zlox_network.h"
#include "zlox_ps2.h"
#include "zlox_mouse.h"
#include "zlox_vga.h"
#include "zlox_my_windows.h"
#include "zlox_audio.h"
#include "zlox_usb.h"
ZLOX_VOID zlox_test_ps2_keyboard();
extern ZLOX_UINT32 placement_address;
extern ZLOX_TASK * current_task;
extern ZLOX_BOOL ide_can_dma;
//zlox_vga.c
extern ZLOX_UINT8 * lfb_vid_memory;
//extern ZLOX_BOOL atapi_vmware_warning;
ZLOX_UINT32 initial_esp;
//zenglOX kernel main entry
ZLOX_SINT32 zlox_kernel_main(ZLOX_MULTIBOOT * mboot_ptr, ZLOX_UINT32 initial_stack)
{
ZLOX_UINT32 initrd_location;
ZLOX_UINT32 initrd_end;
initial_esp = initial_stack;
// init gdt and idt
zlox_init_descriptor_tables();
// Initialise the screen (by clearing it)
zlox_monitor_clear();
asm volatile("sti");
// 将PIT定时器的频率设为50Hz,即每20ms产生一次时间中断
zlox_init_timer(50);
// 将PIT定时器的频率设为1000Hz,即每1ms产生一次时间中断
//zlox_init_timer(1000);
ZLOX_ASSERT(mboot_ptr->mods_count > 0);
initrd_location = *((ZLOX_UINT32*)mboot_ptr->mods_addr);
initrd_end = *((ZLOX_UINT32*)(mboot_ptr->mods_addr+4));
// grub会将initrd模块放置到kernel内核后面,所以将placement_address设置为initrd_end,
// 这样zlox_init_paging分配页表时才能将initrd考虑进来,同时堆分配空间时就不会覆盖到initrd里的内容
placement_address = initrd_end;
zlox_klog_init();
lfb_vid_memory = (ZLOX_UINT8 *)((ZLOX_MULTIBOOT_VBE_INFO *)(mboot_ptr->vbe_mode_info))->physbase;
ZLOX_SINT32 audio_reset = zlox_audio_reset();
if(audio_reset == 0)
zlox_audio_alloc_res_before_init();
// 开启分页,并创建堆
zlox_init_paging_start((ZLOX_UINT32)(mboot_ptr->mem_lower + mboot_ptr->mem_upper));
zlox_pci_init();
zlox_pci_list();
ZLOX_BOOL network_stat = zlox_network_init();
if(zlox_vga_set_mode(ZLOX_VGA_MODE_VBE_1024X768X32) == -1)
{
while(1) // set vbe failed! so we died
;
}
else
zlox_monitor_write("vga [vbe] mode is init now!\n");
zlox_init_my_mouse();
if(network_stat == ZLOX_TRUE)
zlox_monitor_write("network is init now!\n");
zlox_init_paging_end();
if(audio_reset == 0)
zlox_audio_init();
zlox_usb_init();
/*for (ZLOX_UINT16 y = 0; y < 768; y++) {
for (ZLOX_UINT16 x = 0; x < 1024; x++) {
ZLOX_UINT8 f = y % 255;
((ZLOX_UINT32 *)lfb_vid_memory)[x + y * 1024] = 0xFF000000 | (f * 0x10000) | (0 * 0x100) | 0;
}
}*/
// 初始化任务系统
zlox_initialise_tasking();
// Initialise the initial ramdisk, and set it as the filesystem root.
fs_root = zlox_initialise_initrd(initrd_location);
// 初始化系统调用
zlox_initialise_syscalls();
if(zlox_ps2_init() == ZLOX_TRUE)
{
zlox_syscall_monitor_write("PS2 Controller is init now!\n");
if(zlox_initKeyboard() == ZLOX_TRUE)
{
zlox_syscall_monitor_write("=========================\n");
zlox_syscall_monitor_write("Keyboard is init now!\n");
zlox_syscall_monitor_write("=========================\n");
}
zlox_mouse_install();
zlox_syscall_monitor_write("mouse is install now!\n");
}
zlox_init_ata();
zlox_syscall_monitor_write("ata is init now!\n");
// 切换到ring 3的用户模式
zlox_switch_to_user_mode();
zlox_syscall_monitor_write("I'm in user mode!\n");
zlox_syscall_monitor_write("welcome to zenglOX v");
ZLOX_SINT32 major,minor,revision;
zlox_syscall_get_version(&major,&minor,&revision);
zlox_syscall_monitor_write_dec(major);
zlox_syscall_monitor_put('.');
zlox_syscall_monitor_write_dec(minor);
zlox_syscall_monitor_put('.');
zlox_syscall_monitor_write_dec(revision);
zlox_syscall_monitor_write("! I will execve a desktop\n"
"you can input some command: ls , ps , cat , uname , cpuid , shell ,"
" reboot , shutdown , ata , mount , unmount , testoverflow , fdisk , "
"format , file , vga , dhcp isoget...\n\n");
if(ide_can_dma)
zlox_syscall_monitor_write("Congratulation! you can use DMA mode with ATA Drive! ");
else
zlox_syscall_monitor_write("you can only use PIO mode... ");
zlox_syscall_monitor_write("\n\n");
asm ("finit");
ZLOX_SINT32 sec=0;
ZLOX_UINT32 origtick = zlox_syscall_timer_get_tick();
ZLOX_UINT32 frequency = zlox_syscall_timer_get_frequency();
while(sec < 3)
{
while(ZLOX_TRUE)
{
zlox_syscall_idle_cpu();
ZLOX_UINT32 curtick = zlox_syscall_timer_get_tick();
if((curtick - origtick) > frequency)
break;
}
zlox_syscall_monitor_write("..");
sec++;
origtick = zlox_syscall_timer_get_tick();
}
//while(1)
// ;
zlox_syscall_monitor_disable_scroll();
zlox_syscall_execve("desktop");
zlox_syscall_wait(current_task);
ZLOX_SINT32 ret;
ZLOX_TASK_MSG msg;
while(ZLOX_TRUE)
{
ret = zlox_syscall_get_tskmsg(current_task,&msg,ZLOX_TRUE);
if(ret != 1)
{
zlox_syscall_wait(current_task);
// 只剩下一个初始任务了,就再创建一个desktop
if(current_task->next == 0)
{
zlox_syscall_execve("desktop");
zlox_syscall_wait(current_task);
}
}
else if(msg.type == ZLOX_MT_TASK_FINISH)
{
zlox_syscall_finish(msg.finish_task.exit_task);
}
}
return 0;
}