linux 内核裁剪与编译

作者: Mr_Michael | 来源:发表于2019-08-27 14:56 被阅读0次

    一、Linux 内核源码

    www.kernel.org 下载官方内内核。

    1.linux内核目录

    $ tree kernel/ -L 1
    kernel/
    ├── android
    ├── arch
    ├── backported-features
    ├── block
    ├── boot.img
    ├── build.config.cuttlefish.aarch64
    ├── build.config.cuttlefish.x86_64
    ├── certs
    ├── config.old
    ├── COPYING
    ├── CREDITS
    ├── crypto
    ├── Documentation
    ├── drivers
    ├── firmware
    ├── fs
    ├── include
    ├── init
    ├── ipc
    ├── Kbuild
    ├── Kconfig
    ├── kernel
    ├── kernel.img
    ├── lib
    ├── logo.bmp
    ├── MAINTAINERS
    ├── Makefile
    ├── mm
    ├── modules.builtin
    ├── modules.order
    ├── Module.symvers
    ├── net
    ├── README
    ├── REPORTING-BUGS
    ├── resource.img
    ├── samples
    ├── scripts
    ├── security
    ├── sound
    ├── System.map
    ├── tools
    ├── usr
    ├── verity_dev_keys.x509
    ├── virt
    ├── vmlinux
    ├── vmlinux.o
    └── zboot.img
    
    23 directories, 24 file
    

    目录说明

    • arch:包含和硬件体系结构相关的代码,每种平台占一个相应的目录,如 i386、arm、arm64、powerpc、mips 等。Linux 内核目前已经支持30种左右的体系结构。
      • 在 arch 目录下,存放的是各个平台以及各个平台的芯片对 Linux 内核进程调度、内存管理、中断等的支持,以及每个具体的 SoC 和电路板的板级支持代码。
    • block:块设备驱动程序 I/O 调度。
    • crypto:常用加密和散列算法(如AES、SHA等),还有一些压缩和 CRC 校验算法。
    • documentation:内核各部分的通用解释和注释。
    • drivers:设备驱动程序。每个不同的驱动占用一个子目录,如 char、block、net、mtd、 i2c 等。
    • fs:所支持的各种文件系统,如EXT、FAT、NTFS、JFFS2等。
    • include:内核 API 级別头文件,与系统相关的头文件放置在 include/linux 子目录下。
    • init:内核初始化代码。著名的 stait_kemel() 就位于 init/main.c 文件中。
    • ipc:进程间通信的代码。
    • kernel:内核最核心的部分,包括进程调度、定时器等,而和平台相关的一部分代码放在 arch/*/kemel 目录下。
    • lib:库文件代码。
    • mm:内存管理代码,和平台相关的一部分代码放在arch/*/mm目录下。
    • net:网络相关代码,实现各种常见的网络协议。
    • scripts:用于配置内核的脚本文件。
    • security:主要是一个 SELinux 的模块。
    • sound:ALSA、OSS 音频设备的驱动核心代码和常用设备驱动。
    • usr:实现用于打包和压缩的 cpio 等。

    2.快速确定主板关联代码

    板级基础代码

    Linux 移植通常分为体系结构级别移植、处理器级别移植和板级移植 。

    • 确定体系架构相关的文件

      $ tree arch/arm64/ -L 1
      arch/arm64/
      ├── boot
      ├── configs
      ├── crypto
      ├── include
      ├── Kconfig
      ├── Kconfig.debug
      ├── Kconfig.platforms
      ├── kernel
      ├── kvm
      ├── lib
      ├── Makefile
      ├── mm
      ├── net
      └── xen
      
      • 确定内核配置文件,决定编译的内核模块和驱动。

        • 如:默认内核配置文件为<arch/arm64/configs/rockchip_linux_defconfig>

          # 部分内容
          CONFIG_DEFAULT_HOSTNAME="localhost"
          CONFIG_SYSVIPC=y
          CONFIG_POSIX_MQUEUE=y
          CONFIG_FHANDLE=y
          CONFIG_NO_HZ=y
          CONFIG_HIGH_RES_TIMERS=y
          CONFIG_LOG_BUF_SHIFT=18
          CONFIG_CGROUPS=y
          CONFIG_CGROUP_FREEZER=y
          CONFIG_CGROUP_PIDS=y
          CONFIG_CGROUP_DEVICE=y
          CONFIG_CPUSETS=y
          CONFIG_CGROUP_CPUACCT=y
          CONFIG_MEMCG=y
          CONFIG_MEMCG_SWAP=y
          CONFIG_CGROUP_PERF=y
          CONFIG_CGROUP_SCHED=y
          CONFIG_CFS_BANDWIDTH=y
          CONFIG_RT_GROUP_SCHED=y
          CONFIG_BLK_CGROUP=y
          CONFIG_NAMESPACES=y
          CONFIG_USER_NS=y
          ...
          
      • 确定设备树文件,决定板级外设配置

        • 如:<arch/arm64/boot/dts/rockchip/rk3399-firefly-aioc.dts>
    • 确定对应的主板文件(32位板子)。

      • 如:<arch/arm/mach-omap2/board-am335xevm.c>
      • <arch/arm/mach-mxs/mach-mx28evk.c>

    驱动代码

    ​ 驱动代码在drivers 目录

    其它代码

    ​ 文件系统的实现代码、网络子系统的实现代码等。

    2.Linux 内核中的 Makefile 文件

    1)顶层 Makefile

    源码目录树顶层 Makefile 是整个内核源码管理的入口,对整个内核的源码编译起着决定性作用。编译内核时,顶层 Makefile 会按规则递归历遍内核源码的所有子目录下的Makefile 文件,完成各子目录下内核模块的编译。

    内核版本号

    顶层 Makefile,开头的几行记录了内核源码的版本号 。

    VERSION = 2
    PATCHLEVEL = 6
    SUBLEVEL = 35
    EXTRAVERSION =3
    #说明代码版本为 2.6.35.3
    

    内核在目标板运行后,输入 uname -a 命令可以得到印证 。

    编译控制
    • 体系结构

      • Linux 是一个支持众多体系结构的操作系统,在编译过程中需指定体系结构,以与实际平台对应。在顶层 Makefile 中,通过变量 ARCH 来指定 。

      • ARCH ?= $(SUBARCH)
        #如果进行 ARM 嵌入式 Linux 开发,则必须指定 ARCH 为 arm(注意大小写,须与 arch/目录下的 arm 一致)
        #如:$make ARCH=arm
        
    • 编译器

      • 进行 ARM 嵌入式 Linux 开发,必须指定交叉编译器,可以在内核配置通过 CONFIG_CROSS_COMPILE 指定交叉编译器,也可以通过 CROSS_COMPILE 指定。

      $ make ARCH=arm CROSS_COMPILE= arm-linux-gnueabihf-

      
      ```makefile
      CROSS_COMPILE = arm-linux-gnueabihf-
      #注意: CROSS_COMPILE 指定的交叉编译器必须事先安装并正确设置系统环境变量; 如果没有设置环境变量, 则需使用绝对地址
      

    2)子目录的 Makefile

    几乎每个子目录都有相应的 Makefile 文件,管理着对应目录下的代码。

    Makefile 中有两种表示方式:

    • 一种是默认选择编译,用 obj-y 表示

      • obj-y += usb-host.o # 默认编译 usb-host.c 文件
        obj-y += gpio/ # 默认编译 gpio 目录
        
    • 另一种表示则与内核配置选项相关联,编译与否以及编译方式取决于内核配置 。

      • obj-$(CONFIG_WDT) += wdt.o # wdt.c 编译控制
        obj-$(CONFIG_PCI) += pci/ # pci 目录编译控制
        

        是否编译 wdt.c 文件,或者以何种方式编译,取决于内核配置后的变量 CONFIG_WDT值:如果在配置中设置为[*],则静态编译到内核,如果配置为[M],则编译为 wdt.ko 模块,否则不编译。

    3.Linux 内核中的 Kconfig 文件

    ​ 内核源码树每个目录下都还包含一个 Kconfig 文件,用于描述所在目录源代码相关的内核配置菜单,各个目录的 Kconfig 文件构成了一个分布式的内核配置数据库。

    ​ 通过 make menuconfig(make xconfig 或者 make gconfig)命令配置内核的时候,从 Kconfig 文件读取单,配置完毕保存到文件名为.config 的内核配置文件中,供 Makefile 文件在编译内核时使用。

    1)Kconfig的格式

    ​ Kconfig按照一定的格式来书写,menuconfig程序可以识别这种格式,然后从中提取出有效信息组成menuconfig中的菜单项。

    ​ 截取/drivers/net下的Kconfig文件中的部分内容:

    # Network device configuration
    menuconfig NETDEVICES
            default y if UML
            depends on NET
            bool "Network device support"
            ---help---
              You can say N here if you don't intend to connect your Linux box to any other computer at all.
    ……
    config DM9000
            tristate "DM9000 support"
            depends on ARM || BLACKFIN || MIPS
            select CRC32
            select MII
            ---help---
              Support for DM9000 chipset.
    
              To compile this driver as a module, choose M here.  The module will be called dm9000.
    ……
    source "drivers/net/arcnet/Kconfig"
    source "drivers/net/phy/Kconfig"
    
    • menuconfig:表示菜单(本身属于一个菜单中的项目,但是又有子菜单项目)、config表示菜单中的一个配置项(本身并没有子菜单下的项目)。一个menuconfig后面跟着的所有config项就是这个menuconfig的子菜单。这就是Kconfig中表示的目录关系。
    • NETDEVICES:配置项名字,用大写字母表示。这个字符串前面添加CONFIG_后就构成了“.config”文件中的配置项名字。
    • source:内核源码目录树中每一个Kconfig都会用source引入其所有子目录下的Kconfig,从而保证了所有的Kconfig项目都被包含进menuconfig中。
      • 如果在linux内核中添加了一个文件夹,一定要在这个文件夹下创建一个Kconfig文件,然后在这个文件夹的上一层目录的Kconfig中source引入这个文件夹下的Kconfig文件。
    • tristate:意思是三态(3种状态,对应Y、N、M三种选择方式),意思就是这个配置项可以被三种选择。
    • bool:是要么真要么假(对应Y和N)。意思是这个配置项只能被2种选择。
    • depends:意思是本配置项依赖于另一个配置项。如果那个依赖的配置项为Y或者M,则本配置项才有意义;如果依赖的哪个配置项本身被设置为N,则本配置项根本没有意义。
    • select:表示depends on的值有效时,下面的select也会成立,将相应的内容选上。
    • default:表示depends on的值有效时,下面的default也会成立,将相应的选项选上,有三种选项,分别对应y,n,m。
    • help:帮助信息,解释这个配置项的含义,以及如何去配置他。

    2)Kconfig和.config文件和Makefile三者的关联

    • 配置项被配置成Y、N、M会影响“.config”文件中的CONFIG_XXX变量的配置值。
    • .config”中的配置值(=y、=m、没有)会影响最终的Makefile编译链接过程,如makefile中:obj-$(CONFIG_DM9000) += dm9000.o
      • 如果=y则会被编入(built-in);
      • 如果=m会被单独连接成一个”.ko”内核模块(需要insmod动态加载到内核中);
      • 如果没有则对应的代码不会被编译。

    4.Linux 内核源码配置执行过程

    关键文件

    • Kconfig ---> (每个源码目录下)提供选项
    • .config ---> (源码顶层目录下)保存选择结果
    • Makefile---> (每个源码目录下)根据.config中的内容来告知编译系统如何编译

    1)执行步骤

    • 系统读取arch/$ARCH/目录下的Kconfig文件生成整个配置界面选项(Kconfig是整个linux配置机制的核心)。

      • 那么ARCH环境变量的值由linux内核根目录下的makefile文件决定的,在makefile有此环境变量的定义。
      • 或者通过 make ARCH=arm menuconfig命令来生成配置界面。
    • 修改内核配置后,当保存make menuconfig选项时,系统会将配置保存在内核根目录下.config文件。还会将所有的选项以宏的形式保存在Linux内核根目录下的 include/generated/autoconf.h文件下。

      • 内核有默认配置选项提供,存放在arch/$ARCH/configs下,可以将所需的配置复制到内核根目录下.config文件。
      $ cp arch/arm64/configs/rockchip_linux_defconfig .config
      
    • 执行make编译,会根据.config文件所配置的选项(=y、=m、没有)逐个进行编译。

      • 或者可以指定编译配置文件

        # Kernel defconfig
        export RK_KERNEL_DEFCONFIG=rockchip_linux_defconfig
        # Kernel dts
        export RK_KERNEL_DTS=rk3399-firefly-aioc
        
        $ make ARCH=arm64 $RK_KERNEL_DEFCONFIG
        $ make ARCH=arm64 $RK_KERNEL_DTS.img
        

    二、配置和编译 Linux 内核

    1.快速配置内核

    进入 Linux 内核源码数顶层目录,输入 make menuconfig 命令 。

    注意: 主机须安装 ncurses 相关库才能正确运行该命令并出现配置界面 。

    如果没有在 Makefile 中指定 ARCH,则须在命令行中指定

    $ make ARCH=arm menuconfig
    

    2.内核配置详情

    菜单项 说明
    General setup ---> 内核通用配置选项,包括交叉编译器前缀、本地版本、内核压缩模式、 config.gz 支持、内核 log 缓冲区大小、 initramfs以及更多的内核运行特性支持等
    [ ] Enable loadable module support ---> 内核模块加载支持,通常都需要
    [ ] Enable the block layer ---> 使能块设备。如果未选中使能,块设备将不能使用, SCSI类字符设备和 USB 大容量类设备也将不能使用。
    System Type ---> 系统类型,设置 ARM 处理器型号、处理器的特性以及默认的评估板主板
    Bus support ---> PCMCIA/CardBUS 总线支持,目前已经很少使用
    Kernel Features ---> 内核特性,包括内核空间分配、实时性配置等特性配置
    Boot options ---> 内核启动选项,如果采用内置启动参数,则在这里设置
    CPU Power Management ---> CPU 电源管理,包括处理器频率降频、休眠模式支持等
    Floating point emulation ---> 浮点模拟
    Userspace binary formats ---> 用户空间二进制支持
    Power management options ---> 电源管理选项
    [ ] Networking support ---> 网络协议支持,包括网络选项、 CAN-Bus、红外、无线、 NFC等。其中的网络选项还有更多配置项,如 IPv4、 IPv6 等
    Device Drivers ---> 设备驱动,包含多级下级菜单,包括驱动通用选项、 MTD设备、字符设备、网络设备、输入设备、 I2C 总线、 SPI 总线、 USB 总线、 GPIO、声卡、显卡等各种外设配置菜单
    File systems ---> 文件系统, 包含 Ext2、 Ext3、 Ext4、 JFFS、 NFS、 DOS 等各种文件系统, 以及本地语言支持等
    Kernel hacking ---> 内核 Hacking,在内核调试阶段可酌情使能其中的选项,以获得需要的调试信息
    Security options ---> 安全选项
    < > Cryptographic API ---> 加密接口,内核提供的一些加密算法如 CRC32、MD5、SHA1、SHA224 等
    OCF Configuration ---> 开放的加密框架
    Library routines ---> 库例程
    Load an Alternate Configuration File 装载一个配置文件
    ave an Alternate Configuration File 保存为一个配置文件

    1)通用设置 General setup

    选项 说明
    ( ) Cross-compiler tool prefix 交叉编译器前缀,将会设置 CONFIG_CROSS_COMPILE 变量, 等同于 make CROSS_COMPILE=prefix-
    ( ) Local version - append to kernel release 填写本地版本
    [ ] Automatically append version informationto the version string 自动增加版本信息。如果用了 Git 管理内核源码,每次 Git提交都会造成内核版本号增加。谨慎使用该选项
    < > Kernel .config support 选中该选项会将当前内核配置信息保存到内核中
    [ ] Enable access to .config through/proc/config.gz 通过/proc/config.gz 获得当前运行内核的配置信息。建议选中
    [ ] Initial RAM filesystem and RAM disk(initramfs/initrd) support Initramfs 支持,使能该特性可以将一个文件系统打包到内核文件中,内核启动不需要额外的文件系统
    ( ) Initramfs source file(s) Initramfs 文件系统的路径,通常放在源码树 usr 目录下

    2)内核特性 Kernel Features

    选项 说明
    [ ] Tickless System (Dynamic Ticks) 无时钟系统支持,根据系统运行状况来启用或者禁用时钟,能让内核运行更有效且更省电。 A8 这样的处理器建议选中
    [ ] High Resolution Timer Support 高精度定时器。处理器支持则可选中
    Memory split (3G/1G user/kernel split)---> 4G 内存分割比例,内核和用户空间: 3G/1G、 2G/2G、 1G/2G。早期内核是 3G/1G 固定分割,目前可配置
    Preemption Model (No Forced Preemption(Server)) ---> 内核抢占模式,可选值:No Forced Preemption (Server)Voluntary Kernel Preemption (Desktop)Preemptible Kernel (Low-Latency Desktop)需要实时性则须设置为 Preemptible Kernel
    [ ] Compile the kernel in Thumb-2 mode(EXPERIMENTAL) 以 Thumb-2 指令集编译内核。不推荐
    [ ] High Memory Support 高端内存,嵌入式系统通常不用选

    3)启动选项

    默认启动参数通过“Default kernel command string”设置

    (root=/dev/mmcblk0p2 rootwait console=ttyO0,115200) Default kernel command string
    

    内核参数类型通过 Kernel command line type 来设置

    • ( ) Use bootloader kernel arguments if available
      • 可接受bootloader传递的参数启动
    • ( ) Extend bootloader kernel arguments
    • ( ) Always use the default kernel command string
      • 只能使用默认内核启动参数

    4)网络支持

    网络支持部分,包括了以太网、 CAN、红外、蓝牙、无线等各种网络的支持配置选项。

    从 Networking support -> Networking options, 可进入网络选项配置界面 。

    选项 说明
    < > Packet socket 选中支持应用直接与网卡通信而不需要在内核中实现网络协议,建议选中
    < > Unix domain sockets UNIX domain Socket 支持,建议选中。如果采用 udev/mdev动态管理设备,则必须选中
    < > PF_KEY sockets PF_KEY 协议族,内核安全相关,建议选中
    [ ] TCP/IP networking TCP/IP 支持,使用网络通常需选中,还有更多的下级菜单,如 IPv4、 IPv6 等设置
    [ ] Network packet filtering framework(Netfilter) ---> 对网络数据包进行过滤,如果需要防火墙功能,则必须选中。有下级菜单,根据实际需要配置
    < > 802.1d Ethernet Bridging 802.1d 以太网桥
    < > 802.1Q VLAN Support 802.1Q 虚拟局域网
    [ ] QoS and/or fair queueing ---> Qos 支持,该选项可支持多种不同的包调度算法,否则仅能使用简单的 FIFO 算法

    使用 Linux 的系统都会用到网络,而使用网络又往往离不开 TCP/TP,故建议在配置中选中 TCP/IP 选项,并选中下级全部选项 。

    5)设备驱动

    选项 说明
    Generic Driver Options ---> 通用设备驱动选项
    CBUS support ---> CBUS 支持,不清楚则不要选
    < > Connector - unified userspace <-> kernelspacelinker ---> 统一的用户空间<-->内核空间连接器,工作在 Netlinksocket 协议顶层,不确定则不选
    < > Memory Technology Device (MTD) support---> 内存技术设备,如 FLASH、 RAM 等支持。通常需要选中
    Device Tree and Open Firmware support ---> /proc 设备树支持,可选中
    < > Parallel port support ---> 并口支持,嵌入式系统通常不选
    [ ] Block devices ---> 块设备,选中,否则不能操作任何块设备
    [ ] Misc devices ---> 杂项设备。通常选中,如需用 eeprom 设备,则必选
    SCSI device support ---> SCSI 设备支持。如要用 U 盘,则必选
    < > Serial ATA and Parallel ATA drivers ---> SATA 和 PATA 设备支持。除非硬件支持,否则不选
    [ ] Multiple devices driver support (RAID and LVM)---> 多设备支持(RAID&LVM),嵌入式通常不选
    < > Generic Target Core Mod (TCM) and ConfigFSInfrastructure ---> TCM 存储引擎和 ConfigFS 控制
    [ ] Network device support ---> 网络设备支持,包括网卡、 PHY 驱动、 ppp 协议等选择
    [ ] ISDN support ---> ISDN 支持
    < > Telephony support ---> 电话支持。在 Linux 下使用 Modem 拨号,无需使能该选项
    Input device support ---> 输入设备支持,包括键盘、鼠标、触摸屏、游戏杆等
    Character devices ---> 字符设备,包括 tty 等设备。特别注意,串口驱动配置也在这里面
    < > I2C support ---> I2C 支持。 I2C 协议和控制器配置
    [ ] SPI support ---> SPI 支持。 SPI 协议和 SPI 控制器
    PPS support ---> PPS 支持
    PTP clock support ---> PTP 时钟支持
    [ ] GPIO Support ---> GPIO 支持
    < > PWM Support ---> PWM 支持
    < > Dallas's 1-wire support ---> Dallas 单总线支持
    < > Power supply class support ---> 电源管理类支持
    < > Hardware Monitoring support ---> 硬件监测支持,各种传感器
    < > Generic Thermal sysfs driver ---> Thermal sysfs 接口支持
    [ ] Watchdog Timer Support ---> 看门狗支持,包括硬件看门狗和软件看门狗
    Sonics Silicon Backplane ---> SSB 总线支持
    Broadcom specific AMBA ---> 博通 AMBA 总线支持
    Multifunction device drivers ---> 多功能设备驱动支持
    [ ] Voltage and Current Regulator Support ---> 电压和电流调节支持。如果有电源管理芯片,通常需要选中
    < > Multimedia support ---> 多媒体支持。 V4L2 在这里面配置
    Graphics support ---> 图形支持。 Framebuffer、背光、 LCD、开机 LOGO 等配置
    < > Sound card support ---> 声卡支持
    [ ] HID Devices ---> HID 设备,使用 USB 鼠标键盘等 HID 设备必须选中该选项
    [ ] USB support ---> USB 支持
    < > MMC/SD/SDIO card support ---> SD/MMC 设备支持
    < > Sony MemoryStick card support(EXPERIMENTAL) ---> Sony 记忆棒支持
    [ ] LED Support ---> LED 子系统和驱动
    [ ] Accessibility support ---> 易用性支持,嵌入式通常不选
    [*] Real Time Clock ---> 实时时钟,包括处理器内部时钟和外扩时钟选择
    [ ] DMA Engine support ---> 引擎支持
    [ ] Auxiliary Display support ---> 辅助显示支持
    < > Userspace I/O drivers ---> 用户空间 I/O 驱动(uio 支持)
    Virtio drivers ---> Virtio 驱动
    [*] Staging drivers ---> 分阶段驱动
    Hardware Spinlock drivers ---> 硬件 Spinlock 驱动
    [ ] IOMMU Hardware Support ---> IOMMU 硬件支持,根据具体硬件选择
    [ ] Virtualization drivers ---> 虚拟化驱动
    [ ] Generic Dynamic Voltage and Frequency Scaling(DVFS) support ---> 通用的动态电压和频率调节

    6)文件系统 File systems

    选项 说明
    < > Second extended fs support Ext2 文件系统支持,建议选中或模块编译
    < > Ext3 journalling file system support Ext3 文件系统支持,建议选中或模块编译
    < > The Extended 4 (ext4) filesystem Ext4 文件系统支持,建议选中或模块编译
    < > Reiserfs support Reiserfs 是一种先进的文件系统,不过嵌入式中不常用
    < > JFS filesystem support IBM 开发的日志文件系统,嵌入式中不常用
    < > XFS filesystem support XFS 文件系统支持
    < > GFS2 file system support GFS2 文件系统支持
    < > Btrfs filesystem (EXPERIMENTAL)Unstable disk format BtrFS 文件系统支持。 BtrFS 是一种新型文件系统,被称为下一代 Linux 文件系统
    < > NILFS2 file system support(EXPERIMENTAL) NiLFS2 文件系统支持
    [ ] Dnotify support 文件系统通知系统,建议选中
    [ ] Inotify support for userspace 用户空间 Inotify 支持,建议选中
    [ ] Filesystem wide access notification Fanotify 支持,能比 Inotify 传递更多信息
    [ ] Quota support 磁盘配额支持。选中后可限制某个用户或者某组用户的磁盘占用空间。嵌入式中不常用
    < > Kernel automounter version 4support (also supports v3) 第 4 版内核自动加载远程文件系统支持(同时支持第 3 版)
    < > FUSE (Filesystem in Userspace) support 选中后则允许在用户空间实现一个文件系统
    Caches ---> 文件系统 Cache 支持
    CD-ROM/DVD Filesystems ---> CD-ROM 和 DVD 支持,有 ISO 9660 和 UDF 两个选项。如果需要支持 CD/DVD,则可选
    DOS/FAT/NT Filesystems ---> DOS/FAT/NTFS 文件系统支持。如果需要支持 U 盘,必须选中 MDOS 和 VFAT 支持
    Pseudo filesystems ---> 伪文件系统,基于内存的文件系统,如 tmpfs
    [ ] Miscellaneous filesystems ---> 其它杂项文件系统,很多文件系统都归类在这里,嵌入式中常用的 cramfs、 ubifs 等都在这里配置
    [ ] Network File Systems ---> 网络文件系统。建议选中,通过 NFS 能方便调试,对于嵌入 式系统, NFS Server 通常不选
    Partition Types ---> 分区支持
    < > Native language support ---> 本地语言支持,通常选中 iso-8859-1、 CP437、 CP437 和 utf-8等

    3.编译内核

    1)从内核码源编译成zImage

    内核配置完成,输入 make 命令即可开始编译内核。如果没有修改 Makefile 文件并指定
    ARCH 和 CROSS_COMPILE 参数,则须在命令行中指定 。

    $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
    

    目前大多数主机都是多核处理器,为了加快编译进度,可以开启多线程编译,在 make
    的时候加上“-jN”即可, N 的值为处理器核心数目的 2 倍。

    $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- -j8
    

    如果编译不出错,编译完成,会生成 vmlinux、 Image、 zImage 等文件

    文件 说明 备注
    vmlinux 未经压缩、带调试信息和符号表的内核文件, elf 格式 顶层目录下
    arch/arm/boot/compressed/vmlinux 经过压缩的 Image,并加入了解压头的 elf 格式文件
    arch/arm/boot/Image 将 vmlinux 去除调试信息、注释和符号表等,只包含内核代码和数据后得到的非 elf 格式文件
    arch/arm/boot/zImage 经过 objcopy 处理,能直接下载到内存中执行的内核映像文件
    • zImage

    zImage 是通常情况下默认的压缩内核,可以直接加载到内存地址并开始执行。

    • uImage

    对于 ARM Linux 系统,大多数采用 U-Boot 引导,很少直接使用 zImage 映像,实际上
    更多的是 uImage。

    uImage 是 U-Boot 默认采用的内核映像文件,它是在 zImage 内核映像之
    前加上了一个长度为 64 字节信息头的映像。这 64 字节信息头包括映像文件的类型、加载位置、生成时间、大小等信息 。

    在 U-Boot 下,通过 bootm 命令可以引导 uImage 映像文件启动。

    $ tftp C0008000 uImage
    $ bootm C0008000
    

    2)把zImage转为uImage

    • mkimage 工具

    从 zImage 生成 uImage 需要用到 mkimage 工具。该工具可在编译 U-Boot 源码后从 tools目录下获得,复制到系统/usr/bin 目录即可 。

    对于 Ubuntu 系统,还可用 sudo apt-get installu-boot-tools 命令安装得到。

    进入 mkimage 文件所在目录执行该文件,或者在安装 mkimage工具后,使用 mkimage 工具根据 zImage 制作 uImage 映像文件的命令如下:

    $ mkimage [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image
    #命令参数中需要指定体系结构、操作系统类型、压缩方式和入口地址等信息
    
    参数 说明
    -A arch 指定处理器的体系结构为 arch,可能值有: alpha、 arm、 x86、 ia64、 mips、 mips64、 ppc、s390、 sh、 sparc、 sparc64、 m68k 等
    -O os 指定操作系统类型为 os,可用值有: openbsd、 netbsd、 freebsd、 4_4bsd、 linux、 svr4、 esix、solaris、 irix、 sco、 dell、 ncr、 lynxos、 vxworks、 psos、 qnx、 u-boot、 rtems、 artos 等
    -T type 指定映象类型为 type,可能值有: standalone、 kernel、 ramdisk、 multi、 firmware、 script、filesystem 等
    -C comp 指定映象压缩方式为 comp,可能值有:none 不压缩(推荐, zImage 已经过 bzip2 压缩,通常无需再压缩)gzip 用 gzip 的压缩方式bzip2 用 bzip2 的压缩方式
    -a addr 指定映象在内存中的加载地址为 addr(16 进制)。制作好的映象下载到内存时, 须按照该参数所指定的地址值来下载。 U-Boot 的 bootm xxx 命令会判断 xxx 是否与 addr 相同:(1)如果不同,则从 xxx 这个地址开始提取出这个 64 字节的头部,对其进行分析,然后把去掉头部的内核复制到 addr 地址中去运行。(2)如果相同,则不作处理, 仅将-e 指定的入口地址推后 64 字节, 即跳过这 64 字节的头部信息。
    -e ep 指定映象运行的入口地址为 ep(16 进制)。 ep 的值为 addr+0x40,也可设置为和 addr 相同
    -n name 指定映象文件名为 name
    -d data_file 指定制作映象的源文件,通常是 zImage
    image 输出的 uImage 映像文件名称,通常设置为 uImage

    对于 EPC-28x 处理器,内存起始地址为 0x40000000,从 zImage 生成 uImage 映像文件
    的命令实际操作范例:

    $ mkimage -A arm -O linux -T kernel -C none -a 0x40008000 -e 0x40008000 -n 'Linux-2.6.35' -d arch/arm/boot/zImage arch/arm/boot/uImage
    

    内存地址与处理器相关,在不同处理器上可能有差异 .

    查看一个 uImage 映像文件的文件头信息

    $ mkimage -l uImage
    Image Name: Linux-2.6.35.3-571-gcca29a0-g191
    Created: Tue Nov 17 11:57:47 2015
    Image Type: ARM Linux Kernel Image (uncompressed)
    Data Size: 2572336 Bytes = 2512.05 kB = 2.45 MB
    Load Address: 40008000
    Entry Point: 40008000
    

    3)从内核源码直接生成 uImage

    在<arch/arm/boot/Makefile>文件中给出了 uImage 的生成规则:

    quiet_cmd_uimage = UIMAGE $@
        cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A arm -O linux -T kernel \
                    -C none -a $(LOADADDR) -e $(STARTADDR) \
                    -n 'Linux-$(KERNELRELEASE)' -d $< $@
    

    生成 uImage 的编译命令为 make uImage

    $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- -j8 uImage
    

    4)编译内核模块

    如果内核中有配置为<M>的模块或者驱动,需要在编译内核后再通过 make modules 命
    令编译这些模块或者驱动

    $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- modules
    

    编译得到的内核模块文件以“.ko”结尾,这些可以通过 insmod 命令插入到运行的内核中。

    $ insmod kernel/drivers/net/bonding/bonding.ko
    

    有的模块则可能编译后得到多个“.ko”文件,或者依赖于其它模块文件,且各文件插入还有顺序要求, 需要通过 make modules_install 命令安装模块 ,可将编译得到的全部模块安装到某一目录下,并且还会生成模块的依赖关系文件。

    $ make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- INSTALL_MOD_PATH=/home/chenxibing/work/rootfs modules_install
    

    安装后将在安装目录下生成“lib/modules/内核版本/”目录,将“lib/modules/内核版本/”复制到目标系统后根目录后,就可以用 modprobe 命令进行模块安装

    #模块依赖关系
    kernel/drivers/net/bonding/bonding.ko: 
    kernel/drivers/usb/serial/usbserial.ko: 
    kernel/drivers/usb/serial/ftdi_sio.ko:kernel/drivers/usb/serial/usbserial.ko 
    
    # modprobe ftdi_sio
    

    4.运行内核

    得到 uImage 映像文件后,将 uImage 加载到内存地址 ep-0x40 处(0x40007fc0),通过 bootm 命令即可运行内核:

    # tftp 40007fc0 uImage
    # bootm 40007fc0
    

    相关文章

      网友评论

        本文标题:linux 内核裁剪与编译

        本文链接:https://www.haomeiwen.com/subject/zwseectx.html