linux内核编译中常用的目标(二)
文章目录
一. 目标 all 或者 空
当在内核源码顶层目录下执行make的时候,编译的默认目标就是all。代码中的注释有对应的解释。
# The all: target is the default when no target is given on the
# command line.
# This allow a user to issue only 'make' to build a kernel including modules
# Defaults to vmlinux, but the arch makefile usually adds further targets
all: vmlinux
二. 目标 vmlinux
linux内核经过编译后会生成一个elf格式的可执行程序,叫vmlinux或vmlinuz,这个就是原始的未经任何处理加工的原版内核elf文件(后面博文会对它进行详细的讲解)。

三. 目标 modules
modules就是编译内核模块的。所以整个内核,可以简单的理解为 vmlinux + modules组成。
四. 目标 Image/zImage/uImage
1.Image和zImage的区别
内核编译(make)之后会生成两个文件,一个Image,一个zImage,其中Image为内核映像文件,而zImage为内核的一种映像压缩文件。
2.uImage
uImage又是什么呢?
它是uboot专用的映像文件,它是在zImage之前加上一个长度为64字节的“头”,说明这个内核的版本、加载位置、生成时间、大小等信息;其偏移0x40之后与zImage没区别。
64字节的头结构如下:
typedef struct image_header {
uint32_tih_magic;
uint32_tih_hcrc;
uint32_tih_time;
uint32_tih_size;
uint32_tih_load;
uint32_tih_ep;
uint32_tih_dcrc;
uint8_tih_os;
uint8_tih_arch;
uint8_tih_type;
uint8_tih_comp;
uint8_tih_name[IH_NMLEN];
} image_header_t;
所以,uImage和zImage都是压缩后的内核映像。而uImage是用mkimage工具根据zImage制作而来的。
u-boot里面的mkimage工具来生成uImage(u-boot源码包/tools/mkimage.c )
这里解释一下参数的意义:
-A ==> set architecture to 'arch'
-O ==> set operating system to 'os'
-T ==> set image type to 'type' “kernel或是ramdisk”
-C ==> set compression type 'comp'
-a ==> set load address to 'addr' (hex)
-e ==> set entry point to 'ep' (hex)(内核启动时在此位置查询完整的内核印象)
-n ==> set image name to 'name'
-d==> use image data from 'datafile'
-x ==> set XIP (execute in place,即不进行文件的拷贝,在当前位置执行)
对于ARM linux内核映象用法:
-A arm -------- 架构是arm,可取值参照uboot/common/image.c
-O linux -------- 操作系统是linux,可取值参照uboot/common/image.c
-T kernel -------- 类型是kernel,可取值参照uboot/common/image.c
-C none/bzip/gzip -------- 压缩类型,压缩方式参考uboot/common/image.c
-a 50008000 ---- image的载入地址(hex),通常为0x?00008000
-e 800080xx---- 内核的入口地址(hex),xx为0x40或者0x00
-n linux-xxx --- image的名字,随意
-d namexxx ---- 无头信息的image文件名,制作image的源文件
uImagexxx ---- 加了头信息之后的image文件名,随意
因为zImage是经过压缩而得到的,所以其自身就有解压缩代码。需要特别说明的是:
-a参数是内核的加载地址,-e参数是入口地址,两者可以一样,也可以不一样,依情况而定:
- 如果我们没用mkimage对内核进行处理的话,那直接把内核下载到0x50008000(不同开发板不同)再运行就行,内核会自解压运行(不过内核运行需要一个tag来传递参数,而这个tag建议是由BootLoader提供的,在U-Boot下默认是由bootm命令建立的)。
- 如果使用mkimage生成内核镜像文件的话,会在内核的前头加上了64byte的信息,供建立tag之用。bootm命令会首先判断bootm xxxx 这个指定的地址xxxx是否与-a指定的加载地址相同。
[1]如果不同的话会从这个地址开始提取出这个64byte的头部,对其进行分析,然后把去掉头部的内核复制到-a指定的load地址中去运行之(此时-e 和-a应保持一致)。
[2] 如果相同的话那就让其原封不同的放在那,但-e指定的入口地址会推后64byte,以跳过这64byte的头部(此时-e 和-a应不同)。
需要注意的是,因为uboot要重新搬运内核映像,所以要注意bootm xxxx的地址和-a之间的地址不要导致复制时的覆盖。
mkimage命令举例如下
./mkimage -n 'linux-2.6.38' -A arm -O linux -T kernel -C none -a 0x50008000 -e 0x50008000 -d zImage uImage
./mkimage -n 'linux-2.6.30' -A arm -O linux -T kernel -C none -a 0x50008000 -e 0x50008040 -d zImage uImage
五. 目标 M=drivers/xxx
这个可以看作是modules目标中的子集。比如:
make M=drivers/char
这条命令只会去编译mini6410_hello_module这个驱动,而不需要去运行对其他驱动代码的检测。对开发或者后期维护,都节省了相应的编译时间。
六. 目标 xxx.o
这是单独编译某个文件的,当你修改某个文件做开发的时候,你可以先单独编译你修改的文件确保没有语法错误,然后再编译内核或者是模块。
比如在/drivers/char目录中,更改了mem.o文件,那么你可以先运行
make M=drivers/char/mem.o
来确保单个文件的语法没有错误,然后再去编译整个模块。
七. 目标 xxx.s
这个作用是生成了指定文件的汇编代码。
make M=drivers/char/mem.s
这种编译会出生成c文件对应的汇编语言的文件。对于某些棘手问题,会很有用。但是通常内核出问题后,我还是习惯对vmlinux进行反汇编。
八. 目标 help
最后的最后,kbuild中提供了一个help的目标。当你不确定如何使用或者想知道还有哪些目标可以用那就执行
make help
你就可以知道都还有哪些用法了。
linux内核编译中常用的目标(二)的更多相关文章
- Linux内核编译中的各类错误示例
1. do_gettimeofday()函数的使用 linux发行版:Ubuntu22.04 linux内核:5.15.0-52-generic 预编译内核:linux-6.0.1 添加在linux- ...
- 《Linux内核设计与实现》 第一二章学习笔记
<Linux内核设计与实现> 第一二章学习笔记 第一章 Linux内核简介 1.1 Unix的历史 Unix的特点 Unix很简洁,所提供的系统调用都有很明确的设计目的. Unix中一切皆 ...
- Linux内核编译与安装
2013-04-16 Linux内核介绍 Linux内核是一个用C语言写成的,符合POSIX标准的类Unix操作系统.内核是操作系统中最基本的一部分,提供了众多应用程序访问计算机硬件的机制.L ...
- 《Linux内核设计与实现》第一二章读书笔记
第一章 Linux内核简介 1.Unix简介 (一)概念:支持抢占式多任务.多进程.虚拟内存.换页.动态链接和TCP/IP网络的现代化操作系统. (二)Unix特点(层次化结构): Unix很简洁,仅 ...
- 运行在TQ2440开发板上以及X86平台上的linux内核编译
一.运行在TQ2440开发板上的linux内核编译 1.获取源码并解压 直接使用天嵌移植好的“linux-2.6.30.4_20100531.tar.bz2”源码包. 解压(天嵌默认解压到/opt/E ...
- Lab1:Linux内核编译及添加系统调用(详细版)
实验一:Linux内核编译及添加系统调用(HDU) 花了一上午的时间来写这个,良心制作,发现自己刚学的时候没有找到很详细的,就是泛泛的说了下细节地方也没有,于是自己写了这个,有点长,如果你认真的看完了 ...
- Linux内核编译完整过程
Linux内核编译完整过程 通过网上的资料我自己的实际内核编译,我把对Linux内核编译的过程写在这里,也许对其他的Linux爱好者的编译学习有些帮助,其中很大部分是网上的资料,另外就是我在实际编译过 ...
- Linux内核--网络栈实现分析(二)--数据包的传递过程--转
转载地址http://blog.csdn.net/yming0221/article/details/7492423 作者:闫明 本文分析基于Linux Kernel 1.2.13 注:标题中的”(上 ...
- linux内核编译环境配置
linux内核编译环境配置 如果不是编译内核,只需要安装与内核相匹配的kernel-devel开发包即可.即是/lib/modules/`uname -r`/build -> /usr/src/ ...
- 嵌入式C语言自我修养 02:Linux 内核驱动中的指定初始化
2.1 什么是指定初始化 在标准 C 中,当我们定义并初始化一个数组时,常用方法如下: ] = {,,,,,,,,}; 按照这种固定的顺序,我们可以依次给 a[0] 和 a[8] 赋值.因为没有对 a ...
随机推荐
- Java SpringBoot 7z 压缩、解压
Java SpringBoot 7z 压缩.解压 cmd 7z 文件压缩 7z压缩测试 添加依赖 <dependency> <groupId>org.apache.common ...
- 火山引擎 DataTester:让企业“无代码”也能用起来的 A/B 实验平台
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 当数字化变革方兴未艾,无代码正受到前所未有的关注.Salesforce 的数据显示,52%的 IT 部门表示,公司 ...
- AspNetCore 成长杂记(一):JWT授权鉴权之生成JWT(其一)
引子 最近不知怎么的,自从学了WebAPI(为什么是这个,而不是MVC,还不是因为MVC的Razor语法比较难学,生态不如现有的Vue等框架,webapi很好的结合了前端生态)以后,使用别人的组件一帆 ...
- ByteHouse云数仓版查询性能优化和MySQL生态完善
ByteHouse云数仓版是字节跳动数据平台团队在复用开源 ClickHouse runtime 的基础上,基于云原生架构重构设计,并新增和优化了大量功能.在字节内部,ByteHouse被广泛用于各类 ...
- Golang defer使用
学习于https://www.liwenzhou.com/posts/Go/function/的文章 1. defer的执行顺序类似于栈,"后进先出",也就是最先defer的语句最 ...
- C# 自定义并动态切换光标
系统有很多光标类型 :Cursors 类 (System.Windows.Input) | Microsoft Docs 本章介绍如何自定义光标.并动态切换光标类型. 动态切换光标类型 以白板书写为例 ...
- 【Visual C#】基于《斗鱼弹幕服务器第三方接入协议v1.6.2》实现斗鱼弹幕服务器接入
最近在给某个主播开发斗鱼直播间辅助工具,为了程序的高效稳定,也搜索了大量的资料,经过大量什么百度,谷歌搜索... 虽然有很多Python的脚本及JS脚本实现了拉取斗鱼弹幕信息,但是这些年来的开发职业病 ...
- 2022-11-27:超过经理收入的员工。编写一个SQL查询来查找收入比经理高的员工。以下数据的结果输出是Joe,因为Joe是唯一挣得比经理多的雇员。 DROP TABLE IF EXISTS `em
2022-11-27:超过经理收入的员工.编写一个SQL查询来查找收入比经理高的员工.以下数据的结果输出是Joe,因为Joe是唯一挣得比经理多的雇员. DROP TABLE IF EXISTS `em ...
- 2021-10-19:缺失的区间。给定一个排序的整数数组 nums ,其中元素的范围在 闭区间 [lower, upper] 当中,返回不包含在数组中的缺失区间。力扣163。
2021-10-19:缺失的区间.给定一个排序的整数数组 nums ,其中元素的范围在 闭区间 [lower, upper] 当中,返回不包含在数组中的缺失区间.力扣163. 福大大 答案2021-1 ...
- pandas 数据处理 一些常用操作
读取csv文件,打印列名称: import pandas as pd # data = pd.read_csv("guba_fc_result_20230413.csv") dat ...