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代码读取properties配置文件
读取properties配置文件 package com.easycrud.utils; import java.io.IOException; import java.io.InputStream; ...
- BugKu_never_give_up
if(!$_GET['id']) { header('Location: hello.php?id=1'); exit(); } $id=$_GET['id']; $a=$_GET['a']; $b= ...
- 2022-11-01:给定一个只由小写字母和数字字符组成的字符串str。 要求子串必须只含有一个小写字母,数字字符数量随意。 求这样的子串最大长度是多少?
2022-11-01:给定一个只由小写字母和数字字符组成的字符串str. 要求子串必须只含有一个小写字母,数字字符数量随意. 求这样的子串最大长度是多少? 答案2022-11-01: 经典的滑动窗口问 ...
- Linux基础 | 青训营笔记
课程介绍 以下是Linux系统的相关知识(但是并不全部出现在本文中) 学习Linux的价值 Liux是现代化应用程序交付的首选平台,无论是部署在裸机.虚拟化还是容器化环境 公司内部服务(TCE.Faa ...
- 2013年蓝桥杯C/C++大学A组省赛真题(排它平方数)
题目描述: 小明正看着 203879 这个数字发呆. 原来,203879 * 203879 = 41566646641 这有什么神奇呢?仔细观察,203879 是个6位数,并且它的每个数位上的数字都是 ...
- Java的jps命令使用详解
jps命令简介 jps(Java Virtual Machine Process Status Tool)是JDK提供的一个可以列出正在运行的Java虚拟机的进程信息的命令行工具,它可以显示Java虚 ...
- 荣登国家级榜单!ShowMeBug创始人李亚飞入选「科创中国·青年创业榜」
近日,中国科协召开2022"科创中国"年度会议,会上发布了2021"科创中国"系列榜单.其中,ShowMeBug 创始人&CEO李亚飞入选2021年科创 ...
- C++温故补缺(二十一):杂项补充2
杂记2 explicit 在 C++ 中,explicit 是一个关键字,用于修饰类的构造函数,其作用是禁止编译器将一个参数构造函数用于隐式类型转换.具体来说,当一个构造函数被 explicit 修饰 ...
- ChatGPT 问答
Win32GUI编程时,创建窗口触发消息的顺序 在Win32 GUI编程中,创建窗口并显示到屏幕上时,系统会触发一系列的消息,这些消息可以用来完成窗口的初始化和其他相关的工作.下面是创建窗口触发消息的 ...
- 深度学习应用篇-计算机视觉-图像分类[2]:LeNet、AlexNet、VGG、GoogleNet、DarkNet模型结构、实现、模型特点详细介绍
深度学习应用篇-计算机视觉-图像分类[2]:LeNet.AlexNet.VGG.GoogleNet.DarkNet模型结构.实现.模型特点详细介绍 1.LeNet(1998) LeNet是最早的卷积神 ...