main
功能
前面介绍了head.s将执行权交给main.c,内核初始化完成,现在开始进入C代码的分析了。Init主要是取得前面setup.s设置的根文件设备号和一下内存全局变量,初始化陷阱门,块设备,字符设备,tty,磁盘,开启中断等,并从内核模式切换到用户模式。通过fork创建一个子程序,从进程0切换到进程1继续运行指定,进程0通过无限循环进行等待。
void main(void)
{
ROOT_DEV = ORIG_ROOT_DEV;
drive_info = DRIVE_INFO;
memory_end = (1<<20) + (EXT_MEM_K<<10);
memory_end &= 0xfffff000;
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
!内存初始化
mem_init(main_memory_start,memory_end);
!陷阱门
trap_init();
!块设备
blk_dev_init();
!字符设备
chr_dev_init();
!tty
tty_init();
!开机时间
time_init();
!调度
sched_init();
buffer_init(buffer_memory_end);
hd_init();
floppy_init();
sti();
!切换到用户模式
move_to_user_mode();
if (!fork()) {
!fork 子程序继续执行
init();
}
!父进程等待
for(;;) pause();
}
move_to_user_mode
这段代码的作用是切换到用户模式
主要由iret指令完成,当iret返回时,程序将数据出栈给ss,esp,eflags,cs,eip,之后就可以使进程进入用户态。
#define move_to_user_mode() \
__asm__ ("movl %%esp,%%eax\n\t" \ !堆栈指针复制给eax
"pushl $0x17\n\t" \ !压入SS段选择符
"pushl %%eax\n\t" \ !压入堆栈指针
"pushfl\n\t" \ &#x