1.内核移植的基本内容

内核移植包括 : 裁剪 + 配置 + 适配。

提问:

为什么移植一定包含裁剪?

1.硬件资源有限:嵌入式设备(ARM 开发板、IoT 芯片等)Flash、RAM 很小,原版内核体积太大,根本跑不起来。
2.只保留需要的驱动和功能: 开发板子只有特定的串口、网卡、Flash,不需要显卡、声卡、PCIe 等大量无关驱动。
3.提高启动速度、减少漏洞面:裁剪后内核更小、启动更快、更稳定

内核移植的典型完整流程?

1.获取内核源码: 选择对应平台的默认配置(defconfig)
2.裁剪与配置内核: 去掉不需要的文件系统、驱动、网络协议 ; 开启必要的驱动(UART、MMC、LCD、NAND 等); 配置内存大小、启动参数等 ;修改板级相关代码
3.适配硬件:时钟、引脚、中断、内存映射等
4.编译内核(uImage/zImage/Image)
5.烧录到开发板测试、调试

注意:我们桌面linux一般不需要裁剪,但是嵌入式linux必须裁剪。否则内核太大、功能冗余、无法正常启动。

uboot移植,内核移植,以及文件系统构建三者的关系?

2.内核编译过程

1.首先把内核放入ubantu中,解压

2.解压后,得到下面的内容,我们不需要压缩包,压缩包通过rm删除

3.然后我们需要对内核进行编译,为了方便,我们把内核编译的四个命令放到一个脚本里,这样执行这个脚本就相当于输入了这四个命令,不用每次编译都重新输入命令。

4.正式编译

通过执行脚本进行编译。

过程总结:

下载NXP官方维护的linux内核版本,进行改造,直接使用原有的内核版本修改难度大。因为里面大部分驱动是没有的, 然后进解压,编译,试运行。

知识补充:

脚本命令解析

vi build.sh  //创建名为build的脚本,并进入脚本
chmod +x build.sh  //给予脚本执行权限,一般都是给777,即chmod 777 build.sh
./build.sh  //执行这个脚本,即执行这个脚本的全部命令

脚本内容

#!/bin/bash是一个shell解释器,可以暂且理解为,这个是用来执行脚本的默认工具

内核编译命令解析

视频中的编译命令是这样写的

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   # 手动调整配置(可选)
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j   # 编译

但其实也可以这样写,接下来以下面的版本进行解析

export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
make distclean  // 进行编译文件清除
make imx_v7_defconfig // 使用默认配置文件
make menuconfig  //调出配置界面(可选),不操作,按两个exit可退出
make all -j4 编译

export是脚本中的一个专用命令,是用于设置环境变量的

export ARCH=arm  表示编译目标是arm架构,并不是默认的x86架构

export CROSS_COMPILE=arm-linux-gnueabihf- 表示使用arm-linux-gnueabihf-开头的交叉工具链进行编译

export让后面的环境变量被子进程继承,也就是被每个make继承。

内核默认配置文件一般在哪个文件夹

即make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- linux_v7_defconfig中的linux_v7_defconfig在哪里。

解压内核后,在arch/arm/configs里面,里面文件比较多,可以直接搜索。

编译报错处理(重要)

报错如下

报错分析:

bin/sh : 1 : lozp:not found    //原因
recipe for target 'arch/arm/boot/compressed/piggy.lzo' failed // 结果
.....省略.....
recipe for target 'arch/arn/boot/compressed/vmlinux' failed

注意我们前面在编译脚本的地方提到的。

#!/bin/bash是一个shell解释器,可以暂且理解为,这个是用来执行脚本的默认工具

第一行:

/bin/sh     :执行命令的 shell 程序
1           :shell 正在执行的命令行编号,通常表示第 1 行
lzop        :真正找不到的命令
not found   :系统在 PATH 里没找到 lzop 这个可执行程序

第二行:

这个是make 内核的过程中的一个经典的报错形式。意思是Makefile 里用于生成 XXXX 这个目标的命令执行失败了。值得注意的是recipe for target "路径" failed 这是一个结果性的报错。真的的原因要从上面找。这里发现是 XXX not found , 这是一个缺工具的报错,一般安装工具就可以处理了,这里的处理方法就是。进行工具的安装。执行命令如下。另外,值得注意的是,这一个报错,其实导致了两个报错,我们可以看到,有两个 recipe for target XXX  faild

sudo apt-get install lzop

处理结果:

当安装工具后,执行脚本,报错消失,得到内核镜像文件zImage 以及文件 piggy.lzo

知识补充:

缺XXX报错提示总结:

缺库,缺工具,缺依赖并不是一个概念。前面的 lzop,它更准确地说是 缺工具/缺软件,不是缺库。因为内核编译时要执行 lzop 这个压缩命令来生成压缩镜像,如果系统找不到这个命令,就会报错。所以,缺 lzop 不是缺库,是缺工具。缺 libssl.so 才是缺库。缺 openssl/ssl.h 是缺头文件,通常要装开发

类型缺的是什么典型报错例子
缺工具 / 软件一个可执行命令xxx: command not foundxxx: not foundlzopbcflexbisonmakegcc
缺头文件.h 文件fatal error: xxx.h: No such file or directoryopenssl/ssl.hncurses.h
缺库.so.a 库文件cannot find -lxxxundefined reference to xxxlibssllibzlibncurses

包。

sudo apt-get install XXX 命令解释:

sudo 是以超级用户,也就是root的权限执行命令,因为安装软件需要修改系统级别的目录

apt-get是一个包管理工具,这里记为一个负责软件安装,升级,删除的一个工具

install 在这里就是apt-get的一个子命令,没有别的含义

ubantu如何下载软件的?

ubantu可以连接一个官方的软件源,可以理解为windows的应用商店。我们输入命令后,ubantu上网去这个软件源中找。并且会负责,下载,安装,配置的全部内容,我们可以直接使用。但是,但是,但是,我们是幼配置镜像源的,因为ubantu是默认连接国外服务器的,我们要配置镜像源为国内服务器,这个是安装不上软件的原因/

3.内核镜像与设备树传入开发板

内核和设备树都编译准备好之后,拷贝到tftp文件夹,通过tftp传给开发板。主要操作就是在串口执行tftp命令,进行传输,传输完成后,使用bootz命令进行内核启动。总结一下就是:内核镜像 zImage 和设备树 .dtb 可以通过 TFTP 下载到开发板内存中,然后由 U-Boot 启动。

知识补充:

tftp是什么,怎么用,

TFTP 是 Trivial File Transfer Protocol,简单文件传输协议。在这个场景里,它的作用很单纯:从 Ubuntu 主机的 tftpboot 目录里,把 zImage 和 .dtb 下载到开发板 DDR 内存的指定地址。

并且,这里 tftp 不是把文件永久烧写进 EMMC,而是把文件临时下载到 DDR 里,然后 bootz 从 DDR 启动内核。教程中也是这样设置 bootcmd 的:先用 TFTP 下载 zImage 和设备树,再执行 bootz 启动。

注意两个点:暂时放入ddr,不是永久烧写进EMMC

为什么这里不用nfs传输,看起来一样啊?

为什么这里常用 TFTP,而不是 NFS?核心原因是:此时还在 U-Boot 阶段,只需要下载两个文件,不需要挂载一个完整文件系统。TFTP 适合这种场景:一次性下载单个文件,比如zImage ,以及,dtb。NFS 更适合这种场景:长期挂载一个目录作为根文件系统。

tftp哪里来的?

 U-Boot 自带了 TFTP 客户端命令/功能。只要你烧录运行的 U-Boot 编译进了网络功能和 tftp 命令,就可以在 U-Boot 命令行里使用 tftp。我们需要准备的是咋ubantu上在安装tftp服务端。

但是使用tftp也有一个大前提,首先就是uboot编译的时候打开了网络命令,比如tftp ,ping等。第二个就是,uboot已经适配了网卡驱动,并且后面的网络硬件配置,环境变量配置都正确,才可以正常使用

内核来源?

1.我们学习的是修改NXP内核的的方法,正点原子从NXP买了芯片,然后做了自己的开发板,把自己的开发板添加到NXP提供的内核中去

2.从内核官网,直接下载内核,进行修改,难度是非常之大的。因为会少很多复杂的驱动,这些驱动时半导体公司做的比如NXP

报错处理:

报错显示:

make: *** No rule to make target 'dtbs'.  Stop.

原因:

编译顶层设备树的时候需要在顶层的makefile进行编译。Linux 内核源码里有很多个 Makefile,但编译时通常要从“内核源码顶层目录”的 Makefile 入口开始。所以后面回到顶层目录,重新执行设备树编译就OK了

知识补充:

Linux 内核编译的时候,顶层 Makefile 起什么作用?

Linux 内核源码里有很多 Makefile,但真正的编译入口是源码根目录下的顶层 Makefile。它负责确定架构、交叉编译器、编译目标、配置文件,并通过 Kbuild 体系递归调用各级子目录的 Makefile,最终生成 vmlinux、zImage、.dtb、.ko 等产物。

我们配置ARCH 和 CROSS_COMPILE是为了什么?

嵌入式 Linux 是交叉编译,Ubuntu 主机是 x86,但目标板是 ARM,所以要告诉 Makefile:

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

ARCH:指定目标架构,比如 arm。CROSS_COMPILE:指定交叉编译工具链前缀

defconfig 和 .configs是什么文件?

xxx_defconfig 是默认配置模板;
.config 是当前真正生效的内核配置文件;
make menuconfig 修改的是 .config;
最终编译内核时,Kbuild 依据 .config 决定哪些模块编译进内核,哪些编译成模块,哪些不编译。

总结一下就是.configs是真正在用的文件。

Kconfig 和 Makefile 的区别?

Kconfig:负责提供配置选项,比如 menuconfig 里看到的菜单;
.config:保存用户最终选择;
Makefile/Kbuild:根据 .config 决定具体编译哪些文件。

比如某个驱动是这样写的:

obj-$(CONFIG_GPIO_LED) += gpio_led.o

如果 .config 里有:

CONFIG_GPIO_LED=y    //那它会编译进内核。
CONFIG_GPIO_LED=m    //那它会编译成 .ko 模块。
//如果没有配置,就不编译。

built-in.o 和 vmlinuxs是什么?

各个目录下的 .o 文件会先被打包/链接成 built-in.o;
然后多个 built-in.o 再参与链接,最终生成 vmlinux;
vmlinux 是未压缩的内核 ELF 文件;
zImage 是压缩后的 ARM Linux 内核镜像。

设备树编译如何编译?

设备树不是直接手动编译某个 dts 文件,而是通过内核顶层 Makefile 的 make dtbs 目标触发 DTC 编译。

linux内核的启动流程?

U-Boot → zImage 解压 → stext → __mmap_switched → start_kernel → rest_init → kernel_init → 挂载根文件系统 → 执行 init

U-Boot 如何到内核?

1. 把 zImage 加载到 DDR
2. 把 dtb 加载到 DDR
3. 设置 bootargs
4. 执行 bootz
5. 跳转到内核入口

4.把自己的开发板添加到内核

这部分本质上是在 NXP 官方 Linux 内核源码里,给我们自己的开发板,也就是给正点原子 I.MX6U-ALPHA EMMC 版开发板建立一套“自己的板级入口”。这一步并不是从零写内核,而是基于 NXP 官方 I.MX6ULL EVK 开发板做拷贝、改名、适配。

而具体要做的可以总结为以下三个内容:

1. 添加自己的 defconfig
2. 添加自己的 dts 设备树
3. 修改 dts 目录下的 Makefile,让设备树能被编译成 dtb

1.首先实验一下NXP官方的内核和设备树,编译后,使用bootz命令,让uboot启动内核和设备树是否会报错。

这里看到没有问题,下面唯一的一个报错,其原因是没有根文件系统。如果这里不能启动,事情就可能变得麻烦了,一般都是可以启动的。

2.添加开发板默认配置文件

也就是deconfig文件,这里再复习一下,deconfig文件,是默认配置文件,而.config文件是真正使用的配置文件,我们使用的meunconfig修改的 ,就是这个.config文件。以上两个文件如何得到呢,其实和uboot那部分一样,直接复制就可以了。

首先复制配置文件deconfig

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

cd arch/arm/configs
cp imx_v7_mfg_defconfig imx_alientek_emmc_defconfig

然后打开这个配置文件,把"CONFIG_ARCH_MULTI_V6=y"这一行变为"#CONFIG_ARCH_MULTI_V6=y"也就是注释掉,因为imx6ull是armv7架构的,v6架构的我们不要。

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

然后,复制设备树文件dts:

添加适合我们自己板子的设备树文件,这里添加正点原子 EMMC 版开发板的设备树文件为例子,首先,进入目录 arch/arm/boot/dts 中,复制一 份 imx6ull-14x14-evk.dts,然后将其重命名为 imx6ull-alientek-emmc.dts。命令如下:dts 是设备树源码文件,编译 Linux 的时候会将其编译为.dtb 文件。
cd arch/arm/boot/dts
cp imx6ull-14x14-evk.dts imx6ull-alientek-emmc.dts

这里复制哪个设备树文件其实有讲究,主要是按照最相似的原子去复制,imax6ull是板子的主控芯片型号,14x14是芯片封装尺寸的意思。这个好理解,一般尺寸大,引脚多。

3.修改顶层makefile文件

imx6ull-alientek-emmc. 和 dts 创建好以后我们还需要修改文件 arch/arm/boot/dts/Makefile。找到“dtb-$(CONFIG_SOC_IMX6ULL)”配置项,在此配置项中加入“imx6ull-alientek-emmc.dtb”。不然编译的时候是不会编译刚添加的这个设备树的。

4.写一个脚本,编译一下

我们自己写一个脚本进行编译,这里也不是自己手写,而是找到刚才我们复制的哪个deconfig文件,稍微修改一下他的编译脚本。

编译脚本如下imx6ull_alientek_emmc.sh(这个名字可以自己修改,是复制来的)的内容如下

#!/bin/sh
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_alientek_emmc_defconfig //主要改这里,使用我们自己的配置文件,dts文件已经通过修改顶层makefile告知内核了
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16//这里调用顶层makefile
含义如下:
第 2 行,清理工程。
第 3 行,使用默认配置文件 imx_alientek_emmc_defconfig 来配置 Linux 内核。
第 4 行,打开 Linux 的图形配置界面,如果不需要每次都打开图形配置界面可以删除此行。
第 5 行,编译 Linux。 //使用顶层makefilej进行编译
如下显示的话,就是编译成功:
没有报错就是成功了,失败的话,中间会有error
5.让uboot再次加载启动内核,进行验证
主要过程根前面的一次内核编译一样,通过tftp下载zImage和dtb到DDR,然后通过bootz命令启动内核。

提问

1.make imx_alientek_emmc_defconfig生成什么文件?

它不是在编译 zImage,也不是在生成 .dtb,而是告诉内核构建系统:我要按照 imx_alientek_emmc_defconfig 这份默认配置,生成当前内核要使用的 .config 文件。所以是生成deconfig文件

2..config 决定什么?

.config 里面保存了大量配置项,比如:

CONFIG_EXT4_FS=y
CONFIG_NET=y
CONFIG_MMC=y
CONFIG_USB_SUPPORT=y
CONFIG_GPIO_SYSFS=y

它决定:

哪些功能编进内核
哪些功能编成模块
哪些功能不编译
使用哪个 CPU 架构
打开哪些驱动
支持哪些文件系统
支持哪些网络功能

3. make  deconfig ,make  menuconfig ,make -j16 三者关系

defconfig:菜单模板
make xxx_defconfig:按这个菜单生成今天的点菜单 .config
make menuconfig:手动微调今天的点菜单
make -j16:厨师真正开始做菜
zImage / dtb / ko:最后做出来的菜

4.如何使用的?

通过我们写一个编译脚本,然后make这个脚背,进行使用。里面使用了deconfig文件,也使用了顶层的makefile,也就是是我们前面的第四步

5.CPU主频和网络驱动修改:

虽然前面内核和uboot都已经做出过调整,但这还不够。因为从 NXP 官方 EVK 板复制过来的配置,和我们自己板子的硬件并不完全一致,所以 37.4 要继续修改 CPU 主频、EMMC、网络驱动。

这部分可以理解为,在前面的内容中, 已经让内核“有了自己的板子入口”,这部分是继续把板子的关键硬件参数调正确。以确保正常运行。

需要注意的是: 在进行这部分修改之前,需要先进行根文件系统的移植

1.CPU调频策略修改

这个比较简单,直接通过menuconfig就可以,选则不同的调频策略就OK。但是需要注意的一点menuconfig修改的是当前的配置文件.config。不会修改板级配置文件deconfig。

这个修改是为了让内核知道cpu可以跑哪些频率。CPU 主频不是随便写一个数字就行。Linux 里有一个 CPUFreq 调频框架,它会根据设备树和内核配置决定 CPU 可以在哪些频率之间切换。我们修改的内容主要包括两个部分:1.CPU可以跑哪些频率。2.CPU的调频策略

cpu主频修改 = 修改配置文件 + 修改设备树文件。

查看CPU信息

/sys/bus/cpu/devices/cpu0/cpufreq

打印主频信息,这里可以看到CPU目前的运行频率是 792Mhz

cat cpuinfo_cur_freq 

以下是其他文件代表的意义。

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(调频)类型。

使用meauconfig修改调频策略,需要注意的是所有调频策略是默认都使能的,但是哪个是默认的调频策略是需要设置的,一般推荐ondemand。

2.增加CPU的支持频率

修改一下设备树文件 arch/arm/boot/dts/imx6ull.dtsi 即可。在这两个位都添加频率就行,然后重新编译内核。

3.EMMC 驱动修改

修改CPU主频,需要先装好根文件系统。而根文件系统后面往往就在 EMMC 上。而EMMC 修改 = 修改 usdhc2 设备树节点。在下面的修改中,核心板 EMMC 工作电压是 3.3V,所以禁止切换到1.8伏

&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>;   //EMMC 使用 8 位数据线
    non-removable;  //用板载 EMMC ,不用SD卡
    no-1-8-v;  //禁止切换到1.8伏
    status = "okay";  //启用这个控制器
};

4.网络驱动修改:

网络这部分最重要。因为后面做驱动开发时,经常要用:比如TFTP 下载 zImage/dtb, NFS 挂载根文件系统  , scp/ftp 传驱动和应用  ,ping 测试网络、如果 Linux 网卡驱动没调好,后面的实验会很难受。

1.硬件结构

一个完整的网口由以下四个部分组成

IMX6ULL 内部 MAC → RMII 接口 → 外部 PHY → 网络变压器/RJ45,芯片手册中,也表明了MAC的位置如下

所以 Linux 网络要起来,至少要满足这几部分都对:所以这部分不是“写一个新的网卡驱动”,而是 设备树 + 少量 FEC 驱动源码 + menuconfig 配置 三者一起改。

1. MAC 驱动要对
   对应 Linux 里的 freescale/fec_main.c

2. PHY 地址要对
   通过 MDIO 总线访问 PHY,地址错了就找不到 PHY

3. PHY 复位脚要对
   复位 GPIO 不对,PHY 可能一直没正常启动

4. 引脚复用和电气属性要对
   RMII 数据线、时钟线、复位线都要正确配置

5. PHY 驱动要使能
   比如 LAN8720A 需要 SMSC PHY 驱动

2.为什么需要修改

当然是硬件资源不同+ 硬件结构不同。更具体的来说就是:

1. PHY 芯片型号不同
2. PHY 地址不同
3. PHY 复位 GPIO 不同
4. ENET 时钟引脚配置不同
5. 底板版本不同,网络方案也不同

3.主要改哪些文件?

1.描述板子的网络硬件:PHY 地址、复位 GPIO

2.NXP/Freescale FEC 网卡 MAC 驱动源码。

3.使能对应 PHY 驱动

arch/arm/boot/dts/imx6ull-alientek-emmc.dts
drivers/net/ethernet/freescale/fec_main.c
.config / imx_alientek_emmc_defconfig

4.修改复位引脚以及网络时钟引脚驱动

这个部分本质上是修改外部 PHY 芯片的板级适配。对于IMAX6ULL,ENET1 的复位脚 ENET1_RST 接到 I.MX6ULL 的 SNVS_TAMPER7,ENET2 的复位脚 ENET2_RST 接到 SNVS_TAMPER8。

第一点:根据手册

MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07
MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08

那么这两个引脚复用为GPIO功能后,就是GPIO5_IO07以及GPIO5_IO08。

第二点:SNVS_TAMPER7复用为GPIO给PHY用之前,需要先从原来的工作位置释放出来也就是从SPI4释放出来。所以在设备树中,找到spi4的节点,给他频闭掉

第三点:前面完成了引脚释放,这里要完成,引脚的重新管理。

GPIO5_IO07给ENET1

GPIO5_IO08给ENET2

5.设备树节点修改

这里主要修改的是,设备树对网卡的描述。这里的描述改成imx6ull的网卡。其中fec1 对应 ENET1,fec2 对应 ENET2

&fec1 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet1
                 &pinctrl_enet1_reset>;
    phy-mode = "rmii";
    phy-handle = <&ethphy0>;
    phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>;
    phy-reset-duration = <200>;
    status = "okay";
};

&fec2 {
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_enet2
                 &pinctrl_enet2_reset>;
    phy-mode = "rmii";
    phy-handle = <&ethphy1>;
    phy-reset-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
    phy-reset-duration = <200>;
    status = "okay";

    mdio {
        #address-cells = <1>;
        #size-cells = <0>;

        ethphy0: ethernet-phy@0 {
            compatible = "ethernet-phy-ieee802.3-c22";
            reg = <0>;
        };

        ethphy1: ethernet-phy@1 {
            compatible = "ethernet-phy-ieee802.3-c22";
            reg = <1>;
        };
    };
};

各个部分代表的意思,这里主要修改的就是pinctrl-0。这部分是硬件中,引脚使用相关的描述。

pinctrl-0
    指定 ENET 使用哪些引脚配置。

phy-mode = "rmii"
    表示 MAC 和 PHY 之间用 RMII 接口。

phy-handle
    指向具体 PHY 芯片节点。

phy-reset-gpios
    指定 PHY 的复位 GPIO。

phy-reset-duration
    指定复位持续时间,文档中常用 200ms。

mdio
    描述挂在 MDIO 总线上的 PHY。

reg
    表示 PHY 地址。

5.PHY 地址修改

MAC 通过 MDIO 总线访问 PHY。MDIO 总线上可以挂多个 PHY,每个 PHY 有自己的地址。原来的地址是NXP官方自己的,这里我们改成我们板子上的PHY地址,注意,PHY已经在封装的芯片外部了,不是芯片内部。从1和2改成0和1

6.修改驱动源码

主要是进行寄存器的初始值设置

提问:

修改PHY地址的重要性?

PHY 地址写错,会导致Linux FEC 驱动找不到 PHY,进而导致eth0/eth1 起不来,板子的所有网络功能相关的命令都无法使用,比如ping ,等等

PHY复位修改重要性?

PHY 芯片上电后,需要复位脚按正确时序释放,否则 PHY 可能不会正常工作。

修改设备树,修改驱动源码,修改meauconfig的原因?

设备树描述硬件,驱动源码处理特殊时序/寄存器,menuconfig 使能对应驱动

总结:

内核移植流程

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐