/kern/arch/mips/mips/start.s
系统开始引导于此。
22-25 为了gdb的方便,留了20字节作为stack frame
27-57 由注释得知,系统初始时,将一个引导字串放到a0中,并且将内核加载到0x80001000(物理地址0x00001000)中。
80000000将会是exception handler。_end是链接完成后,kernel的结束地址。
59-64 将a0中的bootstring拷贝到_end后面,即将bootstring追加到kernel后面。
66-71 计算出bootstring的长度,并且加上NULL的一个字节
74-76 计算出以bootstring尾部的地址后面第一个页首的地址
78 再增加一页的空间(4k),留作第一个堆栈的空间,此地址便为栈顶地址
80-83 将计算好的stack top地址附给sp,并且将其存储到curkstack(当前内核堆栈地址),和firstfree(第一空余的页面地址)
此处需要注意的是,这两个地址不冲突。堆栈将地址向下减,firstfree向上加,是两个方向。
85-97 至此bootstring存储在s0里面。依旧是为了gdb准备了20字节的stack frame。
103-108 将uTLB的exception handler拷贝到0x80000000
110-115 将exception handler拷贝到0x80000080
118-122 针对mips系统,清除instruction的cache
124-128 初始TLB
154-155 设置状态寄存器,将interrupt寄存器enable
158-162 开始执行kmain()。(不解bootstring虽然在s0,但是为什么在jal kmain后才将move a0,s0呢?)
166-176 kmain是不会返回的,如果返回了,那一定出错了,就执行panic。
/kern/main/main.c
kmain(bootstring)
161 执行boot()进行OS必要的初始化
163 menu(bootstring)
boot()
64-71 打印版本信息
73 内存初始化
74 调度器初始化
75 线程初始化
76 文件系统初始化
77 设备初始化
78 虚拟内存初始化
79 kprintf初始化
82 文件系统设置引导文件系统emu0,(此时忽略错误,因为事实上emu0不存在)
88-89 比较userptr_t的类型是否和char*一样
shutdown()
102 清理bootfs
103 清理curdir(当前目录)
104 解除所有设备的绑定
106 禁用所有中断
108 停止scheduler
109 线程终止
sys_reboot(int code)
124-131 判断入口参数合法性
133 调用shutdown()终止系统
136-139 如果是RB_HALT,就执行md_halt();
140-143 如果是RB_REBOOT,md_reboot();
144-147 如果是RB_POWEROFF,就执行md_poweroff();
150-151 这三个函数都是不可能返回的函数,如果返回了,一定是reboot行为失败了。