編譯內核腳本
A. linux內核程序入口地址
在Linux內核中,使用 vmlinux.lds.S 文件(路徑: arch/arm64/kernel/ )布局內核映像中相關段(例: .text、.data )的位置。
在Linux內核編譯時, vmlinux.lds.S 文件最終會被構建成鏈接腳本 vmlinux.lds 文件(路徑: arch/arm64/kernel/ )。
本文主要介紹Linux內核程序運行的起始位置 _text ,在 vmlinux.lds.S 文件中定義如下:
從上面可以看出: _text = KIMAGE_VADDR + TEXT_OFFSET 。
1、KIMAGE_VADDR定義
文件: arch/arm64/include/asm/memory.h ,定義如下:
文件: include/linux/sizes.h ,定義如下:
宏 KIMAGE_VADDR 展開如下:
上面是按照無符號計算, KIMAGE_VADDR 為: 0xFFFFFF8008000000 。
2、TEXT_OFFSET定義
文件: arch/arm64/Makefile ,定義如下:
通過計算, _text 值為: 0xFFFFFF8008080000 。
在Linux內核啟動時,從 log 信息中也可以找到對應的地址:
_text 對應的是虛擬地址 , 在內核中可以直接通過訪問該地址獲取其保存的值 ,其對應 Image 映像中的第一個字 0x14424000 。
Image 映像查看方法如下:
本文基於 RockPI 4A 單板Linux 4.4內核。
B. 如何把自己的驅動編譯進內核或模塊
我們知道若要給Linux內核添加模塊(驅動)有如下兩種方式:
(1)動態方式:採用insmod命令來給運行中的linux載入模塊。
(2)靜態方式:修改linux的配置菜單,添加模塊相關文件到源碼對應目錄,然後把模塊直接編譯進內核。
對於動態方式,比較簡單,下面我們介紹如何採用靜態的方式把模塊添加到內核。
最終到達的效果是:在內核的配置菜單中可以配置我們添加的模塊,並可以對我們添加的模塊進行編譯。
一. 內核的配置系統組成
首先我們要了解Linux 2.6內核的配置系統的原理,比如我們在源碼下運行「make menuconfig 」為神馬會出現一個圖形配置菜單,配置了這個菜單後又是如何改變了內核的編譯策略滴。
內核的配置系統一般由以下幾部分組成:
(1)Makefile:分布在Linux內核源代碼中的Makefile,定義Linux內核的編譯規則。
(2)配置文件(Kconfig):給用戶提供配置選項,修改該文件來改變配置菜單選項。
(3)配置工具:包括配置命令解釋器(對配置腳本中使用的配置命令進行解釋),配置用戶界面(提供字元界面和圖形界面)。這些配置工具都是使用腳本語言編寫的,如Tcl/TK、Perl等。
其原理可以簡述如下:這里有兩條主線,一條為配置線索,一條為編譯線索。配置工具根據kconfig配置腳本產生配置菜單,然後根據配置菜單的配置情況生成頂層目錄下的.config,在.config里定義了配置選擇的配置宏定義,如下所示:
如上所示,這里定義的這些配置宏變數會在Makefile里出現,如下所示:
然後make 工具根據Makefile里這些宏的賦值情況來指導編譯。所以理論上,我們可以直接修改.config和Makefile來添加模塊,但這樣很麻煩,也容易出錯,下面我們將會看到,實際上我們有兩種方法來很容易的實現。
二. 如何添加模塊到內核
實際上,我們需要做的工作可簡述如下:
(1)將編寫的模塊或驅動源代碼(比如是XXOO)復制到Linux內核源代碼的相應目錄。
(2)在該目錄下的Kconfig文件中依葫蘆畫瓢的添加XXOO配置選項。
(3)在該目錄的Makefile文件中依葫蘆畫瓢的添加XXOO編譯選項。
可以看到,我們奉行的原則是「依葫蘆畫瓢」,主要是添加。
一般的按照上面方式又可出現兩種情況,一種為給XXOO驅動添加我們自己的目錄,一種是不添加目錄。兩種情況的處理方式有點兒不一樣哦。
三. 不加自己目錄的情況
(1)把我們的驅動源文件(xxoo.c)放到對應目錄下,具體放到哪裡需要根據驅動的類型和特點。這里假設我們放到./driver/char下。
(2)然後我們修改./driver/char下的Kconfig文件,依葫蘆添加即可,如下所示:
注意這里的LT_XXOO這個名字可以隨便寫,但需要保持這個格式,他並不需要跟驅動源文件保持一致,但最好保持一致,等下我們在修改Makefile時會用到這個名字,他將會變成CONFIG_LT_XXOO,那個名字必須與這個名字對應。如上所示,tristate定義了這個配置選項的可選項有幾個,help定義了這個配置選項的幫助信息,具體更多的規則這里不講了。
(3)然後我們修改./driver/char下的Makefile文件,如下所示:
這里我們可以看到,前面Kconfig里出現的LT_XXOO,在這里我們就需要使用到CONFIG_XXOO,實際上邏輯是醬汁滴:在Kconfig里定義了LT_XXOO,然後配置完成後,在頂層的.config里會產生CONFIG_XXOO,然後這里我們使用這個變數。
到這里第一種情況下的添加方式就完成了。
四. 添加自己目錄的情況
(1)在源碼的對應目錄下建立自己的目錄(xxoo),這里假設為/drivers/char/xxoo 。
(2) 把驅動源碼放到新建的xxoo目錄下,並在此目錄下新建Kconfig和Makefile文件。然後給新建的Kconfig和Makefile添加內容。
Kconfig下添加的內容如下:
這個格式跟之前在Kconfig里添加選項類似。
Makefile里寫入的內容就更少了:
添加這一句就可以了。
(3)第三也不復雜,還是依葫蘆畫瓢就可以了。
我們在/drivers/char目錄下添加了xxoo目錄,我們總得在這個配置系統里進行登記吧,哈哈,不然配置系統怎麼找到們呢。由於整個配置系統是遞歸調用滴,所以我們需要在xxoo的父目錄也即char目錄的Kconfig和Makefile文件里進行登記。具體如下:
a). 在drivers/char/Kconfig中加入:source 「drivers/char/xxoo/Kconfig」
b). 在drivers/char/Makefile中加入:obj-$(CONFIG_LT_XXOO) += xxoo/
添加過程依葫蘆畫瓢就可以了,灰常滴簡單。
C. 想寫一個shell腳本來刪除ubuntu裡面舊的內核,不知道有沒有大俠能給出思路和代碼的啊。
自己先手動更新一次內核。
然後把手動過程中涉及的命令按照順序整理到一個文本里
腳本的雛形就出來了
然後自己在修改一下。腳本不就有了。
D. RockPI 4A Linux內核下載與編譯
本文介紹RockPI 4A單板Debian系統Linux內核的下載和編譯方法,為後續介紹RockPI 4A單板Linux內核調試進行拋磚引玉。
一笑神腔、代碼下載
Rockpi 4A Debian版本SDK代碼下載方法:
代碼下載完成後,顯示如下瞎冊:
kernel 目錄下保存Linux內核代碼。
build 目錄下保存配置和編譯腳本。
如果RockPI 4A代碼下載失敗,提示如下:
解決方法:將下載鏈接中 https 替換成 git 。
二、內核編譯
使用代碼里的編譯腳本,編譯腳本名稱: mk-kernel.sh ,位置如下:
註:在腳本 mk-kernel.sh 中有一段代碼: source $LOCALPATH/build/board_configs.sh $BOARD ,使用腳本編譯時,必須在 build 文件夾同一級目錄。
RockPI 4A Linux內核編譯方法碰衫如下(使用...省略部分編譯輸出):
其中: rockpi4a 對應RockPI 4A單板,如果使用其它單板,需要設置不同內容。單板類型可參考 build/board_configs.sh 腳本中 case ${BOARD} in 的選項。例:
編譯出來的映像路徑: