linux引导和启动程序

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

1.BIOS/Bootloader:

一上电硬件强制让cpu的cs:ip寄存器指向bios程序的位置从bios程序开始执行由pc机的BIOS 0xFFFFO是BIOs存储的总线地址把bootsect从某个固定的地址拿到了内存中的某个固定地址0x90000并且进行了一系列的硬件初始化和参数设置----bois可以存储着大量的硬件参数

 2.bootsect.s

bootsect.s位于启动区的第一个扇区

作用:首先将后续的setup.s代码从磁盘中加载到紧接着bootsect.s的地方。

在显示屏上显示loading system(操作系统模块加载到ox10000的地方最后跳转到setup.s中去运行

3.setup.s

setup.s位于启动区的2~5扇区

解析BIOS/BOOTLOADER传递来的参数设置系统内核运行LDT(局部描述符IDT(中断描述符寄存器)全局描述符设置全局描述符寄存器)设置中断控制芯片进入保护模式运行svc32保护模式设置寄存器中的值)跳转到system模块的最前面的代码运行(head.s)

重点很多全局变量的属性值都是由这里解析出来设置的比如内存大小内存位置这些环境属性值等等全局变量 都是在boot阶段读入的然后放到宏定义中

4.head.s

head.s大小240个扇区

加载内核运行时的各数据段寄存器重新设置中断描述符表开启内核正常运行时的协处理器等资源设置内存管理的分页机制跳转到main.c开始运行

5.main.c

//main函数 linux引导成功后就从这里开始运行
void main(void)		/* This really IS void, no error here. */
{			/* The startup routine assumes (well, ...) this */
/*
 * Interrupts are still disabled. Do necessary setups, then
 * enable them
 */
//前面这里做的所有事情都是在对内存进行拷贝
 	ROOT_DEV = ORIG_ROOT_DEV;//设置操作系统的根文件
 	drive_info = DRIVE_INFO;//设置操作系统驱动参数
	 //解析setup.s代码后获取系统内存参数
	memory_end = (1<<20) + (EXT_MEM_K<<10);
	//取整4k的内存大小
	memory_end &= 0xfffff000;
	if (memory_end > 16*1024*1024)//控制操作系统的最大内存为16M
		memory_end = 16*1024*1024;
	if (memory_end > 12*1024*1024) 
		buffer_memory_end = 4*1024*1024;//设置高速缓冲区的大小跟块设备有关跟设备交互的时候充当缓冲区写入到块设备中的数据先放在缓冲区里只有执行sync时才真正写入这也是为什么要区分块设备驱动和字符设备驱动块设备写入需要缓冲区字符设备不需要是直接写入的
	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
//内存控制器初始化
	mem_init(main_memory_start,memory_end);
	//异常函数初始化
	trap_init();
	//块设备驱动初始化
	blk_dev_init();
	//字符型设备出动初始化
	chr_dev_init();
	//控制台设备初始化
	tty_init();
	//加载定时器驱动
	time_init();
	//进程间调度初始化
	sched_init();
	//缓冲区初始化
	buffer_init(buffer_memory_end);
	//硬盘初始化
	hd_init();
	//软盘初始化
	floppy_init();
	sti();
	//从内核态切换到用户态上面的初始化都是在内核态运行的
	//内核态无法被抢占不能在进程间进行切换运行不会被干扰
	move_to_user_mode();
	if (!fork()) {	//创建0号进程 fork函数就是用来创建进程的函数	/* we count on this going ok */
		//0号进程是所有进程的父进程
		init();
	}
/*
 *   NOTE!!   For any other task 'pause()' would mean we have to get a
 * signal to awaken, but task0 is the sole exception (see 'schedule()')
 * as task 0 gets activated at every idle moment (when no other tasks
 * can run). For task0 'pause()' just means we go check if some other
 * task can run, and if not we return here.
 */
//0号进程永远不会结束他会在没有其他进程调用的时候调用只会执行for(;;) pause();
	for(;;) pause();
}

6.高速缓冲区

 写文件先进入高速缓冲区由高速缓冲区内存。内存规划

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: linux