最全最詳細(xì)的Linux BSP 實(shí)戰(zhàn)教程,共100篇,包含SOC Bringup, Uboot, 內(nèi)核啟動(dòng), 中斷, 時(shí)鐘, 電源, GPIO, DMA, 低速總線(xiàn), 高速總線(xiàn), 音頻, 顯示, 攝像頭, 網(wǎng)絡(luò)驅(qū)動(dòng)等;博主創(chuàng)建了專(zhuān)門(mén)的專(zhuān)欄技術(shù)討論群,以及免費(fèi)的ChatGPT使用,和大佬們一起討論實(shí)戰(zhàn);經(jīng)過(guò)兩年的輸出和完善打磨,將碎片化的知識(shí)進(jìn)行整理;通過(guò)圖文并茂的方式淺入深出。
內(nèi)核運(yùn)行的第一行代碼
.head.text 文本段
Head.S
start_kernel
setup_arch
mm_init
sched_init
init_IRQ
tick_init
init_timers
hrtimers_init
softirq_init
time_init
console_init
vfs_caches_init
rest_init
上文我們講到,內(nèi)核中各個(gè)階段的初始化非常重要,涉及內(nèi)容很多,比如內(nèi)存管理,進(jìn)程管理,文件系統(tǒng),中斷管理,時(shí)鐘管理等。就算淺嘗輒止的描述每個(gè)模塊,至少也要一萬(wàn)字的總結(jié),所以?xún)?nèi)核的重要程度很有必要單獨(dú)作為一章梳理。
讓我們一起正式進(jìn)入內(nèi)核的世界,站在內(nèi)核的角度,內(nèi)核之前的所有程序都是系統(tǒng)引導(dǎo)程序,其中 CPU 的狀態(tài)如下:
r0 = 0.
r1 = CPU 類(lèi)型.
r2 = kernel參數(shù)list的物理地址.
irq & fiq 必須關(guān)閉.
MMU 必須關(guān)閉,這里內(nèi)存地址都是物理地址.
D-cache 必須關(guān)閉,I-cache 沒(méi)有要求.
內(nèi)核運(yùn)行的第一行代碼
Linux啟動(dòng),會(huì)啟動(dòng)內(nèi)核編譯后的文件 vmlinux,vmlinux 是一個(gè) ELF 文件,按照 ./arch/arm64/kernel/vmlinux.lds 設(shè)定的規(guī)則進(jìn)行鏈接,vmlinux.lds 是 vmlinux.lds.S 編譯之后生成的。所以為了確定 vmlinux 內(nèi)核的起始地址, 首先通過(guò) vmlinux.lds.S 鏈接腳本進(jìn)行分析。如下所示:
$?readelf?-h?vmlinux
ELF?Header:
??Magic:???7f?45?4c?46?02?01?01?00?00?00?00?00?00?00?00?00
??Class:?????????????????????????????ELF64
??Data:??????????????????????????????2's?complement,?little?endian
??Version:???????????????????????????1?(current)
??OS/ABI:????????????????????????????UNIX?-?System?V
??ABI?Version:???????????????????????0
??Type:??????????????????????????????DYN?(Shared?object?file)
??Machine:???????????????????????????AArch64
??Version:???????????????????????????0x1
??Entry?point?address:???????????????0xffff800010000000
??Start?of?program?headers:??????????64?(bytes?into?file)
??Start?of?section?headers:??????????494679672?(bytes?into?file)
??Flags:?????????????????????????????0x0
??Size?of?this?header:???????????????64?(bytes)
??Size?of?program?headers:???????????56?(bytes)
??Number?of?program?headers:?????????5
??Size?of?section?headers:???????????64?(bytes)
??Number?of?section?headers:?????????38
??Section?header?string?table?index:?37
$?readelf?-l?vmlinux
Elf?file?type?is?DYN?(Shared?object?file)
Entry?point?0xffff800010000000
There?are?5?program?headers,?starting?at?offset?64
Program?Headers:
??Type???????????Offset?????????????VirtAddr???????????PhysAddr
?????????????????FileSiz????????????MemSiz??????????????Flags??Align
??LOAD???????????0x0000000000010000?0xffff800010000000?0xffff800010000000
?????????????????0x0000000001beacdc?0x0000000001beacdc??RWE????10000
??LOAD???????????0x0000000001c00000?0xffff800011c00000?0xffff800011c00000
?????????????????0x00000000000c899c?0x00000000000c899c??R?E????10000
??LOAD???????????0x0000000001cd0000?0xffff800011cd0000?0xffff800011cd0000
?????????????????0x0000000000876200?0x0000000000905794??RW?????10000
??NOTE???????????0x0000000001bfaca0?0xffff800011beaca0?0xffff800011beaca0
?????????????????0x000000000000003c?0x000000000000003c??R??????4
??GNU_STACK??????0x0000000000000000?0x0000000000000000?0x0000000000000000
?????????????????0x0000000000000000?0x0000000000000000??RW?????10
?Section?to?Segment?mapping:
??Segment?Sections...
???00?????.head.text?.text?.got.plt?.rodata?.pci_fixup?__ksymtab?__ksymtab_gpl?__ksymtab_strings?__param?__modver?__ex_table?.notes
???01?????.init.text?.exit.text?.altinstructions
???02?????.init.data?.data..percpu?.hyp.data..percpu?.rela.dyn?.data?__bug_table?.mmuoff.data.write?.mmuoff.data.read?.pecoff_edata_padding?.bss
???03?????.notes
???04
通過(guò)上面的查詢(xún)可知,此 vmlinux 為一個(gè) aarch64 架構(gòu)平臺(tái)的 ELF 可執(zhí)行文件,其程序入口的地址為 0xffff800010000000,此段對(duì)應(yīng)的 section 為.head.text .text .got.plt......,所以 vmlinux 的入口在 .head.text 文本段。