Linux内核编译

编译linux内核

# 下载安装lzop库
sudo apt-get install lzop
# 解压linux压缩包
tar -vxjf xxxx.tar.bz2
# 在linux内核工程中加上shell文件,内容如下
#!/bin/sh
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
bear make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j4

编译完成以后就会在 arch/arm/boot 这个目录下生成一个叫做 zImage 的文件,zImage 就是
我们要用的 Linux 镜像文件。另外也会在 arch/arm/boot/dts 下生成很多.dtb 文件,这些.dtb 就是
设备树文件。

linux工程目录结构分析

在这里插入图片描述

目录结构详解

请添加图片描述

在这里插入图片描述

在这里插入图片描述

  • arch目录

这个目录是和架构有关的目录,比如 arm、arm64、avr32、x86 等等架构。

arch/arm中子目录用于控制系统引导、系统调用、动态调 频、主频设置等。arch/arm/configs 目录是不同平台的默认配置文件:xxx_defconfig

arch/arm/boot/dts 目录里面是对应开发平台的设备树文件。arch/arm/boot 目录下会保存编译出来的 Image 和 zImage 镜像文件,而 zImage 就是我们要 用的 linux 镜像文件arch/arm/mach-xxx 目录分别为相应平台的驱动和初始化文件,比如 mach-imx 目录里面就是 I.MX 系列 CPU 的驱动和初始化文件

  • block目录

block 是 Linux 下块设备目录,像 SD 卡、EMMC、NAND、硬盘等存储设备就属于块设备,
block 目录中存放着管理块设备的相关文件。

  • crypto目录

crypto 目录里面存放着加密文件,比如常见的 crc、crc32、md4、md5、hash 等加密算法。

  • Documentation 目录

此目录里面存放着 Linux 相关的文档,如果要想了解 Linux 某个功能模块或驱动架构的功能,就可以在 Documentation 目录中查找有没有对应的文档。

  • drivers目录

驱动目录文件,此目录根据驱动类型的不同,分门别类进行整理,比如 drivers/i2c 就是 I2C 相关驱动目录,drivers/gpio 就是 GPIO 相关的驱动目录。

  • firmware目录

存放固件。

  • fs目录

此目录存放文件系统,比如 fs/ext2、fs/ext4、fs/f2fs 等,分别是 ext2、ext4 和 f2fs 等文件系统。

  • include目录

头文件目录。

  • init目录

存放 Linux 内核启动的时候初始化代码。

  • ipc目录

IPC 为进程间通信,ipc 目录是进程间通信的具体实现代码。

  • kernel目录

linux内核代码。

  • lib目录

lib的意思就是库的意思,所以存放各种公用的库。

  • mm目录

存放内存管理相关代码的目录。

  • net目录

存放网络相关代码的目录。

  • samples目录

存放一些示例代码的目录

  • scripts目录

脚本目录,Linux 编译的时候会用到很多脚本文件,这些脚本文件就保存在此目录中。

  • security目录

存放安全相关的代码。

  • sound目录

存放音频相关驱动文件,音频驱动文件并没有存放到 drivers 目录中,而是单独的目录。

  • tools目录

存放一些编译的时候使用到的工具。

  • usr目录

存放与 initramfs 有关的代码。

initramfs是一个临时的文件系统,其中包含了必要的设备如硬盘、网卡、文件系统等的驱动以及加载驱动的工具及其运行环境,比如基本的C库,动态库的链接加载器等等。同时,那些处理根文件系统在RAID、网络设备上的程序也存放在initramfs中。由第三方程序(如Bootloader)负责将initramfs从硬盘装载进内存。

  • virt目录

目录存放虚拟机相关文件。

  • .config文件

跟 uboot 一样,.config 保存着 Linux 最终的配置信息,编译 Linux 的时候会读取此文件中的配置信息。最终根据配置信息来选择编译 Linux 哪些模块,哪些功能。

  • Kbuild文件

有些Makefile文件会调用他。

  • Kconfig文件

图形化配置界面的配置文件

  • Makefile文件

编译,调用其他文件夹下面的Makefile,生成.config文件等等。顶层Makefile,需要好好的阅读一下。

  • README文件

此文件详细讲解了如何编译 Linux 源码,以及 Linux 源码的目录信息。

VSCode 创建linux源码工程

先创建.vscode目录并新建文件settings.json。其中的内容是:

{
    /*在收索的路径中去掉文件夹或者文件*/
    "search.exclude": {  
        "**/node_modules": true,
        "**/bower_components": true,
        "**/*.o": true,
        "**/*.su": true,
        "**/*.cmd": true,
        "Documentation": true,
        ".tmp*": true,
        /* 屏蔽不用的架构相关的文件    */
        "arch/alpha": true,
        "arch/arc": true,
        "arch/arm64": true,
        "arch/avr32": true,
        "arch/[b-z]*": true,
        "arch/arm/plat*": true,
        "arch/arm/mach-[a-h]*": true,
        "arch/arm/mach-[n-z]*": true,
        "arch/arm/mach-i[n-z]*": true,
        "arch/arm/mach-m[e-v]*": true,
        "arch/arm/mach-k*": true,
        "arch/arm/mach-l*": true,
        /* 屏蔽排除不用的配置文件    */
        "arch/arm/configs/[a-h]*": true,
        "arch/arm/configs/[j-z]*": true,
        "arch/arm/configs/imo*": true,
        "arch/arm/configs/in*": true,
        "arch/arm/configs/io*": true,
        "arch/arm/configs/ix*": true,
        /* 屏蔽掉不用的  DTB 文件    */
        "arch/arm/boot/dts/[a-h]*": true,
        "arch/arm/boot/dts/[k-z]*": true,
        "arch/arm/boot/dts/in*": true,
        "arch/arm/boot/dts/imx1*": true,
        "arch/arm/boot/dts/imx7*": true,
        "arch/arm/boot/dts/imx2*": true,
        "arch/arm/boot/dts/imx3*": true,
        "arch/arm/boot/dts/imx5*": true,
        "arch/arm/boot/dts/imx6d*": true,
        "arch/arm/boot/dts/imx6q*": true,
        "arch/arm/boot/dts/imx6s*": true,
        "arch/arm/boot/dts/imx6ul-*": true,
        "arch/arm/boot/dts/imx6ull-9x9*": true,
        "arch/arm/boot/dts/imx6ull-14x14-ddr*": true,
        "arch/arm/boot/dts/.[a-h]*": true,
        "arch/arm/boot/dts/.[k-z]*": true,
        "arch/arm/boot/dts/.in*": true,
        "arch/arm/boot/dts/.imx1*": true,
        "arch/arm/boot/dts/.imx7*": true,
        "arch/arm/boot/dts/.imx2*": true,
        "arch/arm/boot/dts/.imx3*": true,
        "arch/arm/boot/dts/.imx5*": true,
        "arch/arm/boot/dts/.imx6d*": true,
        "arch/arm/boot/dts/.imx6q*": true,
        "arch/arm/boot/dts/.imx6s*": true,
        "arch/arm/boot/dts/.imx6ul-*": true,
        "arch/arm/boot/dts/.imx6ul*": true,
        "arch/arm/boot/dts/.imx6ull-9x9*": true,
        "arch/arm/boot/dts/.imx6ull-14x14-ddr*": true
    },
    /*去掉显示的文件和文件夹*/
    "files.exclude": {
        "**/.git": true,
        "**/.svn": true,
        "**/.hg": true,
        "**/CVS": true,
        "**/.DS_Store": true,
        "**/*.o": true,
        "**/*.su": true,
        "**/*.cmd": true,
        "Documentation": true,
        ".tmp*": true,
        /* 屏蔽不用的架构相关的文件    */
        "arch/alpha": true,
        "arch/arc": true,
        "arch/arm64": true,
        "arch/avr32": true,
        "arch/[b-z]*": true,
        "arch/arm/plat*": true,
        "arch/arm/mach-[a-h]*": true,
        "arch/arm/mach-[n-z]*": true,
        "arch/arm/mach-i[n-z]*": true,
        "arch/arm/mach-m[e-v]*": true,
        "arch/arm/mach-k*": true,
        "arch/arm/mach-l*": true,
        /* 屏蔽排除不用的配置文件    */
        "arch/arm/configs/[a-h]*": true,
        "arch/arm/configs/[j-z]*": true,
        "arch/arm/configs/imo*": true,
        "arch/arm/configs/in*": true,
        "arch/arm/configs/io*": true,
        "arch/arm/configs/ix*": true,
        /* 屏蔽掉不用的  DTB 文件    */
        "arch/arm/boot/dts/[a-h]*": true,
        "arch/arm/boot/dts/[k-z]*": true,
        "arch/arm/boot/dts/in*": true,
        "arch/arm/boot/dts/imx1*": true,
        "arch/arm/boot/dts/imx7*": true,
        "arch/arm/boot/dts/imx2*": true,
        "arch/arm/boot/dts/imx3*": true,
        "arch/arm/boot/dts/imx5*": true,
        "arch/arm/boot/dts/imx6d*": true,
        "arch/arm/boot/dts/imx6q*": true,
        "arch/arm/boot/dts/imx6s*": true,
        "arch/arm/boot/dts/imx6ul-*": true,
        "arch/arm/boot/dts/imx6ull-9x9*": true,
        "arch/arm/boot/dts/imx6ull-14x14-ddr*": true,
        "arch/arm/boot/dts/.[a-h]*": true,
        "arch/arm/boot/dts/.[k-z]*": true,
        "arch/arm/boot/dts/.in*": true,
        "arch/arm/boot/dts/.imx1*": true,
        "arch/arm/boot/dts/.imx7*": true,
        "arch/arm/boot/dts/.imx2*": true,
        "arch/arm/boot/dts/.imx3*": true,
        "arch/arm/boot/dts/.imx5*": true,
        "arch/arm/boot/dts/.imx6d*": true,
        "arch/arm/boot/dts/.imx6q*": true,
        "arch/arm/boot/dts/.imx6s*": true,
        "arch/arm/boot/dts/.imx6ul-*": true,
        "arch/arm/boot/dts/.imx6ul*": true,
        "arch/arm/boot/dts/.imx6ull-9x9*": true,
        "arch/arm/boot/dts/.imx6ull-14x14-ddr*": true
    }
}

顶层Makefile分析

基本和uboot的Makefile分析相似。

make zImage的过程

各个Image区别

vmlinux 是 ELF 格式的文件,但是在实际中我们不会使用 vmlinux,而是使用 zImage 或 uImage 这样的 Linux 内核镜像文件。

  • vmlinux 是编译出来的最原始的内核文件,是未压缩的。大小16M左右。

  • Image 是 Linux 内核镜像文件,但是 Image 仅包含可执行的二进制数据。Image 就是使用 objcopy 取消掉 vmlinux 中的一些其他信息,比如符号表什么的。但是 Image 是没有压缩过的,Image 保存arch/arm/boot 目录下,其大小大概在 12MB 左右。

  • zImage 是经过 gzip 压缩后的 Image,经过压缩以后其大小大概在 6MB 左右。

  • uImage 是老版本 uboot 专用的镜像文件,uImag 是在 zImage 前面加了一个长度为 64字节的“头”,这个头信息描述了该镜像文件的类型、加载位置、生成时间、大小等信息。但是新的 uboot 已经支持了 zImage 启动!所以已经很少用到 uImage 了。

# 使用“make zImage”编译的 Linux 内核的话,首先肯定要先编译出 vmlinux
$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@
@ make -f ./scripts/Makefile.build obj=arch/arm/boot MACHINE=arch/arm/boot/zImage
# 使用 scripts/Makefile.build 文件来完成 vmlinux 到  zImage 的转换

linux内核移植

修改顶层Makefile

修改顶层 Makefile,直接在顶层 Makefile 文件里面定义 ARCHCROSS_COMPILE 这两个的变量值为 armarm-linux-gnueabihf-。这样在编译的时候就不用输入很长的命令了。

在这里插入图片描述

配置并编译 Linux 内核

uboot 一样,在编译 Linux 内核之前要先配置 Linux 内核。每个板子都有其对应的默认配 置 文 件 , 这 些 默 认 配 置 文 件 保 存 在 arch/arm/configs 目录中。imx_v7_defconfigimx_v7_mfg_defconfig 都可作为 I.MX6ULL EVK 开发板所使用的默认配置文件。但是这里建议使用 imx_v7_mfg_defconfig 这个默认配置文件,首先此配置文件默认支持 I.MX6UL 这款芯片,而且重要的一点就是此文件编译出来的 zImage 可以通过 NXP 官方提供的 MfgTool 工具烧写!!imx_v7_mfg_defconfig 中的“mfg”的意思就是 MfgTool

make clean # 清理工程
make imx_v7_mfg_deconfig  # 配置linux
make V=1 -j8  # 编译

Linux 内核编译完成以后会在 arch/arm/boot 目录下生成 zImage 镜像文件,如果使用设备树的话还会在 arch/arm/boot/dts 目录下开发板对应的.dtb(设备树)文件,比如 imx6ull-14x14-evk.dtb 就是 NXP 官方的 I.MX6ULL EVK 开发板对应的设备树文件

在linux中添加自己的开发板

添加开发板默认配置文件

arch/arm/configs 目录下的 imx_v7_mfg_defconfig重新复制一份 ,命名为imx_dongfang_emmc_defconfig

cd arch/arm/configs/
cp imx_v7_mfg_defconfig imx_dongfang_emmc_defconfig

添加开发板对应的设备树文件

进入目录 arch/arm/boot/dts 中,复制一份 imx6ull-14x14-evk.dts,然后将其重命名为 imx6ull-dongfang-emmc.dts

cd arch/arm/boot/dts
cp imx6ull-14x14-evk.dts imx6ull-dongfang-emmc.dts

.dts 是设备树源码文件,编译 Linux 的时候会将其编译为.dtb 文件。imx6ull-dongfang-emmc.dts 创 建 好 以 后 我 们 还 需 要 修 改 文 件 arch/arm/boot/dts/Makefile , 找 到 “ dtb-$(CONFIG_SOC_IMX6ULL)”配置项,在此配置项中加入“imx6ull-dongfang-emmc.dtb”。

vi Makefile
/dtb-$(CONFIG_SOC_IMX6ULL)  # 收索到该配置所在地方
# 在其中添加一样代码
# imx6ull-dongfang-emmc.dtb \

在这里插入图片描述

编译修改的自己的linux。添加mx6ull_dongfang_emmc.sh文件

#!/bin/bash
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_dongfang_emmc_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
bear make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j8

CPU 主频和网络驱动修改

CPU 主频修改

进入根文件系统终端后,可以使用cat /proc/cpuinfo查看CPU信息。

在这里插入图片描述

BogoMIPS 是 Linux 系统中衡量处理器运行速度的一个 “ 尺 子 ”, 处理器性能越强 , 主频越高 , BogoMIPS 值 就越大 。BogoMIPS 只是粗略的计算 CPU 性能,并不十分准确。但是我们可以通过 BogoMIPS 值来大致
的判断当前处理器的性能。

查看工作频率:进入到目录/sys/bus/cpu/devices/cpu0/cpufreq 中,此目录下会有很多文件。

在这里插入图片描述

  • cpuinfo_cur_freq:当前 cpu 工作频率,从 CPU 寄存器读取到的工作频率。
  • cpuinfo_max_freq:处理器所能运行的最高工作频率(单位: KHz)。
  • cpuinfo_min_freq :处理器所能运行的最低工作频率(单位: KHz)。
  • cpuinfo_transition_latency:处理器切换频率所需要的时间(单位:ns)。
  • scaling_available_frequencies:处理器支持的主频率列表(单位: KHz)。
  • scaling_available_governors:当前内核中支持的所有 governor(调频)类型。
  • scaling_cur_freq:保存着 cpufreq 模块缓存的当前 CPU 频率,不会对 CPU 硬件寄存器进
    行检查。
  • scaling_driver:该文件保存当前 CPU 所使用的调频驱动。
  • scaling_governor:governor(调频)策略,Linux 内核一共有 5 中调频策略,
    ①、Performance,最高性能,直接用最高频率,不考虑耗电。
    ②、Interactive,一开始直接用最高频率,然后根据 CPU 负载慢慢降低。
    ③、Powersave,省电模式,通常以最低频率运行,系统性能会受影响,一般不会用这个!
    ④、Userspace,可以在用户空间手动调节频率。
    ⑤、Ondemand,定时检查负载,然后根据负载来调节频率。负载低的时候降低 CPU 频率,这样省电,负载高的时候提高 CPU 频率,增加性能。
  • scaling_max_freq:governor(调频)可以调节的最高频率。
  • cpuinfo_min_freq:governor(调频)可以调节的最低频率。
  • stats 目录下给出了 CPU 各种运行频率的统计情况,比如 CPU 在各频率下的运行时间以及
    变频次数。

设置一直工作在做高频率

  • 第一种方法:
# 在arch/arm/configs/imx_dongfang_emmc_defconfig文件中修改
# 注释掉第一下面的第一句,并添加最后一句上去
#CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
  • 第二种方法
make menuconfig # 进入图形化配置
# 在下面的路径中修改为performance即可
CPU Power Management           
	-> CPU Frequency scaling 
		-> Default CPUFreq governor

设置超频

设置超频,修改一下设备树文件 arch/arm/boot/dts/imx6ull.dtsi 即可。

cpu0: cpu@0 {
			compatible = "arm,cortex-a7";
			device_type = "cpu";
			reg = <0>;
			clock-latency = <61036>; /* two CLK32 periods */
			operating-points = <
				/* kHz	uV */
				996000	1275000
				792000	1225000
				528000	1175000
				396000	1025000
				198000	950000
			>;
			fsl,soc-operating-points = <
				/* KHz	uV */
				996000	1175000
				792000	1175000
				528000	1175000
				396000	1175000
				198000	1175000
			>;

其中有一段代码,其中的数字就是该开发板所支持的频率。可以知道开发板支持996MHZ、792MHz、528MHz、
396MHz 和 198MHz。如果添加对696MHZ的支持,只需要修改部分。

			operating-points = <
				/* kHz	uV */
				996000	1275000
				792000	1225000
				696000  1225000
				528000	1175000
				396000	1025000
				198000	950000
			>;
			fsl,soc-operating-points = <
				/* KHz	uV */
				996000	1175000
				792000	1175000
				696000  1175000
				528000	1175000
				396000	1175000
				198000	1175000
			>;

编译设备树

make dtbs

使能 8 线 EMMC 驱动

Linux 内核驱动里面 EMMC 默认是 4 线模式的。硬件上使用8线制的速度更快,我们还要将emmc驱动修改为8线制的。修改设备树文件imx6ull_dongfang_emmc.dts即可。在文件最后有:

&usdhc2 {
	pinctrl-names = "default";
	pinctrl-0 = <&pinctrl_usdhc2>;
	non-removable;
	status = "okay";
};

将它修改为

&usdhc2 {
   pinctrl-names = "default", "state_100mhz", "state_200mhz";
   pinctrl-0 = <&pinctrl_usdhc2_8bit>;
   pinctrl-1 = <&pinctrl_usdhc2_8bit_100mhz>;
   pinctrl-2 = <&pinctrl_usdhc2_8bit_200mhz>;
   bus-width = <8>;
   non-removable;
   status = "okay";
};

编译设备树make dtbs,使用新的设备树启动即可。

修改网络驱动

修改为自己使用PHY的芯片驱动。

保存修改后的图形化配置文件

我们使用图形化配置后,会在.config文件中添加相应的使能代码。但是如果我们使用make clean或者make distclean命令清理工程的时候,那么.config中的内容就会被删除掉。之前的所有的配置文件内容也就消失。所以我们在配置完图形界面以后经过测试没有问题,就必须要保存一下配置文件。保存配置的方法有两个。

  • 直接另存为.config文件

直接将.config 文件另存为 imx_dongfang_emmc_defconfig,然后其复制到 arch/arm/configs 目录下,替换以前的imx_dongfang_emmc_defconfig。这样以后执行“make imx_dongfang_emmc_defconfig”重新配置Linux 内核的时候就会使用新的配置文件。

  • 通过图形界面保存配置文件

通过键盘的“”键,移动到“< Save >”选项,然后按下回车键,打开文件名输入对话框。输入要保存的文件名,可以带路径,一般是相对路径。我们输入arch/arm/configs/imx_dongfang_emmc_defconfig即可。设置好文件名以后选择下方的“< Ok >”按钮,保存文件并退出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值