Kernel Exploring
  • 前言
  • 支持
  • 老司机带你探索内核编译系统
    • 编译出你的第一个内核
    • 内核编译中的小目标
    • 可能是kbuild中最直接的小目标 – help
    • 使用了一个kbuild函数的目标 – cscope
    • 内核中单个.o文件的编译过程
    • 根目录vmlinux的编译过程
    • 启动镜像bzImage的前世今生
    • setup.bin的诞生记
    • 真假vmlinux–由vmlinux.bin揭开的秘密
    • bzImage的全貌
    • kbuild系统浅析
  • 启动时的小秘密
    • INIT_CALLS的秘密
    • 内核参数
  • 内核加载全流程
    • bootloader如何加载bzImage
    • 内核压缩与解压
    • 内核加载的几个阶段
    • 保护模式内核代码赏析
  • 内存管理
    • 内核页表成长记
      • 未解压时的内核页表
      • 内核早期的页表
      • cleanup_highmap之后的页表
      • 映射完整物理地址
      • 启用init_level4_pgt
    • 自底而上话内存
      • e820从硬件获取内存分布
      • 原始内存分配器--memblock
      • 页分配器
        • 寻找页结构体的位置
        • 眼花的页结构体
        • Node-Zone-Page
        • 传说的伙伴系统
        • Compound Page
        • GFP的功效
        • 页分配器的用户们
      • slub分配器
        • slub的理念
        • 图解slub
      • 内存管理的不同粒度
      • 挑战和进化
        • 扩展性的设计和实现
        • 减少竞争 per_cpu_pageset
        • 海量内存
        • 延迟初始化
        • 内存热插拔
        • 连续内存分配器
    • 虚拟内存空间
      • 页表和缺页中断
      • 虚拟地址空间的管家--vma
      • 匿名反向映射的前世今生
      • 图解匿名反向映射
      • THP和mapcount之间的恩恩怨怨
      • 透明大页的玄机
      • NUMA策略
      • numa balance
      • 老版vma
    • 内存的回收再利用
      • 水线
      • Big Picture
      • 手动触发回收
      • Page Fram Reclaim Algorithm
      • swapfile原理使用和演进
    • 内存隔离
      • memcg初始化
      • 限制memcg大小
      • 对memcg记账
    • 通用
      • 常用全局变量
      • 常用转换
    • 测试
      • 功能测试
      • 性能测试
  • 中断和异常
    • 从IDT开始
    • 中断?异常?有什么区别
    • 系统调用的实现
    • 异常向量表的设置
    • 中断向量和中断函数
    • APIC
    • 时钟中断
    • 软中断
    • 中断、软中断、抢占和多处理器
  • 设备模型
    • 总线
    • 驱动
    • 设备
    • 绑定
  • nvdimm初探
    • 使用手册
    • 上帝视角
    • nvdimm_bus
    • nvdimm
    • nd_region
    • nd_namespace_X
    • nd_dax
      • dev_dax
  • KVM
    • 内存虚拟化
      • Qemu内存模型
      • KVM内存管理
  • cgroup
    • 使用cgroup控制进程cpu和内存
    • cgroup文件系统
    • cgroup层次结构
    • cgroup和进程的关联
    • cgroup数据统计
  • 同步机制
    • 内存屏障
    • RCU
  • Trace/Profie/Debug
    • ftrace的使用
    • 探秘ftrace
    • 内核热补丁的黑科技
    • eBPF初探
    • TraceEvent
    • Drgn
  • 内核中的数据结构
    • 双链表
    • 优先级队列
    • 哈希表
    • xarray
    • B树
    • Maple Tree
    • Interval Tree
  • Tools
  • Good To Read
    • 内核自带文档
    • 内存相关
    • 下载社区邮件
Powered by GitBook
On this page
  • all 或者 空
  • vmlinux
  • modules
  • bzImage
  • M=drivers/xxx
  • dir/file.o
  • dir/file.i
  • dir/file.s
  • cscope
  • isoimage
  • help

Was this helpful?

  1. 老司机带你探索内核编译系统

内核编译中的小目标

王首富定过一个亿的小目标,虽然我们内核中没有一个亿,却还是有不少有意思的小目标的。

这些小目标可以帮助我们

  • 生成辅助资料

  • 生成单个目标文件

  • 节约时间

  • 偶尔可以帮助一下调试

那我们就一个个讲吧~

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

这个目标在x86平台 =

vmlinux + modules + bzImage

vmlinux

嗯,这个就是你编译完成后在linux源代码目录下的那个vmlinux了。

注意了,这个是一个ELF的文件哦。用处嘛,以后你会慢慢知道的。

modules

modules就是编译内核模块的。

所以整个内核,你可以理解为就是 vmlinux + modules组成的。

bzImage

那既然vmlinux + modules组成了整个内核,多出来了一个bzImage来插什么腿?

这个东西可以看作是vmlinux的衍生。你看vmlinux是ELF格式的,首先在引导程序要加载的时候你得有人看得懂这个格式,另外这个文件比较大。现在4.9的内核编译下来vmlinux就有422M这么大,直接放到启动分区实在太占地方。当然我这个没有裁剪,裁剪后应该可以相应减少,但是恐怕也不会小太多。

所以bzImage可以粗暴地理解为

ELF加载器 + 压缩了的vmlinux。

整个压缩完之后bzImage大小只有7M不到了,这压缩能力杠杠的。

M=drivers/xxx

这个可以看作是modules目标中的更小的一个目标了。

举一个栗子大家看了或许更明白。

make M=drivers/net/ethernet/intel/ixgbe/

这条命令只会去编译ixgbe这个驱动,而不需要去运行对其他驱动代码的检测。对开发或者后期维护,都节省了相应的编译时间。

dir/file.o

这是单独编译某个文件的,当你修改某个文件做开发的时候,你可以先单独编译你修改的文件确保没有语法错误,然后再编译内核或者是模块。

比如在ixgbe模块中,更改了ixgbe_ethtool.o文件,那么你可以先运行

make drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.o

来确保单个文件的语法没有错误,然后再去编译整个模块。

同样这也是可以节省编译时间的,尤其是当遇到某个文件编译有错误的时候。

dir/file.i

这个目标是针对某个文件只做到预处理,也就是把所有的头文件和宏定义都展开了。

用法很简单

make mm/memblock.i

就生成了mm/memblock.i文件,其结果是已经预处理完的,也就是个种宏定义展开后的。

感觉用处不是很多,能想到的就是在阅读内核源代码的时候可以确定到底这个宏定义的是啥。因为内核需要在不同的架构体系下运行,而且同一架构体系下又有不同的配置。所以同样一个函数或者宏会在不同情况下定义成不同的样子,有时候直接肉眼去看代码不一定能看得准。

那怎么办呢?

这个时候就可以执行这个命令,直接看预处理后的文件,或许可以有助于你理解代码那么一点点。

dir/file.s

这个作用是生成了指定文件的汇编代码。

用法类似

make mm/memblock.s

这估计是要做汇编级的调试了,俺还从来没有整过。

cscope

这个目标特殊,已经不是代码了,是生成cscope的文件。嗯,这个文件是用来辅助阅读代码的。

懂得人秒懂,不懂的估计得重新开一个话题了。

isoimage

这个还是Andi Kleen告诉我的。这是一个包含内核的可以启动的iso文件。 用来调试用的,用得真的不多。

有兴趣的朋友或许可以在我其他的文章中见到它的身影。

help

最后的最后,kbuild中提供了一个help的目标。当你不确定如何使用或者想知道还有哪些目标可以用那就执行

make help

你就可以知道都还有哪些用法了。

好了,小目标们讲完了。现在是不是对内核编译又有了点了解?强烈建议没有编译过这些小目标的筒子手动运行一下,看一看执行的结果加深内核编译过程的印象。

还是那句话

纸上得来终觉浅,绝知此事须躬行

Previous编译出你的第一个内核Next可能是kbuild中最直接的小目标 – help

Last updated 3 years ago

Was this helpful?