东莞网络公司 网站建设,win7电脑做网站主机,百度推广送的公司网站有什么用,重庆招聘一般上什么网站原厂 Linux 内核编译
NXP 提供的 Linux 源码肯定是可以在自己的 I.MX6ULL EVK 开发板上运行下去的#xff0c;所以我们肯定是以 I.MX6ULL EVK 开发板为参考#xff0c;然后将 Linux 内核移植到 I.MX6U-ALPHA 开发板上的。
配置编译 Linux 内核
和uboot一样#xff0c;在编…原厂 Linux 内核编译
NXP 提供的 Linux 源码肯定是可以在自己的 I.MX6ULL EVK 开发板上运行下去的所以我们肯定是以 I.MX6ULL EVK 开发板为参考然后将 Linux 内核移植到 I.MX6U-ALPHA 开发板上的。
配置编译 Linux 内核
和uboot一样在编译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。进入到 Ubuntu 中的 Linux 源码根目录下执行如下命令配置 Linux 内核
在这之前要做好交叉编译器的配置make clean //第一次编译 Linux 内核之前先清理一下
make imx_v7_mfg_defconfig //配置 Linux 内核配置完成以后就可以编译了使用如下命令编译 Linux 内核
make 编译完成 Linux 内核编译完成以后会在 arch/arm/boot 目录下生成 zImage 镜像文件如果使用设备树的话还会在 arch/arm/boot/dts 目录下开发板对应的.dtb(设备树)文件比如 imx6ull-14x14-evk.dtb 就是 NXP 官方的 I.MX6ULL EVK 开发板对应的设备树文件。至此我们得到两个文件 ①、 Linux 内核镜像文件 zImage。 ②、 NXP 官方 I.MX6ULL EVK 开发板对应的设备树文件 imx6ull-14x14-evk.dtb。
原厂内核启动测试
前面我们已经得到了 NXP 官方 I.MX6ULL EVK 开发板对应的 zImage 和 imx6ull-14x14-evk.dtb 这两个文件。这两个文件能不能在正点原子的 I.MX6U-ALPHA EMMC 版开发板上启动呢测试一下不就知道了在测试之前确保 uboot 中的环境变量 bootargs 内容如下
consolettymxc0,115200 root/dev/mmcblk1p2 rootwait rw
将前面编译出来的 zImage 和 imx6ull-14x14-evk.dtb 复制到 Ubuntu 中的 tftp 目录下作者喜欢在win下使用tftp工具因为我们要在 uboot 中使用 tftp 命令将其下载到开发板中。 启动开发板进入 uboot 命令行模式然后输入如下命令将zImage 和 imx6ull-14x14-evk.dtb 下载到开发板中并启动
tftp 80800000 zImage
tftp 83000000 imx6ull-14x14-evk.dtb
bootz 80800000 - 83000000 从图可以看出此时 Linux 内核已经启动了但是此时我们的系统还缺少根文件系统因此系统启动会报错
Linux 内核启动以后是需要根文件系统的根文件系统存在哪里是由 uboot 的 bootargs 环境变 量 指 定 bootargs 会 传 递 给 Linux 内 核 作 为 命 令 行 参 数 。 比 如 上 一 小 节 设 置 root/dev/mmcblk1p2也就是说根文件系统存储在/dev/mmcblk1p2 中也就是 EMMC 的分区 2中。这是因为正点原子的 EMMC 版本开发板出厂的时候已经 EMMC 的分区 2 中烧写好了根文件系统所以设置 root/dev/mmcblk1p2。如果我们不设置根文件系统路径或者说根文件系统路径设置错误的话会出现什么问题这个问题是很常见的我们在实际的工作中开发一个产品这个产品的第一版硬件出来以后我们是没有对应的根文件系统可用的必须要自己做根文件系统。在构建出对应的根文件系统之前 Linux 内核是没有根文件系统可用的就会产生如下错误 在图中最后会有下面这一行
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
也就是提示内核崩溃因为 VFS(虚拟文件系统)不能挂载根文件系统因为根文件系统目录不存在。即使根文件系统目录存在如果根文件系统目录里面是空的依旧会提示内核崩溃。这个就是根文件系统缺失导致的内核崩溃但是内核是启动了的只是根文件系统不存在而已。
移植
在前面我们通过编译 NXP 官方 I.MX6ULL EVK 开发板对应的 Linux 内核发现其可以在正点原子的 EMMC 版本开发板启动所以我们就参考 I.MX6ULL EVK 开发板的设置在 Linux 内核中添加正点原子的 I.MX6U-ALPHA 开发板。
添加config配置文件
将 arch/arm/configs 目 录 下 的 imx_v7_mfg_defconfig 重 新 复 制 一 份 命 名 为imx_alientek_emmc_defconfig
添加dts设备树文件
添加适合正点原子 EMMC 版开发板的设备树文件进入目录 arch/arm/boot/dts 中复制一份 imx6ull-14x14-evk.dts然后将其重命名为 imx6ull-alientek-emmc.dts .dts 是设备树源码文件编译 Linux 的时候会将其编译为.dtb 文件。imx6ull-alientek-emmc.dts创 建 好 以 后 我 们 还 需 要 修 改 文 件 arch/arm/boot/dts/Makefile 找 到 “ dtb- $(CONFIG_SOC_IMX6ULL)”配置项在此配置项中加入“imx6ull-alientek-emmc.dtb” 如下所示
417 imx6ull-14x14-evk.dtb \
418 imx6ull-14x14-evk-btwifi.dtb \
419 imx6ull-14x14-evk-emmc.dtb \
420 imx6ull-14x14-evk-gpmi-weim.dtb \
421 imx6ull-14x14-evk-usb-certi.dtb \
422 imx6ull-alientek-emmc.dtb \
编译测试
经过前面的步骤Linux 内核里面已经添加了正点原子 I.MX6UL-ALIPHAEMMC版开发板了接下接编译测试一下。编译完成以后就会在目录 arch/arm/boot 下生成 zImage 镜像文件。在 arch/arm/boot/dts 目录下生成 imx6ull-alientek-emmc.dtb 文件。将这两个文件拷贝到 tftp 目录下然后重启开发板在uboot 命令模式中使用 tftp 命令下载这两个文件并启动。
启动成功添加新board成功。先使用原厂根文件系统
CPU 主频修改
保证文件系统挂载然后启动系统 进入上图所示的命令行以后输入如下命令查看 cpu 信息
cat /proc/cpuinfo 在图中有 BogoMIPS 这一条此时 BogoMIPS 为 3.00 BogoMIPS 是 Linux 系统中衡量处理器运行速度的一个“尺子”处理器性能越强主频越高 BogoMIPS 值就越大。BogoMIPS 只是粗略的计算 CPU 性能并不十分准确。但是我们可以通过 BogoMIPS 值来大致的判断当前处理器的性能。在图中并没有看到当前 CPU 的工作频率那我们就转变另一种方法查看当前 CPU 的工作频率。进入到目录/sys/bus/cpu/devices/cpu0/cpufreq 中此目录下会有很多文件如图所示 此目录中记录了 CPU 频率等信息这些文件的含义如下 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 在各频率下的运行时间以及变频次数。使用如下命令查看当前 CPU 频率
cat cpuinfo_cur_freq 从图可以看出当前 CPU 频率为 198MHz工作频率很低其他的值如下
cpuinfo_cur_freq 198000
cpuinfo_max_freq 792000
cpuinfo_min_freq 198000
scaling_cur_freq 198000
scaling_max_freq 792000
cat scaling_min_freq 198000
scaling_available_frequencies 198000 396000 528000 792000
cat scaling_governor ondemand
可以看出当前 CPU 支持 198MHz、 396MHz、 528Mhz 和 792MHz 四种频率切换其中调频策略为 ondemand也就是定期检查负载然后根据负载情况调节 CPU 频率。因为当前我们开发板并没有做什么工作因此 CPU 频率降低为 198MHz 以省电。如果开发板做一些高负载的工作比如播放视频等操作那么 CPU 频率就会提升上去。查看 stats 目录下的 time_in_state 文件可以看到 CPU 在各频率下的工作时间命令如下
cat /sys/bus/cpu/devices/cpu0/cpufreq/stats/time_in_state 从图中可以看出 CPU 在 198MHz、 396MHz、 528MHz 和 792MHz 都工作过其中 198MHz 的工作时间最长假如我们想让 CPU 一直工作在 792MHz 那该怎么办很简单配置 Linux 内核将调频策略选择为 performance。或者修改 imx_alientek_emmc_defconfig 文件此文件中有下面几行
41 CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMANDy
42 CONFIG_CPU_FREQ_GOV_POWERSAVEy
43 CONFIG_CPU_FREQ_GOV_USERSPACEy
44 CONFIG_CPU_FREQ_GOV_INTERACTIVEy
第 41 行配置 ondemand 为默认调频策略。 第 42 行使能 powersave 策略。 第 43 行使能 userspace 策略。 第 44 行使能 interactive 策略。 将示例代码中的第 41 行屏蔽掉然后在 44 行后面添加
CONFIG_CPU_FREQ_GOV_ONDEMANDy
或者在menuconfig如下路径进行配置
CPU Power Management
- CPU Frequency scaling
- Default CPUFreq governor 修改完成以后重新编译 Linux 内核编译之前先清理一下工程因为我们重新修改过默认配 置 文 件 了 编 译完成 以 后 使 用 新的 zImage 镜 像 文 件 重新 启动 Linux 。 再 次 查 看 /sys/devices/system/cpu/cpu0/cpufreq/ cpuinfo_cur_freq 文件的值如图所示 使能EMMC 驱动
emmc驱动已经在内核中使能但是使用的4现模式硬件设计的为8线模式。打开文件 imx6ull-alientek-emmc.dts找到如下所示内容
734 usdhc2 {
735 pinctrl-names default;
736 pinctrl-0 pinctrl_usdhc2;
737 non-removable;
738 status okay;
739 };
修改为
734 usdhc2 {
735 pinctrl-names default, state_100mhz, state_200mhz;
736 pinctrl-0 pinctrl_usdhc2_8bit;
737 pinctrl-1 pinctrl_usdhc2_8bit_100mhz;
738 pinctrl-2 pinctrl_usdhc2_8bit_200mhz;
739 bus-width 8;
740 non-removable;
741 status okay;
742 };
修改完成以后保存一下 imx6ull-alientek-emmc.dts然后使用命令“make dtbs”重新编译一下设备树编译完成以后使用新的设备树重启 Linux 系统即可。
修改网络驱动
因为在后面学习 Linux 驱动开发的时候要用到网络调试驱动所以必须要把网络驱动调试好。在讲解 uboot 移植的时候就已经说过了正点原子开发板的网络和 NXP 官方的网络硬件上不同网络 PHY 芯片由 KSZ8081 换为了 LAN8720A两个网络 PHY 芯片的复位 IO 也不同。所以 Linux 内核自带的网络驱动是驱动不起来 I.MX6U-ALPHA 开发板上的网络的需要做修改。
修改PHY的复位以及网络时钟引脚驱动
ENET1 复位引脚 ENET1_RST 连接在 I.M6ULL 的 SNVS_TAMPER7 这个引脚上。 ENET2的复位引脚 ENET2_RST 连接在 I.MX6ULL 的 SNVS_TAMPER8 上。打开设备树文件 imx6ullalientek-emmc.dts找到如下代码
584 pinctrl_spi4: spi4grp {
585 fsl,pins
586 MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10 0x70a1
587 MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x70a1
588 MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x70a1
589 MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x80000000
590 ;
591 };
示例代码中第 588 和 589 行就是初始化 SNVS_TAMPER7 和 SNVS_TAMPER8 这两个引脚的不过看样子好像是作为了 SPI4 的 IO这不是我们想要的所以将 588 和 589 这两行删除掉删除掉以后继续在 imx6ull-alientek-emmc.dts 中找到如下所示代码
屏蔽第129行和133行。
第 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 的什么功能引脚因此将示例代码中的第 129 行和第 133 行处的代码删除掉否则会干扰到网络复位引脚 在 imx6ull-alientek-emmc.dts 里面找到名为“iomuxc_snvs”的节点(就是直接搜索)然后在此节点下添加网络复位引脚信息添加完成以后的“iomuxc_snvs”的节点内容如下 最后还需要修改一下 ENET1 和 ENET2 的网络时钟引脚配置 继续在 imx6ull-alientekemmc.dts 中找到如下所示代码 我们可以看到原先的引脚电器属性值为0x4001b031将他们改为0x4001b009。可以从下图看出来变动的是第3、4、5位 我们找到这个IO端口属性寄存器 查看3-5位的定义 可以看到5-3位是端口驱动能力本次将110改为001降低了端口驱动能力。
修改 fec1 和 fec2 节点的 pinctrl-0 属性
在 imx6ull-alientek-emmc.dts 文件中找到名为“fec1”和“fec2”的这两个节点修改其中的“pinctrl-0”属性值修改以后如下所示
修改 LAN8720A 的 PHY 地址
在 uboot 移植章节中我们说过 ENET1 的 LAN8720A 地址为 0x0 ENET2 的 LAN8720A地址为 0x1。在 imx6ull-alientek-emmc.dts 中找到如下代码
第 177 和 178 行添加了 ENET1 网络复位引脚所使用的 IO 为 GPIO5_IO07低电平有效。复位低电平信号持续时间为 200ms。 第 188 和 189 行 ENET2 网络复位引脚所使用的 IO 为 GPIO5_IO08同样低电平有效持续时间同样为 200ms。 第 198 和 204 行“smsc,disable-energy-detect”表明 PHY 芯片是 SMSC 公司的这样 Linux内核就会找到 SMSC 公司的 PHY 芯片驱动来驱动 LAN8720A。 第 196 行注意“ethernet-phy”后面的数字是 PHY 的地址 ENET1 的 PHY 地址为 0所以“”后面是 0(默认为 2)。 第 199 行 reg 的值也表示 PHY 地址 ENET1 的 PHY 地址为 0所以 reg0。 第 202 行 ENET2 的 PHY 地址为 1因此“”后面为 1。 第 205 行因为 ENET2 的 PHY 地址为 1所以 reg1。 至此 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 中加入如下代码
第 3455~3462 就是新加入的代码如果要在 I.MX6ULL 上使用 LAN8720A 就需要设置ENET1 和 ENET2 的 TX_CLK 引脚复位寄存器的 SION 位为 1。
配置 Linux 内核使能 LAN8720 驱动
图中选择将“Drivers for SMSC PHYs”编译到 Linux 内核中因此“”里面变为了“*”。 LAN8720A 是 SMSC 公司出品的因此勾选这个以后就会编译 LAN8720 驱动配置好以后退出配置界面然后重新编译一下 Linux 内核。
修改 smsc.c 文件
首先需要找到 LAN8720A 的驱动文件 LAN8720A 的驱动文件是 drivers/net/phy/smsc.c在此文件中有个叫做 smsc_phy_reset 的函数看名字都知道这是 SMSC PHY 的复位函数因 此 LAN8720A 肯定也会使用到这个复位函数 修改此函数的内容修改以后的 smsc_phy_reset函数内容如下所示
第 67~72 行获取 FEC1 网卡对应的设备节点。 第 74~79 行获取 FEC2 网卡对应的设备节点。 第 81 行从设备树中获取“phy-reset-duration”属性信息也就是复位时间。 第 85 行从设备树中获取“phy-reset-gpios”属性信息也就是复位 IO。 第 89~92 行设置 PHY 的复位 IO复位 LAN8720A。 第 101~108 行以前的 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
修改好设备树和 Linux 内核以后重新编译一下得到新的 zImage 镜像文件和 imx6ullalientek-emmc.dtb 设备树文件使用网线将 I.MX6U-ALPHA 开发板的两个网口与路由器或者电脑连接起来最后使用新的文件启动 Linux 内核。启动以后使用“ifconfig”命令查看一下当前活动的网卡有哪些结果如图所示 关于 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内核移植成功以后就要开始根文件系统的构建。