/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行爲失敗了。