1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 修改linux编译配置文件 Porting:linux内核编译 配置 修改配置文件 添加.c文件到内核...

修改linux编译配置文件 Porting:linux内核编译 配置 修改配置文件 添加.c文件到内核...

时间:2022-05-01 22:17:26

相关推荐

修改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)

457mov r3, r13

458mov 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"

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。