修改linux编译配置文件,Porting:linux内核编译、配置、修改配置文件、添加.c文件到内核...
一、linux內核
$:'uname -a
$:'uanme -r
// 查看linux內核版本,開發板上進入linux后是一樣的命令。
早起常常使用的版本:linux 2.6.x
開發板上使用的版本:linux 3.4.39
linux最新版本:linux 4.x
二、linux內核的5大功能
1)內存管理功能;2)進程管理及進程間通訊;3)虛擬文件子系統;4)設備驅動管理;5)網絡子系統;
嵌入式平臺有操做系統,優點在于:
1)編程簡單,有庫函數能夠調用;
2)能夠實現更加復雜的業務邏輯;// 多進程 多線程
三、linux內核的編譯
env/kernel.tar.bz2
$:'cp /mnt/hgfs/porting/env/kernel.tar.bz2 .
$:'tar xvf *.bz2
$:'cd kernel/
$:'find ./ -type f | wc -l
// 26129
$:'cp arch/arm/configs/x6818_defconfig .config
$:'vi Makefile
// 195 ARCH ?= arm// 196 CROSS_COMPILE ?= arm-cortex_a9-linux-gnueabi-
$:'make uImage -j4
// arch/arm/boot/uImage ?is ?ready
$:'make menuconfig -j4
// 此項為內核功能配置,可刪減(內核裁剪)
** 編譯異常問題解決 **
問題1:
>>若是出現"mkuimage"command not find
解決辦法:
$:'sudo cp ~/project/uboot/tools/mkimage /usr/bin/
$:'make uImage
問題2:
>>Your display is too small...
解決辦法:
縮小字體顯示比例。
驗證uImage的有效性:
把uImage燒寫0x800扇區開始的分區位置。
經過加載的方式:
cp arch/arm/boot/uImage /tftpboot/tftp 48000000 uImagebootm 48000000setenv bootcmd tftp 48000000 uImage \; bootm 48000000
3.1 內核的配置
【什么是配置?】
假設linux內核中提供了10000種功能,可是具體到開發板上只須要其中2000個功能。
1)裁剪掉內核中不須要的功能
不須要掛載U盤
// 內核中關于FAT32類型文件系統相關的代碼的支持就不須要
2)驅動程序的裁剪
// 產品中沒有鍵盤,裁剪掉內核中的鍵盤驅動
【總之】根據目標產品的須要,以及開發板的實際硬件,裁剪掉不須要的內核代碼。
【如何完成配置?】
找一個相近的配置文件,在此基礎上進行修改。
【去哪里找相近的配置?】
1)去內核源碼目錄 ?arch/arm/configs/xxx_defconfig
2)上游廠家提供
【如何修改配置?】
cp 相近的配置.config ?kernel/.config
a)$:' ?make menuconfig
// 模擬菜單顯示界面
General setup ?--->
System Type ?--->
ARM system type (SLsiAP S5P6818) ?--->
Boot options ?--->
Device Drivers ?---> // 硬件驅動設備
File systems ?---> // 文件系統
b)$:'make config
// 純文字提示,基本不用
c)$:' ?make xconfig
// 真實圖形顯示菜單界面,基本不用
"make help" 查看內核make幫助命令。
內核本質也是一個裸板程序。
.o ... .o ?---> elf 文件 (vmlinux)
vmlinux ?---> Image(.bin) ?---> ?zImage ?---> uImage
zImage:解壓縮代碼 + 壓縮后的Image數據
uImage:64Bytes + zImage
// 64Bytes:內核的加載地址、內核版本 ... 通常給uboot使用。
$:'du -h arch/arm/boot/Image
// 11M
$:'du -h arch/arm/boot/zImage
// 5.2M 5400688,壓縮后的Image
$:'du -harch/arm/boot/uImage
// 5.2M 5400752
$:'du -h
// 以兆(M)顯示文件大小 和 文件名
$:'du -b
// 以字節數顯示文件大小 和 文件名
3.2 linux內核的啟動過程
閱讀代碼,組織工程。
linux : vim + ctags
$:'rm arch/arm/mach-s5p6818/prototype/prototype
$:'ctags -R *
windows : source insight
入口點文件:
$:'rm vmlinux
$:'make uImage V=1
// V=1 顯示詳細的編譯過程
$:'vi arch/arm/kernel/vmlinux.lds
.head.text : {
_text = .;
*(.head.text)
}
// 整個linux內核的入口點文件:arch/arm/kernel/head.S
head.S:
設置SVC模式
__lookup_processor_type ?// 檢查CPU的ID看內核的狀態
bl ?__create_page_tables ?// 建立頁表
ldr ? ? r13, =__mmap_switched
b ? ? ? __enable_mmu
。。。
。。。
b ? ? ? __turn_mmu_on
450 ENTRY(__turn_mmu_on)
457 ? ? ? ? mov ? ? r3, r13
458 ? ? ? ? mov ? ? pc, r3//跳轉到__mmap_switched
__mmap_switched:
b ? ? ? start_kernel
start_kernel
-->rest_init
{
//建立一個新的內核線程
kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
}
kernel_init( )
{
prepare_namespace( )
{
//根據bootargs的參數,掛載根文件系統
mount_root( );
}
init_post( )
{
//執行用戶空間的1號進程
run_init_process("/sbin/init");
}
}
系統上電--->uboot完成硬件的初始化--->執行bootcmd中的命令--->加載操做系統到內存--->傳遞參數給內核,并啟動內核--->檢查CPU ID當前內核是否支持--->建立頁表開啟MMU--->start_kernel--->建立一個新的內核線程--->根據參數去掛載根文件系統--->從根文件系統中找到1號進程--->建立執行1號進程--->1號進程后續會建立子進程/bin/bash--->用戶能夠輸入命令
移植內核的關鍵文件:arch\arm\mach-s5p6818\cpu.c
其中的關鍵代碼信息:
static void __initcpu_init_machine ( void ) {
...
nxp_cpu_devs_register ( );
nxp_board_devs_register ( );
}
// 該函數是在 kernel_init 中被調用,即系統啟動過程當中被調用。
kernel_init ( ) {
do_basic_setup ( ) {
do_initcalls ( ) {
...
cpu_init_machine ( ); // 移植的重點。要改的函數。
}
}
}
四、配置過程是如何影響編譯過程的
$:' ?make menuconfig
Device Drivers ?--->
Character devices ?--->
-*- LED Support ?--->
// LED Support for GPIO connected LEDs ---> help
---> 變量:CONFIG_LEDS_GPIO
$:'vi .config
CONFIG_LEDS_GPIO=y ? ?//
CONFIG_LEDS_GPIO=m ?//
# CONFIG_LEDS_GPIO is not set ?// < >
【結論1】配置的結果是以變量取不一樣的值的形式保存在 .config 文件中。
【結論2】內核中幾乎全部的目錄下都有Makefile文件。
【結論3】各個子目錄下的Makefile決定了當前目錄下的文件(夾)是否參與編譯過程。
$:'grep "CONFIG_LEDS_GPIO" * -nRw
// grep顯示行號-遞歸-內容檢索:
drivers/leds/Makefile:22行使用了該變量
obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
? CONFIG_LEDS_GPIO=y ?' boj-y += leds-gpio.o
CONFIG_LEDS_GPIO=y ?' boj-m += leds-gpio.o
< > ? CONFIG_LEDS_GPIO=y ?' boj- ?+= leds-gpio.o
【結論4】
在編譯內核時 boj-y += xxx.o 表明 xxx.c 參與編譯,并最終連接到內核uImage;在編譯內核時 boj-m += xxx.o 表明 xxx.c 參與編譯,但不會連接進內核uImage,生成一個獨立的xxx.o;在編譯內核時 boj- ?+= xxx.o 表明 xxx.c 不參與編譯。
五、如何將一個.c文件編譯進內核
// env/led_drv.c
$:'cp /mnt/hgfs/porting/env/led_drv.c drivers/char/
$:'vi drivers/char/Makefile
增長1行:obj-y ? ? ? ? ? ? ? += led_drv.o
$:'make uImage
$:'cp arch/arm/boot/uImage ?/tftpboot/
#:'tftp 48000000 uImage
#:'bootm 48000000
#:'dmesg >1.txt
#:'dmesg | grep "led_init"
總結
以上是生活随笔為你收集整理的修改linux编译配置文件,Porting:linux内核编译、配置、修改配置文件、添加.c文件到内核...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是BASE最终一致性
- 下一篇: 算法笔记:二分查找