1、电脑加电后,先通过BIOS初始化硬件,然后从硬盘0磁道加载一扇区数据(MBR)到0x7C00~0x7E00内存,然后跳转到x7C00执行。
2、MBR让出0x7C00~0x7E00内存,将引导分区的数据(DBR)加载至该段内存。
3、DBR从分区中加载引导程序+初始化程序(这两程序合并成一个文件OSKRNL)到0x20000,按文件大小全部加载。DBR主要是分析分区格式加载所有内容
4、OSKRNL由osloader.bin+oskrnl.exe组成。
5、osloader.bin 前部分是实模式,后部分为保护模式
5.1 实模式:
5.1.1 通过BIOS中断取得显卡信息,查询VBE3.0保护模式接口
5.1.2开A20地址,
5.1.3 设置临时GDT,
5.1.4 跳转保护模式
5.2 保护模式
5.2.1 开启分页,
5.2.2 将oskrnl.exe按PE文件格式分段复制到相应内存。
5.2.3 设置栈,
5.2.4 跳转oskrnl.exe入口函数main。
6 oskrnl.exe内核初始化文件
6.1 字符屏初始化用于显示调试信息。
6.2 重新设置描述符GDT
6.3 设置中断向量 IDT
6.4 内存初始化
6.5 硬盘初始化, 这之后就可以从硬盘上加载单独的驱动文件
6.7 窗口管理器初始化
6.8 消息管理初始化
6.9 显卡初始化
6.10 键盘初始化
6.11 鼠标初始化
6.12 进程管理器初始化
6.13 时钟初始化
以上就是所有初始化流程,之后就可以创建新的进程。交替运行。
int _main(ULONG VBE_base,ULONG vbePhysBasePtr,ULONG diskID)
{
//已经在保护模式,调用BIOS中断还不会
console_init();
// print_msg("start init...");
//desc.c ,重新设置描述符,idt gdt
Init_Descriptor();
print_farmat_msg(" gdt init end.\n ");
//interrupt.c 将中断设定一个默认值
Init_idt();
print_farmat_msg("idt init end.\n ");
//lib/memorymanage.c 初始化物理、虚拟内存列表,mem.c 设置内存缺页中断处理程序
init_memory();
print_farmat_msg("Memory init end.\n ");
//硬盘,需要加载驱动,为了将内核减小,之后的初始化可以做成单独的文件
init_ide();
print_farmat_msg(" ide init .end. \n");
//以上是最基本的硬件初始化,
//核心最小化,从这里开始,可以读取磁盘上的文件,其余模块都可另行生成独立的文件
//多文件可能导致内存浪费,
//windows.c
//窗口 和信息初始化放在显卡前,有利于切换显示模式后,立即显示窗口
initWindows();
//lb 0x08040107d
print_farmat_msg("windows init end.\n");
//app/messages,创建消息队列
init_Messages();
print_farmat_msg(" message init end.\n");
init_debug_msg_win();
//lb 0x08040108e
print_farmat_msg("debug wnd init end.\n");
//初始化显示 //vbe.c 设置图形显示模式,显存映射
init_graphic(VBE_base,vbePhysBasePtr,CX_SCREEN,CY_SCREEN);
print_farmat_msg(" graphic init. end.\n");
refresh();
//print_farmat_msg("debug wnd init end.\n");
//显卡初始化过程调试信息还是以字符模式显示,之后以窗口显示
//刷新
//refresh();
//初始化键盘
init_keyboard();
print_farmat_msg("init_keyboard init \n");
init_mouse();
print_farmat_msg(" mouse init end.\n");
//lb 0x8040105b
//app/proc.c,建立进程
Init_Process();
print_farmat_msg(" process init end.\n");
create_process("0:hello.exe");
print_farmat_msg("Free PMem :%d \n",get_free_Physics());
//定时中断
Init_Timer();
print_farmat_msg("Timer init end.\n");
while (1)
{
print_farmat_msg("key mouse\n");
scan_to_key();
mouse_proc();
// keys_mouse_pro();
// print_msg(m);
//画鼠标
//DrawRact32(315,225,320,240,clBreak);
}// while (1)
return 1;
}//MAIN