1.Linux操作系统的引导
1.1Linux是如何从硬盘中读出的
1.2Linux在启动的时候是如何拿到硬件参数的
1.3Linux在初始运行中都做了什么
BIOS/BOOTLOADER
由PC机BIOS(0xffff0是BIOS存储的总线地址)把bootsect从某个固定的地址拿到了内存中某个固定地址(0.11版本为0x90000),并且进行了一系列硬件初始化和参数设置
bootsect.s
磁盘引导块程序,在磁盘的第一个扇区中的程序(0磁道 0磁头 1扇区)
作用:首先将后续的setup.s代码从磁盘中加载到紧接着bootsect.s的地方
在显示屏上显示Loading system 再将system模块(操作系统)加载到0x10000的地方
最后跳转到setup.s中去运行
setup.s
解析BIOS/BOOTLOADER传递来的参数
设置系统内核运行的LDT(局部描述符) IDT(中断描述符寄存器)全局描述符(设置全局描述符寄存器)
设置中断控制芯片,进入保护模式运行(SVC32保护模式)
跳转到system模块的最前面的代码运行(head.s)
bash
mov [0],dx ! it from 0x90000
mov [2],ax
mov [4],bx ! bh = display page
mov [6],ax ! al = video mode, ah = window width
mov [8],ax
mov [10],bx
mov [12],cx
两个硬盘参数表
根文件系统
head.s
加载内核运行时的各数据寄存器,重新设置中断描述符表
开启内核正常运行时的协处理器等资源
设置内存管理的分页机制
跳转到main.c开始运行
系统初始化函数main.c
cs
//mark 设置操作系统的根文件
ROOT_DEV = ORIG_ROOT_DEV;
//mark 设置操作系统的驱动参数
drive_info = DRIVE_INFO;
// 解析setup.s代码后获取系统内存参数
// 设置系统的内存大小 系统本身内存(1M),扩展内存大小(参数*kb)
memory_end = (1<<20) + (EXT_MEM_K<<10);
// 内存4k对齐
memory_end &= 0xfffff000;
// 控制操作系统的最大内存为16M
if (memory_end > 16*1024*1024)
memory_end = 16*1024*1024;
// 设置高速缓冲区的大小
if (memory_end > 12*1024*1024)
buffer_memory_end = 4*1024*1024;
else if (memory_end > 6*1024*1024)
buffer_memory_end = 2*1024*1024;
else
buffer_memory_end = 1*1024*1024;
//主内存的开始就是高速缓冲区的结束
main_memory_start = buffer_memory_end;
#ifdef RAMDISK
main_memory_start += rd_init(main_memory_start, RAMDISK*1024);
#endif