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

本文详细介绍了Linux内核的版本查看、主要功能、编译过程以及配置方法。通过实例展示了如何裁剪内核功能、解决编译异常问题,并解析了内核启动流程。此外,还探讨了配置过程如何影响编译,并给出了将自定义.c文件编译进内核的步骤。
摘要由CSDN通过智能技术生成

一、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"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值