BIOS、BOOTLOADER
1.LInux操作系统的引导
1.1Linux是如何从硬盘中读出的
1.2LInux在启动的时候是如何拿到硬件参数的
1.3Linux在初始运行中都做了什么
trap.c | trap_init() |
mktime.c | time_init() |
sched.c | sched_init() |
BIOS/BOOTLOADER:
由PC机的BIOS(0xFFFF0是BIOS存储的总线地址)把bootsect从某个固定的地址拿到了内存中的某个固定地址(0x90000),并且进行了一系列的硬件初始化和参数设置
bootsect.s
磁盘引导块程序,在磁盘的第一个扇区中的程序(0磁道,0磁头,1扇区)
作用:首先将后续的setup.s代码从磁盘中加载到紧接着bootsect.s的地方
再显示屏上显示loading system 再将system(操作系统)模块加载到0x10000的地方
最后跳转到setup.s中去执行
setup.s
解析BIOS/BOOTLOADER传递来的参数
设置系统内核运行的LDT(局部描述符)、LDT(中断描述符寄存器)、全局描述符(设置全局描述符寄存器)
设置中断控制芯片,进入保护模式运行(svc32保护模式、设置寄存器中的值)
跳转到system模块的最前面的代码运行(head.s)
head.s
加载内核运行时的各数据段寄存器,重新设置中断描述符表
开启内核正常运行时的协处理器等资源
设置内存管理的分页机制
跳转到mian.c开始运行
2.系统初始化函数main.c
// 根设备号 -> ROOT_DEV; 高速缓存末端地址 -> buffer_memory_end;
// 机器内存数 -> memory_end;主内存开始地址 -> main_memory_start;
//设置操作系统的根文件
ROOT_DEV = ORIG_ROOT_DEV;
//设置操作系统驱动参数
drive_info = DRIVE_INFO;
//解析setup.s代码后获取系统内存参数
//设置系统的内存大小,系统本身内存内存大小=1Mb 字节+扩展内存(k)*1024 字节
memory_end = (1<<20) + (EXT_MEM_K<<10);// 内存大小=1Mb 字节+扩展内存(k)*1024 字节。
memory_end &= 0xfffff000; // 忽略不到4Kb(1 页)的内存数。
if (memory_end > 16*1024*1024) // 如果内存超过16Mb,则按16Mb 计。
memory_end = 16*1024*1024;
//设置高速缓冲区的大小
if (memory_end > 12*1024*1024) // 如果内存>12Mb,则设置缓冲区末端=4Mb
buffer_memory_end = 4*1024*1024;
else if (memory_end > 6*1024*1024) // 否则如果内存>6Mb,则设置缓冲区末端=2Mb
buffer_memory_end = 2*1024*1024;
else
buffer_memory_end = 1*1024*1024;// 否则则设置缓冲区末端=1Mb
main_memory_start = buffer_memory_end;// 主内存起始位置=
#ifdef RAMDISK // 如果定义了虚拟盘,则主内存将减少。
main_memory_start += rd_init(main_memory_start, RAMDISK*1024);
#endif