1.在U-Boot中驅(qū)動LCD和網(wǎng)絡(luò)
在U-Boot 移植初探一文中介紹了如何修改 NXP官方uboot,使得 uboot能匹配我們自己的開發(fā)板,但是匹配完成后 LCD驅(qū)動和網(wǎng)絡(luò)驅(qū)動還是不正常的,所以下面將介紹如何修改 LCD驅(qū)動和網(wǎng)絡(luò)驅(qū)動等
1.1 LCD驅(qū)動修改
uboot 中修改驅(qū)動都是在對應(yīng)板子的 .c文件和 .h文件中進(jìn)行,即下面兩個文件中:mx6ull_andyxi_emmc.c 和 mx6ull_andyxi_emmc.h
修改 LCD驅(qū)動重點注意以下幾點:
- LCD的 IO配置是否正確
- LCD背光引腳 GPIO的配置
- LCD配置參數(shù)是否正確
我們使用的 I.MX6ULL開發(fā)板的 LCD原理圖和 NXP官方的開發(fā)板一致,也就是LCD的IO和背光IO都是一樣的, 所以IO部分就不用修改了,只需修改 LCD配置參數(shù)即可
mx6ull_andyxi_emmc.c 文件中修改下面內(nèi)容:
/*######### 原始內(nèi)容 ###############################*/
/*該代碼定義了一個變量displays,類型為display_info_t,這個結(jié)構(gòu)體
是LCD信息結(jié)構(gòu)體,其中包括了LCD的分辨率,像素格式,LCD的各個參數(shù)等*/
struct display_info_t const displays[] = {{
.bus = MX6UL_LCDIF1_BASE_ADDR,
.addr = 0,
.pixfmt = 24,
.detect = NULL,
.enable = do_enable_parallel_lcd,
.mode = {
.name = "TFT43AB",
.xres = 480,
.yres = 272,
.pixclock = 108695,
.left_margin = 8,
.right_margin = 4,
.upper_margin = 2,
.lower_margin = 4,
.hsync_len = 41,
.vsync_len = 10,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED
} } };
/*######### 修改后的內(nèi)容 ###########################*/
struct display_info_t const displays[] = {{
.bus = MX6UL_LCDIF1_BASE_ADDR,
.addr = 0,
.pixfmt = 24,
.detect = NULL,
.enable = do_enable_parallel_lcd,
.mode = {
.name = "TFT7016",
.xres = 1024,
.yres = 600,
.pixclock = 19531,
.left_margin = 140, //HBPD
.right_margin = 160, //HFPD
.upper_margin = 20, //VBPD
.lower_margin = 12, //VFPD
.hsync_len = 20, //HSPW
.vsync_len = 3, //VSPW
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED
} } };
mx6ull_andyxi_emmc.h 文件中修改 panel值
panel=TFT7016 #根據(jù)具體使用型號修改
重新編譯 uboot并燒寫到 SD中啟動后,若 LCD仍不能顯示,則需要在uboot命令模式下,檢查環(huán)境變量 panel的值,確保與 LCD參數(shù)里的 name一致
panel=TFT7016 #與mx6ull_andyxi_emmc.c中修改的名稱保持一致
1.2 網(wǎng)絡(luò)驅(qū)動修改
I.MX6UL/ULL 內(nèi)部有個以太網(wǎng) MAC外設(shè),需要外接一個 PHY芯片來實現(xiàn)網(wǎng)絡(luò)通信功能。 我們使用的 I.MX6U 開發(fā)板提供了這兩個網(wǎng)絡(luò)接口,都使用 LAN8720A 作為 PHY 芯片。 NXP 官方的I.MX6ULL EVK 開發(fā)板使用 KSZ8081 的 PHY 芯片。 下面將介紹更換了PHY 芯片以后如何調(diào)整網(wǎng)絡(luò)驅(qū)動,使網(wǎng)絡(luò)工作正常。
開發(fā)板 ENET1/ENET2的原理圖如下示:
網(wǎng)絡(luò) PHY芯片LAN8720A,通過 RMII接口與 I.MX6ULL相連,引腳與 NXP官方的 I.MX6ULL EVK 開發(fā)板基本一樣,只是復(fù)位引腳不同。 從上圖可以看出,復(fù)位引腳ENET1_RST 接到了 I.M6ULL 的 SNVS_TAMPER7 引腳上,復(fù)位引腳 ENET2_RST 接到了 SNVS_TAMPER8 引腳上
修改網(wǎng)絡(luò)驅(qū)動重點注意以下幾點:
- LAN8720A復(fù)位引腳初始化
- LAN8720A的器件ID
- LAN8720A驅(qū)動
在 mx6ull_andyxi_emmc.c中添加復(fù)位引腳驅(qū)動
/* 結(jié)構(gòu)體數(shù)組fec1_pads和fec2_pads是ENET1和ENET2這兩個網(wǎng)口的IO
* 配置參數(shù),在這兩個數(shù)組中添加兩個網(wǎng)口的復(fù)位 IO 配置參數(shù) */
/*######### 原始內(nèi)容 ###############################*/
staticiomux_v3_cfg_tconst fec1_pads[]={
MX6_PAD_GPIO1_IO06__ENET1_MDIO |MUX_PAD_CTRL(MDIO_PAD_CTRL),
MX6_PAD_GPIO1_IO07__ENET1_MDC |MUX_PAD_CTRL(ENET_PAD_CTRL),
......
MX6_PAD_ENET1_RX_ER__ENET1_RX_ER |MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET1_RX_EN__ENET1_RX_EN |MUX_PAD_CTRL(ENET_PAD_CTRL),
};
staticiomux_v3_cfg_tconst fec2_pads[]={
MX6_PAD_GPIO1_IO06__ENET2_MDIO |MUX_PAD_CTRL(MDIO_PAD_CTRL),
MX6_PAD_GPIO1_IO07__ENET2_MDC |MUX_PAD_CTRL(ENET_PAD_CTRL),
......
MX6_PAD_ENET2_RX_EN__ENET2_RX_EN |MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET2_RX_ER__ENET2_RX_ER |MUX_PAD_CTRL(ENET_PAD_CTRL),
};
/*######### 修改后的內(nèi)容 ###########################*/
staticiomux_v3_cfg_tconst fec1_pads[]={
MX6_PAD_GPIO1_IO06__ENET1_MDIO |MUX_PAD_CTRL(MDIO_PAD_CTRL),
MX6_PAD_GPIO1_IO07__ENET1_MDC |MUX_PAD_CTRL(ENET_PAD_CTRL),
......
MX6_PAD_ENET1_RX_ER__ENET1_RX_ER |MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET1_RX_EN__ENET1_RX_EN |MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 |MUX_PAD_CTRL(NO_PAD_CTRL),//添加此行
};
staticiomux_v3_cfg_tconst fec2_pads[]={
MX6_PAD_GPIO1_IO06__ENET2_MDIO |MUX_PAD_CTRL(MDIO_PAD_CTRL),
MX6_PAD_GPIO1_IO07__ENET2_MDC |MUX_PAD_CTRL(ENET_PAD_CTRL),
......
MX6_PAD_ENET2_RX_EN__ENET2_RX_EN |MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET2_RX_ER__ENET2_RX_ER |MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 |MUX_PAD_CTRL(NO_PAD_CTRL),//添加此行
};
/* 函數(shù) setup_iomux_fec 就是根據(jù) fec1_pads 和 fec2_pads 這兩個網(wǎng)絡(luò)IO配置
數(shù)組來初始化I.MX6ULL的網(wǎng)絡(luò)IO,此處需要在其中添加網(wǎng)絡(luò)復(fù)位IO的初始化代碼,
并且復(fù)位一下 PHY 芯片
*/
/*######### 原始內(nèi)容 ###############################*/
staticvoidsetup_iomux_fec(int fec_id)
{
if(fec_id ==0)
imx_iomux_v3_setup_multiple_pads(fec1_pads,ARRAY_SIZE(fec1_pads));
else
imx_iomux_v3_setup_multiple_pads(fec2_pads, ARRAY_SIZE(fec2_pads));
}
/*######### 修改后的內(nèi)容 ###########################*/
staticvoidsetup_iomux_fec(int fec_id)
{
if(fec_id ==0)
{
imx_iomux_v3_setup_multiple_pads(fec1_pads,ARRAY_SIZE(fec1_pads));
gpio_direction_output(ENET1_RESET,1);
gpio_set_value(ENET1_RESET,0);
mdelay(20);
gpio_set_value(ENET1_RESET,1);
}
else{
imx_iomux_v3_setup_multiple_pads(fec2_pads,ARRAY_SIZE(fec2_pads));
gpio_direction_output(ENET2_RESET,1);
gpio_set_value(ENET2_RESET,0);
mdelay(20);
gpio_set_value(ENET2_RESET,1);
}
}
在 mx6ull_andyxi_emmc.h中修改 PHY器件地址及驅(qū)動
/*######### 原始內(nèi)容 ###############################*/
#ifdef CONFIG_CMD_NET
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_MII
#define CONFIG_FEC_MXC
#define CONFIG_MII
#define CONFIG_FEC_ENET_DEV 1 //用于選擇使用哪個網(wǎng)卡,默認(rèn)為1(ENET2)
#if (CONFIG_FEC_ENET_DEV == 0)
#define IMX_FEC_BASE ENET_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR 0x2 //ENET1的PHY地址,默認(rèn)為0x2
#define CONFIG_FEC_XCV_TYPE RMII
#elif (CONFIG_FEC_ENET_DEV == 1)
#define IMX_FEC_BASE ENET2_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR 0x1 //ENET2的PHY地址,默認(rèn)為0x1
#define CONFIG_FEC_XCV_TYPE RMII
#endif
#define CONFIG_ETHPRIME "FEC"
#define CONFIG_PHYLIB
#define CONFIG_PHY_MICREL //用于使能Micrel公司的PHY驅(qū)動(KSZ8081芯片)
#endif
/*######### 修改后的內(nèi)容 ###########################*/
#ifdef CONFIG_CMD_NET
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_MII
#define CONFIG_FEC_MXC
#define CONFIG_MII
#define CONFIG_FEC_ENET_DEV 1
#if (CONFIG_FEC_ENET_DEV == 0)
#define IMX_FEC_BASE ENET_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR 0x0 //修改ENET1的PHY地址為0x0
#define CONFIG_FEC_XCV_TYPE RMII
#elif (CONFIG_FEC_ENET_DEV == 1)
#define IMX_FEC_BASE ENET2_BASE_ADDR
#define CONFIG_FEC_MXC_PHYADDR 0x1 //修改ENET2的PHY地址為為0x1
#define CONFIG_FEC_XCV_TYPE RMII
#endif
#define CONFIG_ETHPRIME "FEC"
#define CONFIG_PHYLIB
#define CONFIG_PHY_SMSC //使能SMSC公司的PHY驅(qū)動(LAN8720A是SMSC生產(chǎn)的)
#endif
在 mx6ull_andyxi_emmc.c中刪除 74LV595的驅(qū)動代碼
/* NXP 官方I.MX6ULL EVK 開發(fā)板使用74LV595來擴(kuò)展 IO,兩個網(wǎng)絡(luò)的復(fù)位引腳
* 就是由74LV595來控制的,I.MX6U-ALPHA開發(fā)板并沒有使用74LV595,因此刪除掉
*/
/*######### 原始內(nèi)容 ###############################*/
#define IOX_SDI IMX_GPIO_NR(5, 10)
#define IOX_STCP IMX_GPIO_NR(5, 7)
#define IOX_SHCP IMX_GPIO_NR(5, 11)
#define IOX_OE IMX_GPIO_NR(5, 8)
/*##### 修改后的內(nèi)容:以上四行替換為以下兩行 #######*/
/* ENET1 的復(fù)位引腳連接到 SNVS_TAMPER7 上,對應(yīng) GPIO5_IO07
* ENET2 的復(fù)位引腳連接到 SNVS_TAMPER8 上,對應(yīng) GPIO5_IO08
*/
#define ENET1_RESET IMX_GPIO_NR(5, 7)
#define ENET2_RESET IMX_GPIO_NR(5, 8)
//刪除74LV595的IO配置參數(shù)結(jié)構(gòu)體
/*######### 刪除以下內(nèi)容 ###############################*/
staticiomux_v3_cfg_tconst iox_pads[]={
/* IOX_SDI */
MX6_PAD_BOOT_MODE0__GPIO5_IO10 |MUX_PAD_CTRL(NO_PAD_CTRL),
/* IOX_SHCP */
MX6_PAD_BOOT_MODE1__GPIO5_IO11 |MUX_PAD_CTRL(NO_PAD_CTRL),
/* IOX_STCP */
MX6_PAD_SNVS_TAMPER7__GPIO5_IO07 |MUX_PAD_CTRL(NO_PAD_CTRL),
/* IOX_nOE */
MX6_PAD_SNVS_TAMPER8__GPIO5_IO08 |MUX_PAD_CTRL(NO_PAD_CTRL),
};
//刪除74LV595的初始化函數(shù)
/*######### 刪除以下內(nèi)容 ###############################*/
staticvoidiox74lv_init(void)
{
int i;
gpio_direction_output(IOX_OE,0);
for(i =7; i >=0; i--){
gpio_direction_output(IOX_SHCP,0);
gpio_direction_output(IOX_SDI, seq[qn_output[i]][0]);
udelay(500);
gpio_direction_output(IOX_SHCP,1);
udelay(500);
}
......
/*
* shift register will be output to pins
*/
gpio_direction_output(IOX_STCP,1);
};
//刪除iox74lv_set函數(shù)(用于控制74LV595的IO輸出電平)
/*######### 刪除以下內(nèi)容 ###############################*/
voidiox74lv_set(int index)
{
int i;
for(i =7; i >=0; i--){
gpio_direction_output(IOX_SHCP,0);
if(i == index)
gpio_direction_output(IOX_SDI, seq[qn_output[i]][0]);
else
gpio_direction_output(IOX_SDI, seq[qn_output[i]][1]);
udelay(500);
gpio_direction_output(IOX_SHCP,1);
udelay(500);
}
......
/*
* shift register will be output to pins
*/
gpio_direction_output(IOX_STCP,1);
};
/* 刪除板子初始化函數(shù) board_init 中的74lv595 的GPIO初始化代碼 */
/*######### 刪除部分代碼 ###############################*/
intboard_init(void)
{
......
imx_iomux_v3_setup_multiple_pads(iox_pads,ARRAY_SIZE(iox_pads));//刪除此行
iox74lv_init(); //刪除此行
......
return0;
}
在drivers/net/phy/phy.c 中的 genphy_update_link函數(shù)里,添加 SMSC的 PHY芯片條件編譯代碼段
/*######### 修改后的內(nèi)容 ###########################*/
intgenphy_update_link(structphy_device*phydev){
unsignedint mii_reg;
//以下為添加的SMSC的PHY芯片條件編譯代碼段,只有使用SMSC的PHY才會執(zhí)行
#ifdef CONFIG_PHY_SMSC
staticint lan8720_flag =0;
int bmcr_reg =0;
if(lan8720_flag ==0){
bmcr_reg =phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
while(phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR)&0X8000){
udelay(100);
}
phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, bmcr_reg);
lan8720_flag =1;
}
#endif
mii_reg =phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
......
return0;
}
至此網(wǎng)絡(luò)的復(fù)位引腳驅(qū)動修改完成,重新編譯 uboot,然后將 u-boot.bin 燒寫到 SD 卡中并啟動,uboot 啟動信息如下圖所示:
由上圖可見當(dāng)前使用FEC1這個網(wǎng)口(ENET2),但此時網(wǎng)絡(luò)地址還沒有設(shè)置。 在uboot使用網(wǎng)絡(luò)之前還要先設(shè)置以下幾個網(wǎng)絡(luò)環(huán)境變量
setenv ipaddr 192.168.10.50 //開發(fā)板 IP 地址
setenv ethaddr b8:ae:1d:01:00:00 //開發(fā)板網(wǎng)卡 MAC 地址
setenv gatewayip 192.168.10.1 //開發(fā)板默認(rèn)網(wǎng)關(guān)
setenv netmask 255.255.255.0 //開發(fā)板子網(wǎng)掩碼
setenv serverip 192.168.10.100 //服務(wù)器地址,也就是 Ubuntu 地址
saveenv //保存環(huán)境變量
設(shè)置好環(huán)境變量以后就可以在 uboot 中使用網(wǎng)絡(luò)了,用網(wǎng)線將開發(fā)板上的 ENET2與電腦連接起來,保證開發(fā)板和電腦在同一個網(wǎng)段內(nèi),通過 ping 命令來測試網(wǎng)絡(luò)連接,命令如下:
ping 192.168.1.100
結(jié)果如下圖示,說明ping 主機(jī)成功,至此說明ENET2網(wǎng)絡(luò)工作正常
將 mx6ull_andyxi_emmc.h中的CONFIG_FEC_ENET_DEV參數(shù)改為 0,然后重新編譯 uboot 并燒寫到 SD 卡中重啟,按以上步驟可以測試 ENET1 的網(wǎng)絡(luò)是否正常工作
1.3 其他修改
在 uboot啟動信息中會有“Board: MX6ULL 14x14 EVK”這一句,即板子名字為“ MX6ULL 14x14 EVK”,可將其改為我們自已的名字“ MX6ULL ANDYXI EMMC”
在mx6ull_andyxi_emmc.c中的checkboard函數(shù)里,做如下修改
/*######### 修改后的內(nèi)容 ###########################*/
intcheckboard(void)
{
if(is_mx6ull_9x9_evk())
puts("Board: MX6ULL 9x9 EVK\\n");
else
puts("Board: MX6ULL ANDYXI EMMC\\n");
return0;
}
修改完成以后重新編譯 uboot 并燒寫到 SD 卡中驗證,uboot 啟動信息如下圖,可見名字已經(jīng)修改過來了
2.bootcmd和bootargs環(huán)境變量
uboot 中有兩個非常重要的環(huán)境變量 bootcmd 和 bootargs,是采用類似 shell 腳本語言編寫的,里面有很多 NXP自己定義的的環(huán)境變量引用
文件 mx6ull_andyxi_emmc.h中的
宏CONFIG_EXTRA_ENV_SETTINGS 保存著這些環(huán)境變量的默認(rèn)值,其內(nèi)容如下:
#if defined(CONFIG_SYS_BOOT_NAND)
#defineCONFIG_EXTRA_ENV_SETTINGS\\
CONFIG_MFG_ENV_SETTINGS \\
"panel=TFT43AB\\0"\\
"fdt_addr=0x83000000\\0"\\
"fdt_high=0xffffffff\\0"\\
......
"bootz ${loadaddr} - ${fdt_addr}\\0"
#else
#defineCONFIG_EXTRA_ENV_SETTINGS\\
CONFIG_MFG_ENV_SETTINGS \\
"script=boot.scr\\0"\\
"image=zImage\\0"\\
"console=ttymxc0\\0"\\
"fdt_high=0xffffffff\\0"\\
"initrd_high=0xffffffff\\0"\\
"fdt_file=undefined\\0"\\
......
"findfdt="\\
"if test $fdt_file = undefined; then " \\
"if test $board_name = EVK && test $board_rev = 9X9; then " \\
"setenv fdt_file imx6ull-9x9-evk.dtb; fi; " \\
"if test $board_name = EVK && test $board_rev = 14X14; then " \\
"setenv fdt_file imx6ull-14x14-evk.dtb; fi; " \\
"if test $fdt_file = undefined; then " \\
"echo WARNING: Could not determine dtb to use; fi; " \\
"fi;\\0" \\
2.1 bootcmd環(huán)境變量
bootcmd 保存著 uboot 默認(rèn)命令, uboot 倒計時結(jié)束后就會執(zhí)行其中的命令。 一般是用來啟動內(nèi)核的,比如讀取 EMMC或 NAND Flash中的內(nèi)核鏡像文件和設(shè)備樹文件到 DRAM中,然后啟動內(nèi)核
可在 uboot啟動后進(jìn)入命令行設(shè)置 bootcmd環(huán)境變量的值。 如果 EMMC或者 NAND中沒有保存 bootcmd的值,那么 uboot就會使用默認(rèn)值,板子第一次運行 uboot 時都會使用默認(rèn)值來設(shè)置 bootcmd 環(huán)境變量
打開文件 include/env_default.h,在此文件中有如下所示內(nèi)容:
......
#ifdef CONFIG_BOOTARGS
"bootargs=" CONFIG_BOOTARGS "\\0"
#endif
#ifdef CONFIG_BOOTCOMMAND
"bootcmd=" CONFIG_BOOTCOMMAND "\\0"
#endif
......
env_default.h中指定了很多環(huán)境變量的默認(rèn)值,比如 bootcmd 的默認(rèn)值是CONFIG_BOOTCOMMAND,bootargs的是 CONFIG_BOOTARGS。 我們可在mx6ull_andyxi_emmc.h 文件中通過設(shè)置宏 CONFIG_BOOTCOMMAND來設(shè)置 bootcmd 的默認(rèn)值, NXP官方設(shè)置的 CONFIG_BOOTCOMMAND 值如下:
#defineCONFIG_BOOTCOMMAND\\
"run findfdt;"\\
"mmc dev ${mmcdev};"\\
"mmc dev ${mmcdev}; if mmc rescan; then "\\
"if run loadbootscript; then "\\
"run bootscript; "\\
"else "\\
"if run loadimage; then "\\
"run mmcboot; "\\
"else run netboot; "\\
"fi; "\\
"fi; "\\
"else run netboot; fi"
2.2 bootargs環(huán)境變量
bootargs 保存著 uboot 傳遞給 Linux 內(nèi)核的參數(shù),以下面命令為例
setenv bootargs console= ttymxc0, 115200 root= /dev/mmcblk1p2 rootwait rw
bootargs 中常用的參數(shù)有:
- console:用來設(shè)置 linux終端,即通過什么設(shè)備來和 Linux進(jìn)行交互,是串口還是 LC 屏幕,一般設(shè)置串口作為 Linux終端,這樣就可以在電腦上通過串口助手來和 linux進(jìn)行交互了
console= ttymxc0, 115200
//console 為 ttymxc0,因為 linux啟動以后I.MX6ULL的串口1
//在linux下的設(shè)備文件就是/dev/ttymxc0
//ttymxc0 后面的“115200”,是設(shè)置串口的波特率
- root:用來設(shè)置根文件系統(tǒng)的位置
root= /dev/mmcblk1p2 rootwait rw
// /dev/mmcblk1p2用于指明根文件系統(tǒng)存放在mmcblk1設(shè)備的分區(qū)2中
// /dev/mmcblkxpy(x=0~ n,y=1~ n)表示mmc設(shè)備x的分區(qū)y
// rootwait表示等待mmc設(shè)備初始化完成以后再掛載,否則的話會出錯
// rw 表示根文件系統(tǒng)是可以讀寫的,不加rw的話可能只能讀而無法進(jìn)行寫操作
- rootfstype:一般與root一起使用, 用于指定根文件系統(tǒng)類型,如果根文件系統(tǒng)為ext 格式的話此選項無所謂。 如果根文件系統(tǒng)是 yaffs、 jffs 或 ubifs 的話就需要設(shè)置此選項,指定根文件系統(tǒng)的類型
3.U-Boot啟動Linux測試
uboot 已經(jīng)移植好后,就要測試一下 uboot 能不能完成它的工作:啟動 Linux 內(nèi)核。 這里測試兩種啟動 Linux 內(nèi)核的方法,一種是直接從 EMMC 啟動,一種是從網(wǎng)絡(luò)啟動
3.1 從EMMC啟動Linux
從 EMMC 啟動也就是將編譯出來的 Linux 鏡像文件 zImage 和設(shè)備樹文件保存在 EMMC中, uboot 從 EMMC 中讀取這兩個文件并啟動,這個是產(chǎn)品最終的啟動方式。 此處默認(rèn)已經(jīng)將 zImage 文件和設(shè)備樹文件燒寫到了 EMMC 中,可以直接讀取來進(jìn)行測試
使用命令“l(fā)s mmc 1:1”檢查 EMMC 的分區(qū) 1 中是否已有相關(guān)文件,下圖結(jié)果表示已有相關(guān)文件
設(shè)置 bootargs 和 bootcmd 這兩個環(huán)境變量
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
setenv bootcmd 'mmc dev 1; fatload mmc 1:1 80800000 zImage; fatload mmc 1:1 83000000
imx6ull-andyxi-emmc.dtb; bootz 80800000 - 83000000;'
saveenv
輸入“boot”命令,啟動內(nèi)核即可
3.2 從網(wǎng)絡(luò)啟動Linux
從網(wǎng)絡(luò)啟動 linux系統(tǒng)的唯一目的就是為了調(diào)試! 不管是為了調(diào)試 linux系統(tǒng)還是 linux下的驅(qū)動,每次修改 linux系統(tǒng)文件或者 linux下的某個驅(qū)動后都要將其燒寫到 EMMC 中去測試,這樣太麻煩了。 可以設(shè)置從網(wǎng)絡(luò)啟動,將 linux鏡像文件和根文件系統(tǒng)都放到 Ubuntu下指定的文件夾中,這樣每次重新編譯 linux內(nèi)核或者 linux驅(qū)動后只需要將其拷貝到這個指定的文件夾中即可,這樣就無需頻繁的燒寫 EMMC
可以通過 nfs或者 tftp從 Ubuntu中下載 zImage和設(shè)備樹文件,本文使用 tftp從 Ubuntu中下載 zImage和設(shè)備樹文件,默認(rèn)已經(jīng)將 zImage和設(shè)備樹文件放到 Ubuntu下的 tftp目錄中
設(shè)置 bootargs 和 bootcmd 這兩個環(huán)境變量
setenv bootargs 'console=ttymxc0,115200 root=/dev/mmcblk1p2 rootwait rw'
setenv bootcmd 'tftp 80800000 zImage; tftp 83000000 imx6ull-andyxi-emmc.dtb; bootz
80800000 - 83000000'
saveenv
輸入“boot”命令,啟動內(nèi)核,下圖結(jié)果表示內(nèi)核啟動成功
4.U-Boot移植總結(jié)
uboot 移植到此結(jié)束,簡單總結(jié)一下 uboot 移植的過程:
- 不管是購買的還是自己做的開發(fā)板,基本都是參考半導(dǎo)體廠商的 dmeo板,半導(dǎo)體廠商會在他們的開發(fā)板上移植好 uboot、kernel和 rootfs等,最終制作好 BSP包提供給用戶。 我們可在官方提供的 BSP包的基礎(chǔ)上添加自已的板子,即俗稱的移植
- 購買的或者自己做的開發(fā)板一般不會原封不動的照抄半導(dǎo)體廠商的 demo板,都會根據(jù)實際情況來做修改,有修改就會涉及到 uboot下驅(qū)動的移植
- 一般 uboot中需要解決串口、NAND、EMMC或 SD卡、網(wǎng)絡(luò)和 LCD動,因為 uboot的主要目的是啟動 Linux內(nèi)核,所以不用考慮太多的外設(shè)驅(qū)動
- 在 uboot中添加自己的開發(fā)板信息,并根據(jù)實際情況來修改 uboot中的驅(qū)動
-
NXP
+關(guān)注
關(guān)注
61文章
1348瀏覽量
189365 -
lcd
+關(guān)注
關(guān)注
34文章
4520瀏覽量
171542 -
Linux
+關(guān)注
關(guān)注
87文章
11511瀏覽量
213790 -
u-boot
+關(guān)注
關(guān)注
0文章
122瀏覽量
38833 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5680瀏覽量
104704
發(fā)布評論請先 登錄
U-boot的基本介紹

U-Boot的啟動及移植分析
Porting U-Boot to the Control
一種在U-BOOT中嵌入千兆網(wǎng)絡(luò)功能的方法
u-boot的Makefile分析
基于S3C2440的U-Boot開機(jī)logo的設(shè)計

u-boot簡介
深度解析U-Boot網(wǎng)絡(luò)實現(xiàn)

U-Boot架構(gòu)淺析

在u-boot中使用ethernet的方法
在Vitis中調(diào)試ARM可信固件和U-boot

U-boot的QSPI驅(qū)動移植方法及驗證方法

U-boot的MMC DM框架驅(qū)動的移植方法

評論