日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

很好的linux启动说明( bootsect.S、setup.S、head.S)

發(fā)布時間:2025/6/15 65 豆豆
生活随笔 收集整理的這篇文章主要介紹了 很好的linux启动说明( bootsect.S、setup.S、head.S) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
bootsect.S,系統(tǒng)引導程序,一般不超過512字節(jié)。 PC系統(tǒng)結構中,線性地址0xA0000以上,即640K以上用于圖形接口卡和BIOS自身,640K以下為系統(tǒng)的基本內存。如果配置更多的內存,則0x100000,即1MB處開始稱為高內存。當BIOS引導一個系統(tǒng)時,總是把引導扇區(qū)讀入到基本內存地址為0x7c00的地方,然后跳轉到此執(zhí)行引導扇區(qū)的代碼。這段代碼將自身搬運到0x90000處,并跳轉到那繼續(xù)執(zhí)行,然后通過BIOS提供的讀磁盤調用“int 0x13從磁盤上讀入setup和內核映像。其中setup的映像讀入到0x90200處,然后跳轉到setup的代碼中。 0x900000xA0000一共64Kbootsect僅占512字節(jié),所以setup大小理論上可到63.5KB Linux2.4版本以前,在最前面的512字節(jié)里保護了一個mini “boot loader”,只要拷貝啟動代碼運行就可從軟盤啟動;但在2.6版本中不再保護這樣的”boot loader”,所以必須在第一個磁盤分區(qū)上存儲一個合適的boot loader才能從軟盤啟動,軟盤、硬盤和光驅啟動都是一樣的過程。 setup進行映像的解壓縮,從BIOS收集一些數(shù)據(jù),在控制臺顯示一些信息。 基本內存中開頭一部分空間是保留給BIOS自己用的,另一方面對于Linux內核的引導也需要保留一些運行空間,一共保存了64K。基本內存中用于內核映像的就是8*64K=512K,其中頂端留4K用于引導命令行及從BIOS獲取需要傳遞給內核的數(shù)據(jù)。內核映像一般都經(jīng)過壓縮,壓縮后的映像和引導扇區(qū)及輔助引導程序的映像拼接在一起,成為內核的引導映像。大小不超過508K的映像稱為小映像zImage,早期版本放在0x10000位置處,否則稱為大內核bzImage,放在0x100000位置處。 CPUbootsect時處于16位實地址模式,然后在setup的執(zhí)行過程中轉入32位保護模式。 SetupBIOS中讀取系統(tǒng)數(shù)據(jù)(內存大小、顯卡模式、磁盤等參數(shù)),將數(shù)據(jù)保存在0x90000-0x901FF,覆蓋了bootsect的內容。設置32位運行方式:加載中斷描述表寄存器IDTR、全局描述表寄存器GDTR;臨時設置IDT表和GDT表,并在GDT表中設置內核代碼段和數(shù)據(jù)段的描述符,在Head.S中會根據(jù)內核的需要重新設置這些描述符表;開啟A20地址線;重新設置兩個中斷控制器8259A,將硬件中斷號重新設置為0x200x2f;最后設置CPU的控制寄存器CR0(機器狀態(tài)字)的保護模式比特(PE)位,從而進入32位保護模式運行;然后跳轉到head.S中的startup_32執(zhí)行。 對于小內核映像放在0x10000處,Setup會把system0x10000移到0x0000開始處。對于大內核映像,vmlinux中普通內核代碼被編譯成以PAGE_OFFSET+1MB為起始地址,在Head.S中初始化代碼把虛擬地址減去PAGE_OFFSET就能得到以1MB為起始位置的物理地址,這也正是內核映像在物理內存中的存放位置。 Head.S中的startup_32主要用于開啟頁面單元。初始化工作在編譯過程中開始進行,它先定義一個稱為swapper_pg_dir的數(shù)組,使用鏈接器指示在地址0x00101000。然后分別為兩個頁面pg0pg1創(chuàng)建頁表項。第一組指向pg0pg1的指針放在能覆蓋19MB內存的位置,第二組指針放在PAGE_OFFSET+1MB的位置。一旦開始頁機制,在上述頁表和頁表項指針建立后可以保證,在內核映像中不論是采用物理地址還是虛擬地址,都可以進行正確的頁面映射。內核其他部分的頁表初始化在paging_init()中完成。映射建立后,通過設置cr0寄存器中的某位開啟頁面映射,然后通過一個跳轉指令保證指令指針的正確性。 1Bootsect啟動過程: 假設用LILO啟動,啟動時用戶可以選擇啟動哪個操作系統(tǒng)。LILOboot loader分為兩部分,一部分放到啟動分區(qū)的第一個扇區(qū); 1)????????BIOSMBR或啟動分區(qū)的第一個扇區(qū)的啟動部分加載到地址0x00007c00處; 2)????????該程序將自身移到0x00096a00,建立實模式棧(0x000980000x000969ff),將LILO的第二部分加載到0x00096c00處,然后跳轉到此執(zhí)行; 3)????????然后第二部分程序從磁盤讀取一個可啟動的操作系統(tǒng)列表讓用戶選擇,最后用戶選擇每個OS后,boot loader可以拷貝不啟動分區(qū)或者之間拷貝內核映像到RAM中去; 4)????????加載Linux內核映像時,LILO boot loader首先調用BIOS例程顯示”Loading …”信息; 5)????????調用BIOS例程加載內核映像的初始化部分到RAM上,內核映像的前512字節(jié)放在0x00090000位置,setup()函數(shù)代碼放在0x00090200位置; 6)????????接著調用BIOS例程裝載內核映像的其余部分,映像可能放在低地址0x00010000(使用make zImage編譯的小內核映像)或者高地址0x00100000(使用make bzImage編譯的大內核映像)。 7)????????然后跳至剛剛setup部分。 2Setup.S分析 setup()匯編函數(shù)被連接器放在內核映像文件中的0x200偏移處。Setup函數(shù)必須初始化計算機中的硬件設備并為內核程序的執(zhí)行建立環(huán)境。 1)????????ACPI兼容的系統(tǒng)中,調用BIOS例程建立描述系統(tǒng)物理內存布局的表。在早期系統(tǒng)中,它調用BIOS例程返回系統(tǒng)可以的RAM大小; 2)????????設置鍵盤的重復延遲和速率; 3)????????初始化顯卡; 4)????????檢測IBM MCA總線、PS/2鼠標設備、APM BIOS支持等; 5)????????如果BIOS支持Enhanced Disk Drive Services (EDD),將調用正確的BIOS例程建立描述系統(tǒng)可用硬盤的表; 6)????????如果內核加載在低RAM地址0x00010000,則把它移動到0x00001000處;如果映像加載在高內存1M位置,則不動; 7)????????啟動位于8042鍵盤控制器的A20 pin 8)????????建立一個中斷描述表IDT和全局描述表GDT表; 9)????????如果有的話,重啟FPU單元; 10)????對可編程中斷控制器進行重新編程,屏蔽所以中斷,級連PICIRQ2不需要; 11)????設置CR0狀態(tài)寄存器的PE位使CPU從實模式切換到保護模式,PG位清0,禁止分頁功能; 12)????跳轉到startup_32()匯編函數(shù),?jmpi 0x100000, __BOOT_CS,終于進入內核Head.S 3Head.S分析 有兩個不同的startup_32()函數(shù),一個在arch/i386/boot/compressed/head.S文件中,setup結束后,該函數(shù)被放在0x00001000或者0x00100000位置,該函數(shù)主要操作: 1)????????首先初始化段寄存器和臨時堆棧; 2)????????清除eflags寄存器的所有位; 3)????????_edata_end區(qū)間的所有內核未初始化區(qū)填充0 4)????????調用decompress_kernel( )函數(shù)解壓內核映像。首先顯示"Uncompressing Linux..."信息,解壓完成后顯示?"OK, booting the kernel."。內核解壓后,如果時低地址載入,則放在0x00100000位置;否則解壓后的映像先放在壓縮映像后的臨時緩存里,最后解壓后的映像被放置到物理位置0x00100000處; 5)????????跳轉到0x00100000物理內存處執(zhí)行; ??? ????解壓后的映像開始于arch/i386/kernel/head.S?文件中的startup_32()函數(shù),因為通過物理地址的跳轉執(zhí)行該函數(shù)的,所以相同的函數(shù)名并沒有什么問題。該函數(shù)未Linux第一個進程建立執(zhí)行環(huán)境,操作如下: 1)?????????初始化ds,es,fs,gs段寄存器的最終值; 2)????????0填充內核bss段; 3)????????初始化swapper_pg_dir數(shù)組和pg0包含的臨時內核頁表: l??????????swapper_pg_dir0x1000)pg0(0x2000)清空,swapper_pg_dir作為整個系統(tǒng)的頁目錄; l??????????pg0作為第一個頁表,將其地址賦到swapper_pg_dir的第一個32位字中。 l??????????同時將該頁表項也賦給swapper_pg_dir的第3072個入口,表示虛擬地址0xc0000000也指向pg0 l??????????pg0這個頁表填滿指向內存前4M l??????????cr3寄存器中存放PGD的地址,并設置cr0寄存器中的PG位,啟用分頁支持。 4)????????建立進程0idle進程的內核模式的堆棧; 5)????????再次清除eflags寄存器的所有位; 6)????????調用setup_idt()用非空的中斷處理函數(shù)填充IDT表; 7)????????將從BIOS獲取的系統(tǒng)參數(shù)傳遞到操作系統(tǒng)的第一個頁面幀; 8)????????識別處理器的模式; 9)????????GDTIDT表的地址加載到gdtridtr寄存器中; 10)?跳轉到start_kernel函數(shù),這個函數(shù)是第一個C編制的函數(shù),內核又有了一個新的開始。 4start_kernel()分析: 1)????????調度器初始化,調用sched_init(); 2)????????調用build_all_zonelists函數(shù)初始化內存區(qū); 3)????????調用page_alloc_init()mem_init()初始化伙伴系統(tǒng)分配器; 4)????????調用trap_init()init_IRQ()對中斷控制表IDT進行最后的初始化; 5)????????調用softirq_init()?初始化TASKLET_SOFTIRQHI_SOFTIRQ 6)????????Time_init()對系統(tǒng)日期和時間進行初始化; 7)????????調用kmem_cache_init()初始化slab分配器; 8)????????調用calibrate_delay()計算CPU時鐘頻率; 通過調用 kernel_thread() 啟動進程 1init 進程的內核線程,然后該線程再創(chuàng)建其他的內核線程執(zhí)行 /sbin/init 程序。

總結

以上是生活随笔為你收集整理的很好的linux启动说明( bootsect.S、setup.S、head.S)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。