内核配置裁剪及启动流程(代码片段)

今天天气真好 今天天气真好     2022-12-04     627

关键词:

文章目录

一、内核分析之编译初体验

1.解压缩

2.配置
内核的配置有三种方法
(1)直接执行make menuconfig,从头到尾每一条都自己配置,有成千上万的配置项,比较复杂

(2)使用默认的配置,在这个基础上进行修改
先在内核目录下进行查找:find -name "*defconfig*"

进入对应的arch/arm/configs目录,可以看到:

那么就可以直接执行make s3c2410_defconfig进行配置
执行完之后会提示所有的配置项都被写到.config里面,因此这条命令的执行结果是保存在.config里面的
后面再执行make menuconfig,他肯定会去读取这个.config,然后出现一个菜单,可以在这个菜单上修改配置项

注意执行make menuconfig之前,需要安装ncrses,他是一个提供功能键定义、屏幕绘制以及基于文本终端的图形互动功能的动态库。

sudo apt-get install bc
sudo apt-get install libncurses5-dev libncursesw5-dev
sudo apt-get install zlib1g:i386
sudo apt-get install libc6-i386 lib32stdc++6 lib32gcc1 lib32ncurses5

之后执行make menuconfig就可以出现如下界面

(3)使用厂家提供的配置文件
方法就是直接将厂家的config文件复制为.config文件,然后make menuconfig进行配置

输入Y,就会被编译进内核里面
输入N,就不编译
输入M,就被做为一个模块,也就是一个驱动程序
输入*,build-in,表示编译进内核
输入M,表示被作为一个模块

3.编译
编译直接执行make命令即可
或者当我们想生成uImage,uImage就是在真正的内核前面加一个头部(uboot支持的内核有一个头部)
如果想编译一个内核给uboot用,那就执行make uImage

将编译好的UImage烧到单板上
菜单项里面的K是烧写UImage,然后打开dnw,进行发送
如下:

在源码目录下看到cmd_menu.c中命令K
他是先用usb命令来接受dnw发送的数据,收到之后就去擦除内核分区,然后再把30000000位置的东西烧写filesize大小到内核分区

4.启动内核
倒数计时之后,就会去执行bootcmd这个环境变量里面定义的两条命令,这两条命令一个是从flash中读出内核,一个是启动内核
烧写完之后可以使用b命令来进行启动,如下:

当然,我们这里没有烧写文件系统,所以最终会卡着

二、内核分析之配置

通过前面我们知道配置最终生成的是.config文件,里面有很多配置项,以DM9000为例,进行搜索可以看到:

y也就是会被编译进内核里面,继续搜索CONFIG_DM9000,可以看到如下:

1.C源码里面用到了CONFIG_DM9000,也就是一个宏,宏只能在头文件或者C文件中定义,因此是在include/linux/autoconf.h定义的

2.driver/net/Makefile,也就是子目录的Makefile里面有
对于子目录的Makefile,格式比较简单,

obj-y += xxx.o	表示xxx.c这个文件最终会被编译进内核里面
obj-m += yyy.o	表示yyy.c这个文件最终会被编译成一个可加载的模块yyy.ko

3.include/config/auto.config
对于子目录下的CONFIG_DM9000则是在include/config/auto.config中进行定义
同样,auto.config也是自动生成的,内容来源于.config
而include/config/auto.config则是被顶层的Makefile包含

4.include/generated/autoconf.h 自动生成的(make机制),里面的内容来源于.config,打开autoconf.h看时都是被定义为1的

因此我们执行make uImage的时候,发生了如下事情:
1、.config---->auto.config,这个文件是被源代码使用的
2、.config---->autoconf.h,这个文件是被顶层Makefile包含的,子目录下的Makefile来使用

三、内核分析之Makefile

首先我们从最简单的角度总结Makefile的作用:
(1)决定编译哪些文件
(2)怎么编译这些文件
(3)怎么链接这些文件,最重要的是他们的顺序如何

Linux内核Makefile文件分类如下:

1.分析子目录下的Makefile,以driver/char目录下的Makefile进行分析为例,可以看到:

如果CONFIG_SGI_SNSC这个变量在配置文件中被定义为y,则snsc.c snsc_event.c会被编译为snsc.o snsc_event.o,最后链接到内核里去

如果被定义为m,则snsc.c snsc_event.c会被编译为模块.ko文件

那么对于a.c和b.c两个文件
被编译进内核很简单,obj-y += a.o b.o
如果这两个要组成一个模块,则是:

obj-m += ab.o
ab-objs := a.o b.o

最终的结果就是a.c–>a.o,b.c–>b.o,然后这两者链接为ab.ko

注意到我们前面编译内核的时候使用的命令时make uImage。搜索发现uImage的时候发现uImage是在arch/arm/Makefile中定义
2.架构相关的Makefile
因为uImage是在这里定义,最终也会生成uImage,那么可以知道架构相关的Makefile肯定会被包含进顶层的Makefile


uImage依赖于vmlinux,uImage = 头部 + 真正的内核
因此我们制作uImage的时候要先编译出真正的内核,真正的内核就是vmlinux
vmlinux的依赖在顶层Makefile里面

3.顶层Makefile
在顶层Makefile里面可以看到是包含了架构相关的Makefile的

同时还会包含auto.config配置文件

分析vmlinux可以看到:


具体这里不详细介绍,可以分别进行搜索找出原材料。

为了更方便知道结果,可以指向make uImage V=1命令,V=1是将命令详细的列出来,执行这个命令来看最终是做了什么,执行了什么。

总结分析Makefile最终知道:
1.第一个文件:arch/arm/kernel/head.s
2.链接脚本:arch/arm/kernel/vmlinux.lds

四、内核分析之启动过程

从前面我们分析u-boot启动过程可以知道,先是设置参数,然后启动内核。怎么启动?执行thekernel这个函数。
theKernel就是内核的入口地址
第一个参数是0
第二个参数是机器ID
第三个参数是那些参数存放的地址

那么我们的内核首先就会去处理u-boot传过来的参数

注意内核的最终目的是运行应用程序
对于pc机来说应用程序在C盘,D盘。对于Linux来说是在根文件系统,因此需要挂接根文件系统,然后启动应用程序。

知道最开始和最终目的,下面来分析中间做了什么

补充一点:对于最终生成的很大的内核,可以进行压缩,最终得到一个很小的内核,在压缩后的内核前面加上一段自解压代码,最后内核就从自解压代码这里开始运行,自解压代码的作用就是将压缩后的内核解压出来,然后再去执行解压缩后的内核。

首先分析arch/arm/kernel/head.s文件
100ask/uboot-2.6/linux-2.6.22.6/arch/arm/kernel/head.s
所做的工作:
1.判断是否支持这个CPU
2.判断是否支持这个单板,也就是启动内核时传入的R1(机器ID)
3.建立页表
4.使能mmu

5.跳转执行start_kernel,这是kernel的第一个C函数,在这个C函数里面去处理启动参数

里面主要是进行一些初始化工作,前面我们已经处理了传进来的机器ID,但是启动参数还没有处理,这个函数里面的下面这两个函数就是用来处理传入的参数的

如果uboot没有传入命令行参数(也就是bootargs这个环境变量对应的参数),那就回使用默认的命令行参数default_command_line

同时也会调用rest_init函数,这个函数里面会去创建一个内核线程,想当于调用kernel_init这个函数

u-boot传过来的参数如下:

内核启动流程大致调用关系:

start_kernel
    setup_arch	//解析uboot传入的启动参数
    setup_command_line  //解析uboot传入的启动参数
    parse_early_param
    	do_early_param	//从_setup_start到_setup_end,调用early函数
    unknown_bootoption
    	obsolote_checksetup	//从_setup_start到_setup_end,调用非early函数
	rest_init
		kernel_init
			prepare_namespace
				mount_root	//挂接根文件系统
			init_post
				//执行应用程序

以命令行参数为例来进行分析:
进入u-boot可以看到:

分析代码可以发现:命令行参数最开始是被保存在某个字符串里面,对于不同的"root=",对应不同的处理函数root_dev_setup,这两者被定义在一个结构体里面,这些很多的结构体被链接脚本放到一块,在arch/arm/kernel/vmlinux.lds里面

*(.init.setup),调用的时候就从start一直搜索到end,具体怎么调用在前面内核调用流程里面

在flash里面没有分区表,但是从命令行参数得知有root = /dev/mtdblock3,那么整个分区怎么体现?

—>在代码里面写死

openharmonyliteos-m内核启动流程(代码片段)

文章目录【OpenHarmony】LiteOS-M内核启动流程一、LiteOS内核框架二、程序运行环境准备(上电执行)三、外设复位及关键外设初始化四、时钟树及片上外设配置五、内核初始化5.1基本内核功能初始化5.2其他系统功能初始化六... 查看详情

全志linux系统启动优化启动优化速度方式优化启动流程优化uboot优化kernel等(代码片段)

....3.3kernel启动优化.2.3.3.1kernel压缩方式.2.3.3.2加载位置2.3.3.3内核裁剪2.3.3.4预设置lpj数值2.3.3.5initcall优化2.3.3.6内核initcallmodule并行2.3.3.7减少pty/tty个数2.3.3.8内核module.2.3.3.9DeferredInitcalls2.3.4rootfs启动优化2.3.4.1initramfs2.3.4.2rootfs类型以及... 查看详情

全志linux系统启动优化启动优化速度方式优化启动流程优化uboot优化kernel等(代码片段)

....3.3kernel启动优化.2.3.3.1kernel压缩方式.2.3.3.2加载位置2.3.3.3内核裁剪2.3.3.4预设置lpj数值2.3.3.5initcall优化2.3.3.6内核initcallmodule并行2.3.3.7减少pty/tty个数2.3.3.8内核module.2.3.3.9DeferredInitcalls2.3.4rootfs启动优化2.3.4.1initramfs2.3.4.2rootfs类型以及... 查看详情

移值linux3.4.2内核之框架及初步修改(代码片段)

...程,一上电后BIOS会去引导扇区读取系统引导程序引导windows内核的启动,内核启动过程中会去识别C盘,D盘,装载驱动程序,启动应用,对于嵌入式LINUX来说,BIOS称为Bootloader,它主要完成的工作有如下3步1.装载内核到内存中2.设置TAG参数3.启... 查看详情

移值linux3.4.2内核之框架及初步修改(代码片段)

...程,一上电后BIOS会去引导扇区读取系统引导程序引导windows内核的启动,内核启动过程中会去识别C盘,D盘,装载驱动程序,启动应用,对于嵌入式LINUX来说,BIOS称为Bootloader,它主要完成的工作有如下3步1.装载内核到内存中2.设置TAG参数3.启... 查看详情

6-内核配置选项编写(代码片段)

内核裁剪的方式有两种:    第一种:makemenuconfig进入图形界面的配置。    第二种:就是打开源码进行相应的裁剪。这里我们先介绍一下第一种方式的裁剪方式:makemenuconfig  首先介绍下makemenuconfig这个命令实际上是... 查看详情

开机启动及grub基础知识和光盘镜像制作(代码片段)

...otfs(switchroot)-->/sbin/init加电自检启动bios读取mbr引导加载内核(ramdisk)根切换执行/sbin/init文件执行/etc/rc.d/目录下所有S开头的服务2、简述grub启动引导程序配置及 查看详情

centos7选定默认启动内核,及删除无用内核(代码片段)

转自https://www.cnblogs.com/niyeshiyoumo/p/6762193.htmlcentos7选定默认启动内核,及删除无用内核#使用cat/boot/grub2/grub.cfg|grepmenuentry查看系统可用内核[[email protected]-slave27~]#cat/boot/grub2/grub.cfg|grepmenuentryif[x" 查看详情

移值linux3.4.2内核之内核裁剪(代码片段)

...上图可知,留给kernel分区的大小只有2M但是我们制作出来的内核已经超过了2M首先裁剪内核里无关的CPU/单板文件如上图所示,我们可以AT2440EVB单板去掉执行makemenuconfig后按下’/’,进行搜索条目找到该配置选项的路径,然后选择对应单... 查看详情

centos启动流程及grublegacy

Linux系统的组成部分:内核+根文件系统内核的功能:进程管理、内存管理、网络管理、文件系统、驱动程序、安全功能系统在运行时要么就是在运行内核代码,要么就是在运行应用程序代码。如果一个程序大多数时间在内核的系... 查看详情

全志tinalinux系统裁剪boot0裁剪uboot裁剪内核裁剪文件系统裁剪c库裁剪文件系统压缩(代码片段)

文章目录1概述2Tina系统裁剪简介2.1boot0裁剪2.2uboot裁剪2.3内核裁剪2.3.1删除不使用的功能2.3.2删除不使用的驱动2.3.3修改内核源代码2.3.3.1size工具.2.3.3.2ksize.py脚本2.3.3.3nm命令2.3.3.4kernel压缩方式.2.4文件系统裁剪.2.4.1应用程序及冗余文... 查看详情

内核启动流程(代码片段)

1.链接脚本        liteos_a的链接脚本路径如下:OpenHarmony/kernel/liteos_a/tools/build/liteos_llvm.ld        链接脚本的内容如下:ENTRY(reset_vector)INCLUDEboard.ldINPUT(libuserinit.O)SECTIONS#各种段定义,此处全部省 查看详情

eurekaserver自动装配及启动流程解析(代码片段)

...系列的注解,主要作用我们之前也多次提到了,就是引入配置类而已。看一下源码吧@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import(EurekaServerMarkerConfiguration.class)public@interfaceEnableEurekaServer引入了一个配置类EurekaServerMa... 查看详情

移值linux3.4.2内核之内核裁剪(代码片段)

...上图可知,留给kernel分区的大小只有2M但是我们制作出来的内核已经超过了2M首先裁剪内核里无关的CPU/单板文件如上图所示,我们可以AT2440EVB单板去掉执行makemenuconfig后按下’/’,进行搜索条目找到该配置选项的路径,然后选择对应单... 查看详情

u-boot移植(十三)---代码修改---裁剪及环境变量一

一、内核裁剪  内核的裁剪首先就是修改我们的配置文件,即include/configs/jz2440.h文件,里面定义的很多宏,我们也许用不上的就要去掉。1/*2*(C)Copyright20023*SysgoReal-TimeSolutions,GmbH<www.elinos.com>4*MariusGroeger<[email protected]>... 查看详情

tina_linux_启动优化_开发指南(代码片段)

....3.3kernel启动优化.2.3.3.1kernel压缩方式.2.3.3.2加载位置2.3.3.3内核裁剪2.3.3.4预设置lpj数值2.3.3.5initcall优化2.3.3.6内核initcallmodule并行2.3.3.7减少pty/tty个数2.3.3.8内核module.2.3.3.9DeferredInitcalls2.3.4rootfs启动优化2.3.4.1initramfs2.3.4.2rootfs类型以及 查看详情

全志tinalinux系统裁剪boot0裁剪uboot裁剪内核裁剪文件系统裁剪c库裁剪文件系统压缩(代码片段)

文章目录1概述2Tina系统裁剪简介2.1boot0裁剪2.2uboot裁剪2.3内核裁剪2.3.1删除不使用的功能2.3.2删除不使用的驱动2.3.3修改内核源代码2.3.3.1size工具.2.3.3.2ksize.py脚本2.3.3.3nm命令2.3.3.4kernel压缩方式.2.4文件系统裁剪.2.4.1应用程序及冗余文... 查看详情

全志tinalinux系统裁剪boot0裁剪uboot裁剪内核裁剪文件系统裁剪c库裁剪文件系统压缩(代码片段)

文章目录1概述2Tina系统裁剪简介2.1boot0裁剪2.2uboot裁剪2.3内核裁剪2.3.1删除不使用的功能2.3.2删除不使用的驱动2.3.3修改内核源代码2.3.3.1size工具.2.3.3.2ksize.py脚本2.3.3.3nm命令2.3.3.4kernel压缩方式.2.4文件系统裁剪.2.4.1应用程序及冗余文... 查看详情