一、在 Linux 中添加自己的开发板
1、添加开发板默认配置文件
将 arch/arm/configs 目 录 下 的 imx_v7_mfg_defconfig 重新复制一份,命名为 imx_kodo_emmc_defconfig,命令如下:
cd arch/arm/configs
cp imx_v7_mfg_defconfig imx_kodo_emmc_defconfig
以后就可以使用如下命令来配置正点原子 EMMC 版开发板对应的 Linux 内核了:
make imx_kodo_emmc_defconfig
2、添加开发板对应的设备树文件
添加适合 EMMC 版开发板的设备树文件,进入目录 arch/arm/boot/dts 中,复制一份 imx6ull-14x14-evk.dts,将其重命名为 imx6ull-kodo-emmc.dts,命令如下:
cd arch/arm/boot/dts
cp imx6ull-14x14-evk.dts imx6ull-kodo-emmc.dts
.dts 是设备树源码文件,编译 Linux 的时候会将其编译为.dtb 文件。imx6ull-kodo-emmc.dts 创建好以后还需要修改文件 arch/arm/boot/dts/Makefile , 找到 “ dtb- \((CONFIG_SOC_IMX6ULL)”配置项,在此配置项中加入“imx6ull-kodo-emmc.dtb”,如下所示:
dtb-\)(CONFIG_SOC_IMX6ULL) +=
imx6ull-14x14-ddr3-arm2.dtb
imx6ull-14x14-ddr3-arm2-adc.dtb
imx6ull-14x14-ddr3-arm2-cs42888.dtb
imx6ull-14x14-ddr3-arm2-ecspi.dtb
imx6ull-14x14-ddr3-arm2-emmc.dtb
imx6ull-14x14-ddr3-arm2-epdc.dtb
imx6ull-14x14-ddr3-arm2-flexcan2.dtb
imx6ull-14x14-ddr3-arm2-gpmi-weim.dtb
imx6ull-14x14-ddr3-arm2-lcdif.dtb
imx6ull-14x14-ddr3-arm2-ldo.dtb
imx6ull-14x14-ddr3-arm2-qspi.dtb
imx6ull-14x14-ddr3-arm2-qspi-all.dtb
imx6ull-14x14-ddr3-arm2-tsc.dtb
imx6ull-14x14-ddr3-arm2-uart2.dtb
imx6ull-14x14-ddr3-arm2-usb.dtb
imx6ull-14x14-ddr3-arm2-wm8958.dtb
imx6ull-14x14-evk.dtb
imx6ull-14x14-evk-btwifi.dtb
imx6ull-14x14-evk-emmc.dtb
imx6ull-14x14-evk-gpmi-weim.dtb
imx6ull-14x14-evk-usb-certi.dtb
imx6ull-kodo-emmc.dtb
imx6ull-9x9-evk.dtb
imx6ull-9x9-evk-btwifi.dtb
imx6ull-9x9-evk-ldo.dtb
第 23 行为“imx6ull-alientek-emmc.dtb”,编译 Linux 的时候就可以从 imx6ull-kodo-emmc.dts 编译出 imx6ull-kodo-emmc.dtb 文件了。
3、编译测试
创建一个编译脚本 kodo.sh,脚本内容如下:
!/bin/sh
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- distclean
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf imx_kodo_emmc_defconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all -j16
第 2 行:清理工程。
第 3 行:使用默认配置文件 imx_kodo_emmc_defconfig 来配置 Linux 内核。
第 4 行:打开 Linux 的图形配置界面,不需要每次都打开图形配置界面可以删除。
第 5 行:编译 Linux。
执行 shell 脚本 kodo.sh 编译 Linux 内核,命令如下:
chmod 777 kodo.sh //给予可执行权限
./kodo.sh //执行 shell 脚本编译内核
编译完成以后就会在目录 arch/arm/boot 下生成 zImage 镜像文件。在 arch/arm/boot/dts 目录下生成 imx6ull-kodo-emmc.dtb 文件。将这两个文件拷贝到 tftp 目录下,然后重启开发板,在 uboot 命令模式中使用 tftp 命令下载这两个文件并启动,命令如下:
tftp 80800000 zImage
tftp 83000000 imx6ull-kodo-emmc.dtb
bootz 80800000 - 83000000
只要出现如图所示内容就表示 Linux 内核启动成功:
二、CPU 主频和驱动修改
1、CPU 主频修改
2、使能 8 线 EMMC 驱动
Linux 内核驱动里面 EMMC 默认是 4 线模式的, 8 线模式的速度快,所以将 EMMC 的驱动修改为 8 线模式,直接修改设备树即可,打开文件 imx6ull-kodo-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;
no-1-8-v;
status = "okay";
};
修改完成以后保存一下 imx6ull-kodo-emmc.dts,然后使用命令“make dtbs”重新编译一下设备树,编译完成以后使用新的设备树重启 Linux 系统即可。
3、修改网络驱动
学习 Linux 驱动开发的时候要用到网络调试驱动,所以要把网络驱动调试好。开发板的网络和 NXP 官方的网络硬件上不同,网络 PHY 芯片由 KSZ8081 换为了 LAN8720A,两个网络 PHY 芯片的复位 IO 也不同,需要做修改。
①、修改 LAN8720 的复位以及网络时钟引脚驱动
ENET1 复位引脚 ENET1_RST 连接在 I.M6ULL 的 SNVS_TAMPER7 这个引脚上。ENET2 的复位引脚 ENET2_RST 连接在 I.MX6ULL 的 SNVS_TAMPER8 上。
打开设备树文件 imx6ull-kodo-emmc.dts,找到如下代码:
pinctrl_spi4: spi4grp {
fsl,pins = <
MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10 0x70a1
MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x70a1
MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x70a1
MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x80000000
>;
};
示例代码中第 5 和 6 行就是初始化 SNVS_TAMPER7 和 SNVS_TAMPER8 这两个
引脚的,不过是作为了 SPI4 的 IO,所以将 5 和 6 这两行注释掉。
继续在 imx6ull-alientek-emmc.dts 中找到如下所示代码:
spi4 {
compatible = "spi-gpio";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_spi4>;
pinctrl-assert-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>;
......
cs-gpios = <&gpio5 7 0>;
第 5 行:设置 GPIO5_IO08 为 SPI4 的一个功能引脚(不清楚具体作为什么功能用),而 GPIO5_IO08 就是 SNVS_TAMPER8 的 GPIO 功能引脚。
第 7 行:设置 GPIO5_IO07 作为 SPI4 的片选引脚,而 GPIO5_IO07 就是 SNVS_TAMPER7 的 GPIO 功能引脚。需要 GPIO5_IO07 和 GPIO5_IO08 分别作为 ENET1 和 ENET2 的复位引脚,因此将示例代码中的第 5 行和第 7 行处的代码注释掉!
在 imx6ull-kodo-emmc.dts 里面找到名为“iomuxc_snvs”的节点(就是直接搜索),然后在此节点下添加网络复位引脚信息,添加完成以后的“iomuxc_snvs”的节点内容如下:
&iomuxc_snvs {
pinctrl-names = "default_snvs";
pinctrl-0 = <&pinctrl_hog_2>;
imx6ul-evk {
......
/省略掉其他/
/*enet1 reset zuozhongkai*/
pinctrl_enet1_reset: enet1resetgrp {
fsl,pins = <
/* used for enet1 reset */
MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x10B0
>;
};
/*enet2 reset zuozhongkai*/
pinctrl_enet2_reset: enet2resetgrp {
fsl,pins = <
/* used for enet2 reset */
MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x10B0
>;
};
};
};
第 1 行:imx6ull-kodo-emmc.dts 文件中 iomuxc_snvs 节点。
第 9~14 行:ENET1 网络复位引脚配置信息。
第 17~22 行:ENET2 网络复位引脚配置信息。
最后还需要修改一下 ENET1 和 ENET2 的网络时钟引脚配置,继续在 imx6ull-kodo-emmc.dts 中找到如下所示代码:
pinctrl_enet1: enet1grp {
fsl,pins = <
MX6UL_PAD_ENET1_RX_EN__ENET1_RX_EN 0x1b0b0
MX6UL_PAD_ENET1_RX_ER__ENET1_RX_ER 0x1b0b0
MX6UL_PAD_ENET1_RX_DATA0__ENET1_RDATA00 0x1b0b0
MX6UL_PAD_ENET1_RX_DATA1__ENET1_RDATA01 0x1b0b0
MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN 0x1b0b0
MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b0b0
MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b0b0
MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 0x4001b009
>;
};
pinctrl_enet2: enet2grp {
fsl,pins = <
MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0
MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0
MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0
MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0
MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0
MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b009
>;
};
第 10 和 25 行:分别为 ENET1 和 ENET2 的网络时钟引脚配置信息,将这两个引脚的电气属性值改为 0x4001b009,原来默认值为 0x4001b031。
修改完成以后保存一下 imx6ull-kodo-emmc.dts,网络复位以及时钟引脚驱动就修改好了。
②、修改 fec1 和 fec2 节点的 pinctrl-0 属性
在 imx6ull-kodo-emmc.dts 文件中找到名为“fec1”和“fec2”的这两个节点,修改其中的“pinctrl-0”属性值,修改以后如下所示:
&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1
&pinctrl_enet1_reset>;
phy-mode = "rmii";
......
status = "okay";
};
&fec2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet2
&pinctrl_enet2_reset>;
phy-mode = "rmii";
......
};
第 3~4 行:修改后的 fec1 节点“pinctrl-0”属性值。
第 12~13 行:修改后的 fec2 节点“pinctrl-0”属性值。
③、修改 LAN8720A 的 PHY 地址
在 uboot 移植时, ENET1 的 LAN8720A 地址为 0x0,ENET2 的 LAN8720A
地址为 0x1。在 imx6ull-kodo-emmc.dts 中找到如下代码:
&fec1 {
pinctrl-names = "default";
......
phy-handle = <ðphy0>;
status = "okay";
};
&fec2 {
pinctrl-names = "default";
......
phy-handle = <ðphy1>;
status = "okay";
mdio {
#address-cells = <1>;
#size-cells = <0>;
ethphy0: ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <2>;
};
ethphy1: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <1>;
};
};
};
第 1~6 行:ENET1 对应的设备树节点。
第 8~28 行:ENET2 对应的设备树节点。但是第 14~26 行的 mdio 节点描述了 ENET1 和 ENET2 的 PHY 地址信息。将代码改为如下内容:
&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1
&pinctrl_enet1_reset>;
phy-mode = "rmii";
phy-handle = <ðphy0>;
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 = <ðphy1>;
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";
smsc,disable-energy-detect;
reg = <0>;
};
ethphy1: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
smsc,disable-energy-detect;
reg = <1>;
};
};
};
第 18 和 19 行:添加了 ENET1 网络复位引脚所使用的 IO 为 GPIO5_IO07,低电平有效,复位低电平信号持续时间为 200ms。
第 18 和 19 行:ENET2 网络复位引脚所使用的 IO 为 GPIO5_IO08,同样低电平有效,持续时间同样为 200ms。
第 28 和 34 行:“smsc,disable-energy-detect”表明 PHY 芯片是 SMSC 公司的,这样 Linux 内核就会找到 SMSC 公司的 PHY 芯片驱动来驱动 LAN8720A。
第 26 行:注意“ethernet-phy@”后面的数字是 PHY 的地址,ENET1 的 PHY 地址为 0,所以“@”后面是 0(默认为 2)。
第 29 行:reg 的值也表示 PHY 地址,ENET1 的 PHY 地址为 0,所以 reg=0。
第 32 行:ENET2 的 PHY 地址为 1,因此“@”后面为 1。
第 35 行:因为 ENET2 的 PHY 地址为 1,所以 reg=1。
至此,LAN8720A 的 PHY 地址就改好了,保存一下 imx6ull-kodo-emmc.dts 文件。然后使用“make dtbs”命令重新编译一下设备树。
④、修改 fec_main.c 文件
要在 I.MX6ULL 上使用 LAN8720A,需要修改一下 Linux 内核源码,打开
drivers/net/ethernet/freescale/fec_main.c,找到 fec_probe 函数,加入如下代码:
static int
fec_probe(struct platform_device *pdev)
{
struct fec_enet_private *fep;
struct fec_platform_data *pdata;
struct net_device *ndev;
int i, irq, ret = 0;
struct resource *r;
const struct of_device_id *of_id;
static int dev_id;
struct device_node *np = pdev->dev.of_node, *phy_node;
int num_tx_qs;
int num_rx_qs;
/* 设置 MX6UL_PAD_ENET1_TX_CLK 和 MX6UL_PAD_ENET2_TX_CLK
* 这两个 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);
......
return ret;
}
第 18~25 就是新加入的代码,如果要在 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
⑥、修改 smsc.c 文件
在测试 NFS 挂载文件系统的时候发现文件系统挂载成功率很低!提示 NFS 服务器找不到。NFS 挂载就是通过网络来挂载文件系统,这样做的好处就是方便我们后续调试 Linux 驱动。既然是挂载失败那么可以肯定的是网络驱动有问题,网络驱动分两部分:内部 MAC+外部 PHY,内部 MAC 驱动是由 NXP 提供的,一般不会出问题,所以只有可能是外部 PHY,也就是 LAN8720A 的驱动可能出问题了。在 uboot 中需要对LAN8720A 进行一次软复位,要设置 LAN8720A 的 BMCR(寄存器地址为 0)寄存器 bit15 为 1。所以猜测,在 Linux 中也需要对 LAN8720A 进行一次软复位。
LAN8720A 的驱动文件是 drivers/net/phy/smsc.c,在此文件中有个叫做 smsc_phy_reset 的函数,看名字这是 SMSC PHY 的复位函数,因此 LAN8720A 肯定也会使用到这个复位函数,修改此函数的内容,修改以后的 smsc_phy_reset
函数内容如下所示:
static int smsc_phy_reset(struct phy_device *phydev)
{
int err, phy_reset;
int msec = 1;
struct device_node np;
int timeout = 50000;
if(phydev->addr == 0) / FEC1 */ {
np = of_find_node_by_path("/soc/aips-bus@02100000/ethernet@02188000");
if(np == NULL) {
return -EINVAL;
}
}
if(phydev->addr == 1) /* FEC2 */ {
np = of_find_node_by_path("/soc/aips-bus@02000000/ethernet@020b4000");
if(np == NULL) {
return -EINVAL;
}
}
err = of_property_read_u32(np, "phy-reset-duration", &msec);
/* A sane reset duration should not be longer than 1s */
if (!err && msec > 1000)
msec = 1;
phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
if (!gpio_is_valid(phy_reset))
return;
gpio_direction_output(phy_reset, 0);
gpio_set_value(phy_reset, 0);
msleep(msec);
gpio_set_value(phy_reset, 1);
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;
}
第 7~12 行:获取 FEC1 网卡对应的设备节点。
第 14~19 行:获取 FEC2 网卡对应的设备节点。
第 21 行:从设备树中获取“phy-reset-duration”属性信息,也就是复位时间。
第 25 行:从设备树中获取“phy-reset-gpios”属性信息,也就是复位 IO。
第 29~32 行:设置 PHY 的复位 IO,复位 LAN8720A。
第 41~48 行:以前的 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 镜像文件和 imx6ull-kodo-emmc.dtb 设备树文件,使用网线将 I.MX6U-ALPHA 开发板的两个网口与路由器或者电脑连接起来,最后使用新的文件启动 Linux 内核。启动以后使用“ifconfig”命令查看一下当前活动的网卡有哪些。
⑧、网络挂载根文件系统
网络驱动移植好以后,将根文件系统 rootfs 使用 NFS 挂载到 Linux 系统上,
uboot 里面的 bootargs 环境变量会设置“root”的值,所以我们将 root 的值改为 NFS 挂载即可。
在 Linux 内核源码里面有相应的文档 Documentation/filesystems/nfs/
nfsroot.txt,格式如下:
root=/dev/nfs nfsroot=[
根据上面的格式 bootargs 环境变量的 root 值如下:
root=/dev/nfs nfsroot=192.168.148.103:/home/kodo/NFS/rootfs,proto=tcp rw ip=192.168.148.240:192.168.148.103:192.168.1.1:255.255.255.0::eth0:off
“proto=tcp”表示使用 TCP 协议,“rw”表示 nfs 挂载的根文件系统为可读可写。
启动开发板,进入 uboot 命令行模式,然后重新设置 bootargs 环境变量,命令如下:
setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.148.103:/home/kodo/NFS/rootfs,proto=tcp rw ip=192.168.148.240:192.168.148.103:192.168.1.1:255.255.255.0::eth0:off'
setenv bootcmd 'tftp 80800000 zImage;tftp 83000000 imx6ull-kodo-emmc.dtb;bootz 80800000 - 83000000'
saveenv
⑨、LCD 控制台设置
想要设置 LCD 作为终端控制台,需要设置 uboot 中的 bootargs,重启开发板,进入 Linux 命令行,重新设置 bootargs 参数的 console 内容,命令如下:
setenv bootargs 'console=tty1 console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.148.103:/home/kodo/NFS/rootfs,proto=tcp rw ip=192.168.148.240:192.168.148.103:192.168.1.1:255.255.255.0::eth0:off'
设置了两遍 console,第一次设置 console=tty1,也就是设置 LCD 屏幕为控制台,第二遍又设置 console=ttymxc0,115200,也就是设置串口也作为控制台。相当于打开了两个 console,一个是 LCD,一个是串口,重启开发板 LCD 和串口都会显示 Linux 启动 log 信息。但是此时还不能使用 LCD 作为终端进行交互,设置还未完成。
打开开发板根文件系统中的 /etc/inittab 文件,在里面加入下面这一行:
tty1::askfirst:-/bin/sh
添加完成以后的/etc/inittab 文件内容如图所示:
修改完成以后保存 /etc/inittab 并退出,然后重启开发板,重启以后开发板 LCD 屏幕最后一行会显示下面一行语句:
Please press Enter to activate this console.
上述提示语句说的是:按下回车键使能当前终端,可以接上一个 USB 键盘,Linux 内核默认已经使能了 USB 键盘驱动了,因此可以直接使用 USB 键盘。
关于 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内核移植成功以后就要开始根文件系统的构建。