linux內核學習-編譯架構-2.鏈接文件lds

上一篇文章說了make命令是怎麼根據make menuconfig的配置編譯出.o文件的。根據程序編譯的過程“檢查語法,編譯,最後鏈接”。最後需要有一個文件用來組織這些.o文件。這裏最重要的一個就是程序的入口地址。

一、找到vmlinux.lds文件

根據目標系統的不同的,vmlinux.lds的文件也會不同。比如,arm架構的在/arch/arm/kernel/ vmlinux.lds
打開這個文件,如下
在這裏插入圖片描述

從這個文件的註釋可以知道lds文件是腳本工具自動生成,用戶不要去更改它。
圖片代碼可以獲取到信息是

  1. 入口的函數是ENTRY(stext)。叫stext的函數,是一個彙編函數。不是main函數哦。
  2. 看391行可以知道存放鏈接的順序依次爲:initcall0.init, initcall0s.init…..

二、擴展下initcall機制

在linux初始化的過程中,內核採用了一種initcall的機制,它利用gcc的擴展功能以及ld的連接控制腳本實現了在內核初始化的過程中通過簡單的循環就實現了相關驅動的初始化。

具體的機制我還看不懂,這邊博文寫的挺好,不過文章挺亂的,也不好理解。先mark吧。以後我可能就懂了。

我當前個人感覺就是它會找這個文件/include/linux/init.h中的定義的啓動代碼。文件下定義了這樣的代碼

#define pure_initcall(fn)		__define_initcall("0",fn,0)

#define core_initcall(fn)		__define_initcall("1",fn,1)
#define core_initcall_sync(fn)		__define_initcall("1s",fn,1s)
#define postcore_initcall(fn)		__define_initcall("2",fn,2)
#define postcore_initcall_sync(fn)	__define_initcall("2s",fn,2s)
#define arch_initcall(fn)		__define_initcall("3",fn,3)
#define arch_initcall_sync(fn)		__define_initcall("3s",fn,3s)
#define subsys_initcall(fn)		__define_initcall("4",fn,4)
#define subsys_initcall_sync(fn)	__define_initcall("4s",fn,4s)
#define fs_initcall(fn)			__define_initcall("5",fn,5)
#define fs_initcall_sync(fn)		__define_initcall("5s",fn,5s)
#define rootfs_initcall(fn)		__define_initcall("rootfs",fn,rootfs)
#define device_initcall(fn)		__define_initcall("6",fn,6)
#define device_initcall_sync(fn)	__define_initcall("6s",fn,6s)
#define late_initcall(fn)		__define_initcall("7",fn,7)
#define late_initcall_sync(fn)		__define_initcall("7s",fn,7s)

代碼中的1,2,3,4這些就是指模塊的啓動順序,比如叫core_initcall的內核(core)模塊,就是第一個啓動。

分析到這裏貌似我的思路又斷了,下一步,應該如何編譯。先停留在這。後續再分析

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章