计算机从加电到系统(Linux)启动完成
0x0 背景
在我參加的面試和我面試別人、或者參加別人對別人的面試的事后經常遇到的一個問題就是:請從計算機加電開始描述一下計算機啟動到操作系統正式啟動起來的全過程。這是一個考驗對計算機體系結構和基本知識了解程度的問題。今天也就特別針對這個問題做一個回答,答案是基于80x86結構Linux 2.6及更高版本內核的為基準操作系統為例來回答的。
0x1 從加電到BIOS啟動
STEP 1 加電引導寄存器置位
這一過程指的是,計算機加電后,一個特殊電路會在CPU對應的一陣針腳產生一個邏輯電平,這個電平的值從針腳進入CPU后,會引發將寄存器(cs、eip等等)設置成特定值。
STEP 2 引導BIOS啟動
這一過程指的是系統從物理地址0xfffffff0處加載一段程序到只讀內存(ROM-> Read Only Memory),這個程序在80x86體系架構中一般稱為BIOS。
相關知識學習
- MS-DOS的很多系統調用依賴BIOS
- Linux進入保護模式后不再依賴BIOS,BIOS只能以實模式運行。
0x2 BIOS引導操作系統鏡像的加載
STEP 1 檢查硬件
沒啥可說的,一般可認為是開機加電自檢,這個階段會顯示一些信息,包括BIOS版本這一類的信息。
STEP 2 初始化硬件
主要是避免IRQ先與I/O沖突,本階段最后會顯示所有PCI(總線--內部硬件通信線路)設備信息。
STEP 3 搜索操作系統
從軟盤、網絡、磁盤、CD-ROM的主引導扇區上搜索。找到后加載注意到扇區的內容到0x00007c00的位置(RAM中),跳轉到這個地址,開始執行這段代碼,這段程序叫做bootloader。
由于大小限制,linux的啟動程序GRUB(GRand Unified BootLoader)或者是LILO(LInux LOader)被分為兩部分。 第一部分就是加載到0x00007c00的這一段,他會把自己移動到0x00096a00的位置,建立實模式棧(0x00098000~0x000969ff) 第一部分吧第二部分加載到0x00096c00開始的位置中。 以上的位置都是在RAM中。 第二部分搜索磁盤上的OS景象,,把對應的扇區拷貝到RAM中執行: 1、首先把內核景象的第一個512B的部分從0x00090000處裝入RAM中; 2、把setup()函數代碼段裝入0x00090200位置(RAM); 3、加載其他內核部分從高(0x00100000)或低(0x00010000)兩個位置任選其一加載到RAM中,分別稱為大映像內核和小映像內核; 4、跳轉到setup函數執行;0x3 setup函數引導內核
這個過程主要是檢查和初始化硬件、雖然BIOS完成了相似的大部分工作,但是因為不依賴與BIOS,所以,還是重新初始化了硬件方面的事情;重要的過程有:
1、移動低裝載小映像內核的位置到0x00001000去,如果是高裝載則不移動; 2、建立IDT(臨時中斷描述符表)和GDT(臨時全局描述符表); 3、如果需要,重置浮點單元(FPU); 4、重新編寫可編程終端控制器(PIC),屏蔽除IRQ2外的所有終端; 5、設置cr0寄存器到PE位,設置PG位為0,切換到保護模式,暫未啟用分頁; 6、跳轉到startup_32()函數;0x4 內核建立階段
STEP 1 startup_32()函數
主要做的事情如下:
1、初始化段寄存器和一個臨時堆棧,并清零eflags寄存器所有為; 2、用0填充_edata 和_end符號標識的內核未初始化數據區; 3、調用decompress_kernel函數解壓內核映像; 【低裝載的情況解壓內容放在0x00100000位置開始的RAM中,高裝載的放在這后面的一個臨時緩沖區內,解壓后的內核就被移動到0x00100000位置】 4、跳轉到0x00100000位置開始執行,新的執行點事arch/i386/kernerlhead.s中的另一個startup_32函數。STEP 2 再戰startup_32()函數
這個函數就是init進程(也是pid=0的0號進程)主要做了一下工作:
1、段寄存器初始化為最終值,內核的bss段填寫為0; 2、初始化臨時內核頁表,初始化pg0,使得線性地址一律映射到統一的物理地址上; 3、cr3寄存器保存了頁全局目錄,并設置cr0的pg位啟用分頁; 4、清零eflags,使用setup_idt函數用空的終端處理程序填充IDT; 5、從bios獲取的數據(系統參數和傳遞給os的參數)放入頁框1; 6、識別處理器、用GDT和IDT填充gdtr和idtr寄存器; 7、跳轉到start_kernel函數0x5 內核完善階段start_kernel函數
這一階段最終完善了內核的初始化的后續工作,啟動了程序調度、內存管理等操作系統的功能,其中就涉及到了著名的函數sched_init函數,至此,系統完全啟動成功。
轉載于:https://www.cnblogs.com/KevinGeorge/p/10166647.html
總結
以上是生活随笔為你收集整理的计算机从加电到系统(Linux)启动完成的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 洛天依官方原版mmd模型_【MMD模型】
- 下一篇: linux控制风扇转速的命令,Cputr