嵌入式Linux系统开发笔记(十一)

Linux内核移植

下载NXP官方维护的linux-imx-rel_imx_4.1.15_2.1.0_ga版本

git clone git://source.codeaurora.org/external/imx/linux-imx.git --single-branch  rel_imx_4.1.15_2.1.0_ga

如果下载速度过慢,也可以从以下国内的gitee仓库下载

git clone https://gitee.com/SudekiMing/linux-imx-rel_imx_4.1.15_2.1.0_ga.git
2.1 编译NXP 官方开发板 Linux 内核

在编译 Linux 内核之前要先配置 Linux 内核。每个板子都有其对应的默认配 置 文 件 , 这 些 默 认 配 置 文 件 保 存 在 arch/arm/configs 目 录 中 。

imx_v7_defconfig 和imx_v7_mfg_defconfig 都可作为 I.MX6ULL EVK 开发板所使用的默认配置文件。但是这里建议使用 imx_v7_mfg_defconfig 这个默认配置文件,首先此配置文件默认支持 I.MX6UL 这款芯片,而且重要的一点就是此文件编译出来的 zImage 可以通过 NXP 官方提供的 MfgTool 工具烧写!!imx_v7_mfg_defconfig 中的“mfg”的意思就是 MfgTool。

# 清除工程
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
# 配置工程
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_defconfig
# 打开图形配置界面,对 Linux 进行配置
# make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
# 编译
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j4

修改顶层 Makefile,直接在顶层 Makefile 文件里面定义 ARCH 和 CROSS_COMPILE 这两个的变量值为 arm 和 arm-linux-gnueabihf-

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xm3qHhvr-1675179780820)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-2.1-1-Linux指定ARCH和CROSS_COMPILE.png)]

这样在编译的时候就不用输入很长的命令,修改后即可使用下面的指令进行编译了

# 清除工程
make distclean
# 配置工程
make imx_v7_defconfig
# 打开图形配置界面,对 Linux 进行配置
# make menuconfig
# 编译
make -j4

Linux 内核编译完成以后会在 arch/arm/boot 目录下生成 zImage 镜像文件,如果使用设备树的话还会在 arch/arm/boot/dts 目录下开发板对应的.dtb(设备树)文件。

NXP 官方的 I.MX6ULL EVK 开发板对应的设备树文件如下:

①、 Linux 内核镜像文件: zImage。
②、 NXP 官方 I.MX6ULL EVK 开发板对应的设备树文件: imx6ull-14x14-evk.dtb。

2.2 在 Linux 中添加自己的开发板

我们参考 I.MX6ULL EVK 开发板的设置,在 Linux 内核中添加正点原子的 I.MX6U-ALPHA 开发板。

2.2.1 添加开发板默认配置文件

将 arch/arm/configs 目 录 下 的 imx_v7_mfg_defconfig 重 新 复 制 一 份 , 命 名 为imx_atk_mfg_defconfig,命令如下:

cd arch/arm/configs
cp imx_v7_mfg_defconfig imx_atk_mfg_defconfig

打开 imx_atk_mfg_defconfig文件,找到“CONFIG_ARCH_MULTI_V6=y”这一行,将其屏蔽掉

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x8pfO7DX-1675179780821)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-2.2.1-1-Linux去除v6配置防止驱动加载失败.png)]

因为 I.MX6ULL 是 ARMV7 架构的,因此要屏蔽掉 V6 相关选项,否则后面做驱动实验的时候可能会遇到驱动模块无法加载的情况。

以后就可以使用如下命令来配置正点原子 EMMC 版开发板对应的 Linux 内核了:

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

添加适合正点原子 EMMC 版开发板的设备树文件,进入目录 arch/arm/boot/dts 中,复制一份 imx6ull-14x14-evk.dts,然后将其重命名为 imx6ull-14x14-evk.dts,命令如下:

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8DxUnpXc-1675179780822)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-2.2.2-1-Linux添加设备树文件.png)]

这样编译 Linux 的时候就可以从 imx6ull-14x14-atk.dts 编译出 imx6ull-14x14-atk.dtb 文件了。

2.2.3 CPU 主频和网络驱动修改

正点原子 I.MX6U-ALPHA 开发板所使用的 I.MX6ULL 芯片主频都是 792MHz 的,也就是NXP 官方宣传的 800MHz 版本。

查看 cpu 信息命令

# 查看cpu信息
cat /proc/cpuinfo

# 查看详细的cpu信息
cd /sys/bus/cpu/devices/cpu0/cpufreq
# 查看cpu当前的工作频率
cat cpuinfo_cur_freq
# 查看CPU 在各频率下的工作时间
cat /sys/bus/cpu/devices/cpu0/cpufreq/stats/time_in_state
# 查看cpu调频策略
cat scaling_governor

假如我们想让 CPU 一直工作在 792MHz 那该怎么办?很简单,配置 Linux 内核,将调频策略选择为 performance。

通过图形化界面配置 Linux 内核的 CPU 调频策略,输入“ make menuconfig”打开 Linux 内核的图形化配置界面,进入如下路径:

CPU Power Management
	-> CPU Frequency scaling
		-> Default CPUFreq governor

打开默认调频策略选择界面,选择“performance” ,选择以后退出图形化配置界面,然后编译 Linux内核即可。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aTxxIqua-1675179780822)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-2.2.3-1-Linux修改CPU主频.png)]

我们学习的时候为了高性能,大家可以使用 performance 模式。但是在以后的实际产品开发中,从省电的角度考虑,建议大家使用 ondemand 模式,一来可以省电,二来可以减少发热。

2.2.4 修改EMMC驱动
  • 使能 8 线 EMMC 驱动

正点原子 EMMC 版本核心板上的 EMMC 采用的 8 位数据线。Linux 内核驱动里面 EMMC 默认是 4 线模式的, 4 线模式肯定没有 8 线模式的速度快,所以我们将 EMMC 的驱动修改为 8 线模式。修改方法很简单,直接修改设备树即可,打开文件 imx6ull-14x14-atk.dts,修改如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x1V2siLs-1675583644360)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-2.2.4-1-Linux修改EMMC驱动.png)]

  • 关闭 EMMC 1.8V 供电选项

EMMC 工作电压是 3.3V 的,因此我们要在示例代码中的 usdhc2 设备树节点中添加“no-1-8-v” 选项,也就是关闭 1.8V 这个功能选项。 防止内核在运行的时候用 1.8V 去驱动 EMMC,导致 EMMC 驱动出现问题。

修改完成以后保存一下 imx6ull-14x14-atk.dts,然后使用命令 make dtbs 重新编译一下设备树,编译完成以后使用新的设备树重启 Linux 系统即可。

2.2.5 网络驱动修改

注意!正点原子I.MX6U-ALPHA开发板V2.4版本以前的底板使用的网络PHY为LAN8720,V2.4 及其以后的版本使用的网络 PHY 为 SR8201F,而且网络 PHY 地址有改变,大家一定要看准自己所使用的底板版本号!(我的底板版本为V1.7)

正点原子开发板的网络和 NXP 官方的网络硬件上不同,网络 PHY 芯片由 KSZ8081 换为了 LAN8720A,两个网络 PHY 芯片的复位 IO 也不同。所以 Linux 内核自带的网络驱动是驱动不起来 I.MX6U-ALPHA 开发板上的网络的,需要做修改。

  • 修改 LAN8720 的复位以及网络时钟引脚驱动

ENET1 复位引脚 ENET1_RST 连接在 I.M6ULL 的 SNVS_TAMPER7 这个引脚上。 ENET2的复位引脚 ENET2_RST 连接在 I.MX6ULL 的 SNVS_TAMPER8 上。打开设备树文件 imx6ull-14x14-atk.dts

第 129 行,设置 GPIO5_IO08 为 SPI4 的一个功能引脚 ,而 GPIO5_IO08 就是 SNVS_TAMPER8 的 GPIO 功能引脚。第 133 行,设置 GPIO5_IO07 作为 SPI4 的片选引脚,而 GPIO5_IO07 就是 SNVS_TAMPER7的 GPIO 功能引脚。

现在我们需要 GPIO5_IO07 和 GPIO5_IO08 分别作为 ENET1 和 ENET2 的复位引脚,而不是 SPI4 的什么功能引脚,因此将下面两行代码删除掉!! 否则会干扰到网络复位引脚! 修改如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6Hj54IcE-1675583644361)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-2.3.5-1-Linux修改复位以及网络时钟引脚驱动.png)]

在 imx6ull-14x14-atk.dts里面找到名为“iomuxc_snvs”的节点(可以直接搜索),然后在此节点下添加网络复位引脚信息,添加完成以后的“iomuxc_snvs”的节点内容如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H1EaZTvr-1675583644361)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-2.3.5-2-Linux修改复位以及网络时钟引脚驱动.png)]

最后还需要修改一下 ENET1 和 ENET2 的网络时钟引脚配置, 继续在 imx6ull-14x14-atk.dts 中找到如下所示代码, 修改ENET1 和 ENET2 的网络时钟引脚配置信息,将这两个引脚的电气属性值改为 0x4001b009,原来默认值为 0x4001b031。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KYyAKUw6-1675583644362)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-2.3.5-3-Linux修改复位以及网络时钟引脚驱动.png)]

  • 修改 fec1 和 fec2 节点的 pinctrl-0 属性

imx6ull-14x14-atk.dts 文件中找到名为“fec1”和“fec2”的这两个节点,修改其中的“pinctrl-0”属性值;

  • 修改 LAN8720A 的 PHY 地址

ENET1 的 LAN8720A 地址为 0x0, ENET2 的 LAN8720A地址为 0x1。在imx6ull-14x14-atk.dts 中修改如下代码:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9OByildG-1675583644362)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-2.3.5-4-Linux修改复位以及网络时钟引脚驱动.png)]

解析:

第 175 和 176 行,添加了 ENET1 网络复位引脚所使用的 IO 为 GPIO5_IO07,低电平有效。复位低电平信号持续时间为 200ms。
第 186 和 187 行, ENET2 网络复位引脚所使用的 IO 为 GPIO5_IO08,同样低电平有效,持续时间同样为 200ms。
第 196 和 202 行,“smsc,disable-energy-detect”表明 PHY 芯片是 SMSC 公司的,这样 Linux内核就会找到 SMSC 公司的 PHY 芯片驱动来驱动 LAN8720A。
第 194 行,注意“ethernet-phy@”后面的数字是 PHY 的地址, ENET1 的 PHY 地址为 0,所以“@”后面是 0(默认为 2)。
第 197 行, reg 的值也表示 PHY 地址, ENET1 的 PHY 地址为 0,所以 reg=0。
第 200 行, ENET2 的 PHY 地址为 1,因此“@”后面为 1。
第 203 行,因为 ENET2 的 PHY 地址为 1,所以 reg=1。
至此, LAN8720A 的 PHY 地址就改好了,保存一下 imx6ull-alientek-emmc.dts 文件。然后
使用“make dtbs”命令重新编译一下设备树。

  • 修改 fec_main.c 文件

要 在 I.MX6ULL 上 使 用 LAN8720A , 需 要 修 改 一 下 Linux 内 核 源 码 , 打 开drivers/net/ethernet/freescale/fec_main.c,找到函数 fec_probe,在 fec_probe 中加入如下代码:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bRpaRYNC-1675583644362)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-2.3.5-5-Linux修改复位以及网络时钟引脚驱动.png)]

如果要在 I.MX6ULL 上使用 LAN8720A 就需要设置ENET1 和 ENET2 的 TX_CLK 引脚复位寄存器的 SION 位为 1。

  • 配置 Linux 内核,使能 LAN8720 驱动

输入命令 make menuconfig,打开图形化配置界面,选择使能 LAN8720A 的驱动,路径如下:

-> Device Drivers
	-> Network device support
		-> PHY Device support and infrastructure
			-> Drivers for SMSC PHYs

选择将“Drivers for SMSC PHYs”编译到 Linux 内核中,LAN8720A 是 SMSC 公司出品的,因此勾选这个以后就会编译 LAN8720 驱动,配
置好以后退出配置界面。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v8U1svRR-1675583644363)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-2.3.5-6-Linux使能LAN8720A网络驱动配置.png)]

我们在配置完图形界面以后经过测试没有问题,就必须要保存一下配置文件。我们可以输入下面的指令:

# 保存修改后的图形化配置,将在顶层目录下生成defconfig文件
make savedefconfig

cp defconfig imx_atk_mfg_defconfig
  • 修改 smsc.c 文件

测试 NFS 挂载文件系统的时候发现文件系统挂载成功率很低 ,老是提示 NFS 服务器找不到。

网络驱动分两部分:内部 MAC+外部 PHY,内部 MAC 驱动是由 NXP 提供的,一般不会出问题,所以只有可能是外部 PHY,也就是
LAN8720A 的驱动可能出问题了。

要设置 LAN8720A 的 BMCR(寄存器地址为 0)寄存器 bit15 为 1,在 Linux 中需要对 LAN8720A 进行一次软复位。

首先需要找到 LAN8720A 的驱动文件, LAN8720A 的驱动文件是 drivers/net/phy/smsc.c,在此文件中有个叫做 smsc_phy_reset 的函数,这是 SMSC PHY 的复位函数,因此, LAN8720A 肯定也会使用到这个复位函数, 修改此函数的内容,修改以后的 smsc_phy_reset函数内容如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jO3qE0Oa-1675583644363)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-2.3.5-7-Linux增加LAN8720A软复位.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h16puLZN-1675583644363)(..\Linux驱动开发记录\Linux驱动开发记录图库\九-2.3.5-8-Linux增加LAN8720A软复位.png)]

解析:

第 68~73 行,获取 FEC1 网卡对应的设备节点。
第 75~80 行,获取 FEC2 网卡对应的设备节点。
第 82 行,从设备树中获取“phy-reset-duration”属性信息,也就是复位时间。
第 86 行,从设备树中获取“phy-reset-gpios”属性信息,也就是复位 IO。
第 29~32 行,设置 PHY 的复位 IO,复位 LAN8720A。
第 102~109 行,之前的 smsc_phy_reset 函数会判断 LAN8720 是否处于 Powerdown 模式,只有处于 Powerdown 模式的时候才会软复位 LAN8720。这里我们将软复位代码移出来,这样每次调用 smsc_phy_reset 函数 LAN8720A 都会被软复位。
最后我们还需要在 drivers/net/phy/smsc.c 文件中添加两个头文件,因为修改后的smsc_phy_reset 函数用到了 gpio_direction_output 和 gpio_set_value 这两个函数,需要添加的头文件如下所示:

#include <linux/of_gpio.h>
#include <linux/io.h>
2.3 关于 Linux 内核简单总结一下移植步骤

①、在 Linux 内核中查找可以参考的板子,一般都是半导体厂商自己做的开发板。
②、编译出参考板子对应的 zImage 和.dtb 文件。
③、使用参考板子的 zImage 文件和.dtb 文件在我们所使用的板子上启动 Linux 内核,看能否启动。
④、如果能启动的话就万事大吉,如果不能启动那就悲剧了,需要调试 Linux 内核。不过一般都会参考半导体官方的开发板设计自己的硬件,所以大部分情况下都会启动起来。启动Linux 内核用到的外设不多,一般就 DRAM(Uboot 都初始化好的)和串口。作为终端使用的串口一般都会参考半导体厂商的 Demo 板。
⑤、修改相应的驱动,像 NAND Flash、 EMMC、 SD 卡等驱动官方的 Linux 内核都是已经提供好了,基本不会出问题。重点是网络驱动,因为 Linux 驱动开发一般都要通过网络调试代码,所以一定要确保网络驱动工作正常。如果是处理器内部 MAC+外部 PHY 这种网络方案的话,一般网络驱动都很好处理,因为在 Linux 内核中是有外部 PHY 通用驱动的。只要设置好复位引脚、 PHY 地址信息基本上都可以驱动起来。
⑥、 Linux 内核启动以后需要根文件系统,如果没有根文件系统的话肯定会崩溃,所以确定 Linux内核移植成功以后就要开始根文件系统的构建。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值