一. 目标 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内核编译中常用的目标(二)的更多相关文章

  1. Linux内核编译中的各类错误示例

    1. do_gettimeofday()函数的使用 linux发行版:Ubuntu22.04 linux内核:5.15.0-52-generic 预编译内核:linux-6.0.1 添加在linux- ...

  2. 《Linux内核设计与实现》 第一二章学习笔记

    <Linux内核设计与实现> 第一二章学习笔记 第一章 Linux内核简介 1.1 Unix的历史 Unix的特点 Unix很简洁,所提供的系统调用都有很明确的设计目的. Unix中一切皆 ...

  3. Linux内核编译与安装

    2013-04-16    Linux内核介绍  Linux内核是一个用C语言写成的,符合POSIX标准的类Unix操作系统.内核是操作系统中最基本的一部分,提供了众多应用程序访问计算机硬件的机制.L ...

  4. 《Linux内核设计与实现》第一二章读书笔记

    第一章 Linux内核简介 1.Unix简介 (一)概念:支持抢占式多任务.多进程.虚拟内存.换页.动态链接和TCP/IP网络的现代化操作系统. (二)Unix特点(层次化结构): Unix很简洁,仅 ...

  5. 运行在TQ2440开发板上以及X86平台上的linux内核编译

    一.运行在TQ2440开发板上的linux内核编译 1.获取源码并解压 直接使用天嵌移植好的“linux-2.6.30.4_20100531.tar.bz2”源码包. 解压(天嵌默认解压到/opt/E ...

  6. Lab1:Linux内核编译及添加系统调用(详细版)

    实验一:Linux内核编译及添加系统调用(HDU) 花了一上午的时间来写这个,良心制作,发现自己刚学的时候没有找到很详细的,就是泛泛的说了下细节地方也没有,于是自己写了这个,有点长,如果你认真的看完了 ...

  7. Linux内核编译完整过程

    Linux内核编译完整过程 通过网上的资料我自己的实际内核编译,我把对Linux内核编译的过程写在这里,也许对其他的Linux爱好者的编译学习有些帮助,其中很大部分是网上的资料,另外就是我在实际编译过 ...

  8. Linux内核--网络栈实现分析(二)--数据包的传递过程--转

    转载地址http://blog.csdn.net/yming0221/article/details/7492423 作者:闫明 本文分析基于Linux Kernel 1.2.13 注:标题中的”(上 ...

  9. linux内核编译环境配置

    linux内核编译环境配置 如果不是编译内核,只需要安装与内核相匹配的kernel-devel开发包即可.即是/lib/modules/`uname -r`/build -> /usr/src/ ...

  10. 嵌入式C语言自我修养 02:Linux 内核驱动中的指定初始化

    2.1 什么是指定初始化 在标准 C 中,当我们定义并初始化一个数组时,常用方法如下: ] = {,,,,,,,,}; 按照这种固定的顺序,我们可以依次给 a[0] 和 a[8] 赋值.因为没有对 a ...

随机推荐

  1. facebook分享不能显示图片链接问题

    <meta property="og:url" content="http://www.nytimes.com/2015/02/19/arts/internatio ...

  2. APISIX 是怎么保护用户的敏感数据不被泄露的?

    本文以 APISIX 作为例子,为大家介绍了如何借助 Global Data Encryption 功能来保护敏感数据,确保不会有任何敏感数据进行明文存储,这样即使 etcd 中所有存储的数据都被盗取 ...

  3. Puppeteer+RabbitMQ:Node.js 批量加工pdf服务架构设计与落地

    全文约8500字,阅读时长约10分钟. 智慧作业最近上线「个性化手册」(简称个册)功能,一份完整的个性化手册分为三部分: •学情分析:根据学生阶段性的学习和考试情况进行学情分析.归纳.总结,汇总学情数 ...

  4. html/css 添加图片

    通过img.src添加图片 添加一个img元素,设置content,会发现在IE.safari等浏览器内显示为空白. 一般我们使用img,是通过src来设置的,可以通过react的import图片添加 ...

  5. Redis篇一之基础数据结构

    文章目录 Redis的数据结构 String类型**** Hash类型 List类型 Set类型 SortedSet类型 BitMap类型 HyperLogLog 总结 Redis诞生于2009年全称 ...

  6. HTML中meta标签的那些属性

    <meta> 标签是 HTML 中用于描述网页元信息的元素.它位于 <head> 部分,不会显示在页面内容中,但对于浏览器.搜索引擎等具有重要作用.主要作用有:定义文档的字符编 ...

  7. 2020-10-23:go中channel的创建流程是什么?

    福哥答案2020-10-23:1.元素大小是否小于2的16次方,否则throw.2.对齐检查,否则throw.3.元素大小和容量的乘积不能超出范围,否则panic.4.生成*hchan,设置buf.4 ...

  8. 2022-07-21:给定一个字符串str,和一个正数k, 你可以随意的划分str成多个子串, 目的是找到在某一种划分方案中,有尽可能多的回文子串,长度>=k,并且没有重合。 返回有几个回文子串。 来

    2022-07-21:给定一个字符串str,和一个正数k, 你可以随意的划分str成多个子串, 目的是找到在某一种划分方案中,有尽可能多的回文子串,长度>=k,并且没有重合. 返回有几个回文子串 ...

  9. 爆肝一周,我开源了ChatGPT 中文版接口,官方1:1镜像支持全部 官方接口

    这里实现我之前文章承诺承接上文 人人实现ChatGPT自由,手把手教你零撸部署自己聊天私服 现在ChatGPT 提供了api接口 可以让我自己对接去实现我们自己想要gpt应用,但是由于一些原因,国内也 ...

  10. 2023-05-16:给你一个 严格升序排列 的正整数数组 arr 和一个整数 k 。 请你找到这个数组里第 k 个缺失的正整数。 输入:arr = [2,3,4,7,11], k = 5。 输出:9

    2023-05-16:给你一个 严格升序排列 的正整数数组 arr 和一个整数 k . 请你找到这个数组里第 k 个缺失的正整数. 输入:arr = [2,3,4,7,11], k = 5. 输出:9 ...