新建名为mx6ull_lux_emmc.sh的shell脚本
#!/bin/sh
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- disclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_v7_mfg_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16
给予权限
chmod 777 mx6ull_lux_emmc.sh
运行脚本
错误提示“ recipe for target ‘arch/arm/boot/compressed/piggy.lzo’failed”
解决方案:安装lozp库
sudo apt-get insatll lzop
arch文件夹 与架构相关的文件
arch/arm/configs中是不同平台的默认配置文件:xxx_defconfig,也就是编译脚本中的imx_v7_defconfig
arch/arm/boot/dts中是对应平台的设备树文件
arch/arm/boot文件夹中会保存编译生成的镜像文件zImage
block文件夹中是块设备目录
.config文件中保存着Linux最终的配置信息,根据此配置信息来编译对应的模块
{
"search.exclude": {
"**/node_modules": true,
"**/bower_components": true,
"**/*.o":true,
"**/*.su":true,
"**/*.cmd" :true,
"Documentation":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-1*":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/imx6u11-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,
/*屏蔽不用的架构相关的文件*/
"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-1*":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/imx6u11-9x9*":true,
"arch/arm/boot/dts/imx6ull-14x14-ddr*":true,
}
}
编译完成之后,首先修改顶层Makefile中的ARCH 和 CROSS_COMPILE
将编译生成的镜像文件zImage和生成的设备树文件imx6ull-14x14-evk.dtb文件放入TFTP文件夹中,在uboot中将其下载到开发板中
cp arch/arm/boot/zImage /home/zuozhongkai/linux/tftpboot/ -f
cp arch/arm/boot/dts/imx6ull-14x14-evk.dtb /home/zuozhongkai/linux/tftpboot/ -f
tftp 80800000 zImage
tftp 83000000 imx6ull-14x14-evk.dtb
bootz 80800000 – 83000000
会提示根文件系统未指定导致内核崩溃
拷贝arch/arm/configs中的imx_v7_mfg_defconfig为imx_lux_emmc_defconfig
拷贝arch/arm/boot/dts/中的imx6ull-14x14-evk.dts为imx6ull-lux-emmc.dts
在arch/arm/boot/dts中找到Makefile文件,在其中找到dtb-$(CONFIG_SOC_IMX6ULL),在其中添加imx6ull-lux-emmc.dtb,这样在进行编译的时候就会将imx6ull-lux-emmc.dts文件编译成imx6ull-lux-emmc.dtb 文件
重写编译脚本,因为要用自己复制为编译文档编译
#!/bin/sh
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- disclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- imx_lux_emmc_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16
重新启动内核,用新编译的镜像文件和设备树文件
在设备树中找到lcdif结点
&lcdif {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_lcdif_dat
&pinctrl_lcdif_ctrl>;
display = <&display0>;
status = "okay";
display0: display {
bits-per-pixel = <24>;
bus-width = <24>;
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <31000000>;
hactive = <800>;
vactive = <480>;
hfront-porch = <40>;
hback-porch = <88>;
hsync-len = <48>;
vback-porch = <32>;
vfront-porch = <13>;
vsync-len = <3>;
hsync-active = <0>;
vsync-active = <0>;
de-active = <1>;
pixelclk-active = <0>;
};
};
};
};
主频不修改,则主频为198000
使能8线EMMC
修改设备树代码
&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";
};
重新编译设备树,重启
修改复位引脚驱动
修改PHY地址
操作复位引脚,低电平有效,持续26ms
smsc,disable-energy-detect”表明 PHY 芯片是 SMSC 公司的,这样 Linux 内核就会找到 SMSC 公司的 PHY 芯片驱动来驱动 LAN8720A
ENET1 的 PHY 地址为 0,所以“@”后面是 0(默认为 2)
reg 的值也表示 PHY 地址, ENET1 的 PHY 地址为 0,所以 reg=0
&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1>;
phy-mode = "rmii";
phy-handle = <ðphy0>;
phy-reset-gpios = <&gpio5 7 GPIO_ACTIVE_LOW>;
phy-reset-duration = <26>;
status = "okay";
};
&fec2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet2>;
phy-mode = "rmii";
phy-handle = <ðphy1>;
phy-reset-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
phy-reset-duration = <26>;
status = "okay";
mdio {
#address-cells = <1>;
#size-cells = <0>;
ethphy0: ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c22";
smsc,disable-energy-detect;
reg = <0>;
};
ethphy1: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
smsc,disable-energy-detect;
reg = <1>;
};
};
};
修改fec_main.c
如果要在 I.MX6ULL 上使用 LAN8720A 就需要设置ENET1 和 ENET2 的 TX_CLK 引脚复位寄存器的 SION 位为 1
找到文件 drivers/net/ethernet/freescale/fec_main.c
int num_tx_qs;
int num_rx_qs;
/*
设置 MX6UL_PAD_ENET1_TX_CLK 和 MX6UL_PAD_ENET2_TX_CLK
3453 * 这两个 IO 的复用寄存器的 SION 位为 1。
*/
void __iomem *IMX6U_ENET1_TX_CLK;
void __iomem *IMX6U_ENET2_TX_CLK;
IMX6U_ENET1_TX_CLK = ioremap(0x020E00DC,4);
writel(0x14,IMX6U_ENET1_TX_CLK);
IMX6U_ENET2_TX_CLK = ioremap(0x020E00FC,4);
writel(0x14,IMX6U_ENET2_TX_CLK);
fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs);
配置Linux内核,使能驱动
使用make menuconfig 使能LAN8720A驱动
-> Device Drivers
-> Network device support
-> PHY Device support and infrastructure
-> Drivers for SMSC PHYs
修改smsc.c文件
找到文件drivers/net/phy/smsc.c
static int smsc_phy_reset(struct phy_device *phydev)
{
int timeout = 50000;
int rc = phy_read(phydev, MII_LAN83C185_SPECIAL_MODES);
if (rc < 0)
return rc;
/* If the SMSC PHY is in power down mode, then set it
* in all capable mode before using it.
*/
if ((rc & MII_LAN83C185_MODE_MASK) == MII_LAN83C185_MODE_POWERDOWN)
{
/* set "all capable" mode and reset the phy */
rc |= MII_LAN83C185_MODE_ALL;
phy_write(phydev, MII_LAN83C185_SPECIAL_MODES, rc);
}
phy_write(phydev, MII_BMCR, BMCR_RESET);
/* wait end of reset (max 500 ms) */
do {
udelay(10);
if (timeout-- == 0)
return -1;
rc = phy_read(phydev, MII_BMCR);
} while (rc & BMCR_RESET);
return 0;
}
网络驱动测试
修改完网络驱动注意保存配置信息,通过图形化配置的信息会保存在.config文件中,当执行make distclean 时,.config 文件会被清除,配置信息也就没了
保存配置信息
不执行make distclean 命令,重新编译时只会编译需要编译的文件,已经编译过的文件不会再次编译,节省编译时间
编译测试
打开两个网卡
ifconfig eth0 up
ifconfig eth1 up
看到"SMSC LAN8710/LAN8720”字样,说明当前的网络驱动使用的就是我们前面使能的 SMSC 驱动
给网卡配置IP地址
ifconfig eth0 192.168.31.251
ifconfig eth1 192.168.31.252
pingUbuntu主机
ping 192.168.31.224