1.在U-Boot中驅(qū)動(dòng)LCD和網(wǎng)絡(luò)
在U-Boot 移植初探一文中介紹了如何修改 NXP官方uboot,使得 uboot能匹配我們自己的開發(fā)板,但是匹配完成后 LCD驅(qū)動(dòng)和網(wǎng)絡(luò)驅(qū)動(dòng)還是不正常的,所以下面將介紹如何修改 LCD驅(qū)動(dòng)和網(wǎng)絡(luò)驅(qū)動(dòng)等
1.1 LCD驅(qū)動(dòng)修改
uboot 中修改驅(qū)動(dòng)都是在對(duì)應(yīng)板子的 .c文件和 .h文件中進(jìn)行,即下面兩個(gè)文件中:mx6ull_andyxi_emmc.c 和 mx6ull_andyxi_emmc.h
修改 LCD驅(qū)動(dòng)重點(diǎn)注意以下幾點(diǎn):
- 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)容 ###############################*/
/*該代碼定義了一個(gè)變量displays,類型為display_info_t,這個(gè)結(jié)構(gòu)體
是LCD信息結(jié)構(gòu)體,其中包括了LCD的分辨率,像素格式,LCD的各個(gè)參數(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ù)具體使用型號(hào)修改
重新編譯 uboot并燒寫到 SD中啟動(dòng)后,若 LCD仍不能顯示,則需要在uboot命令模式下,檢查環(huán)境變量 panel的值,確保與 LCD參數(shù)里的 name一致
panel=TFT7016 #與mx6ull_andyxi_emmc.c中修改的名稱保持一致
1.2 網(wǎng)絡(luò)驅(qū)動(dòng)修改
I.MX6UL/ULL 內(nèi)部有個(gè)以太網(wǎng) MAC外設(shè),需要外接一個(gè) PHY芯片來實(shí)現(xiàn)網(wǎng)絡(luò)通信功能。 我們使用的 I.MX6U 開發(fā)板提供了這兩個(gè)網(wǎng)絡(luò)接口,都使用 LAN8720A 作為 PHY 芯片。 NXP 官方的I.MX6ULL EVK 開發(fā)板使用 KSZ8081 的 PHY 芯片。 下面將介紹更換了PHY 芯片以后如何調(diào)整網(wǎng)絡(luò)驅(qū)動(dòng),使網(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ū)動(dòng)重點(diǎn)注意以下幾點(diǎn):
- LAN8720A復(fù)位引腳初始化
- LAN8720A的器件ID
- LAN8720A驅(qū)動(dòng)
在 mx6ull_andyxi_emmc.c中添加復(fù)位引腳驅(qū)動(dòng)
/* 結(jié)構(gòu)體數(shù)組fec1_pads和fec2_pads是ENET1和ENET2這兩個(gè)網(wǎng)口的IO
* 配置參數(shù),在這兩個(gè)數(shù)組中添加兩個(gè)網(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 這兩個(gè)網(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ū)動(dòng)
/*######### 原始內(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 //用于選擇使用哪個(gè)網(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ū)動(dòng)(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ū)動(dòng)(LAN8720A是SMSC生產(chǎn)的)
#endif
在 mx6ull_andyxi_emmc.c中刪除 74LV595的驅(qū)動(dòng)代碼
/* NXP 官方I.MX6ULL EVK 開發(fā)板使用74LV595來擴(kuò)展 IO,兩個(gè)網(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 上,對(duì)應(yīng) GPIO5_IO07
* ENET2 的復(fù)位引腳連接到 SNVS_TAMPER8 上,對(duì)應(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才會(huì)執(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ū)動(dòng)修改完成,重新編譯 uboot,然后將 u-boot.bin 燒寫到 SD 卡中并啟動(dòng),uboot 啟動(dòng)信息如下圖所示:
由上圖可見當(dāng)前使用FEC1這個(gè)網(wǎng)口(ENET2),但此時(shí)網(wǎng)絡(luò)地址還沒有設(shè)置。 在uboot使用網(wǎng)絡(luò)之前還要先設(shè)置以下幾個(gè)網(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ā)板和電腦在同一個(gè)網(wǎng)段內(nèi),通過 ping 命令來測(cè)試網(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 卡中重啟,按以上步驟可以測(cè)試 ENET1 的網(wǎng)絡(luò)是否正常工作
1.3 其他修改
在 uboot啟動(dòng)信息中會(huì)有“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 卡中驗(yàn)證,uboot 啟動(dòng)信息如下圖,可見名字已經(jīng)修改過來了
2.bootcmd和bootargs環(huán)境變量
uboot 中有兩個(gè)非常重要的環(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 倒計(jì)時(shí)結(jié)束后就會(huì)執(zhí)行其中的命令。 一般是用來啟動(dòng)內(nèi)核的,比如讀取 EMMC或 NAND Flash中的內(nèi)核鏡像文件和設(shè)備樹文件到 DRAM中,然后啟動(dòng)內(nèi)核
可在 uboot啟動(dòng)后進(jìn)入命令行設(shè)置 bootcmd環(huán)境變量的值。 如果 EMMC或者 NAND中沒有保存 bootcmd的值,那么 uboot就會(huì)使用默認(rèn)值,板子第一次運(yùn)行 uboot 時(shí)都會(huì)使用默認(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,因?yàn)?linux啟動(dòng)以后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è)備初始化完成以后再掛載,否則的話會(huì)出錯(cuò)
// rw 表示根文件系統(tǒng)是可以讀寫的,不加rw的話可能只能讀而無法進(jìn)行寫操作
- rootfstype:一般與root一起使用, 用于指定根文件系統(tǒng)類型,如果根文件系統(tǒng)為ext 格式的話此選項(xiàng)無所謂。 如果根文件系統(tǒng)是 yaffs、 jffs 或 ubifs 的話就需要設(shè)置此選項(xiàng),指定根文件系統(tǒng)的類型
3.U-Boot啟動(dòng)Linux測(cè)試
uboot 已經(jīng)移植好后,就要測(cè)試一下 uboot 能不能完成它的工作:?jiǎn)?dòng) Linux 內(nèi)核。 這里測(cè)試兩種啟動(dòng) Linux 內(nèi)核的方法,一種是直接從 EMMC 啟動(dòng),一種是從網(wǎng)絡(luò)啟動(dòng)
3.1 從EMMC啟動(dòng)Linux
從 EMMC 啟動(dòng)也就是將編譯出來的 Linux 鏡像文件 zImage 和設(shè)備樹文件保存在 EMMC中, uboot 從 EMMC 中讀取這兩個(gè)文件并啟動(dòng),這個(gè)是產(chǎn)品最終的啟動(dòng)方式。 此處默認(rèn)已經(jīng)將 zImage 文件和設(shè)備樹文件燒寫到了 EMMC 中,可以直接讀取來進(jìn)行測(cè)試
使用命令“l(fā)s mmc 1:1”檢查 EMMC 的分區(qū) 1 中是否已有相關(guān)文件,下圖結(jié)果表示已有相關(guān)文件
設(shè)置 bootargs 和 bootcmd 這兩個(gè)環(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”命令,啟動(dòng)內(nèi)核即可
3.2 從網(wǎng)絡(luò)啟動(dòng)Linux
從網(wǎng)絡(luò)啟動(dòng) linux系統(tǒng)的唯一目的就是為了調(diào)試! 不管是為了調(diào)試 linux系統(tǒng)還是 linux下的驅(qū)動(dòng),每次修改 linux系統(tǒng)文件或者 linux下的某個(gè)驅(qū)動(dòng)后都要將其燒寫到 EMMC 中去測(cè)試,這樣太麻煩了。 可以設(shè)置從網(wǎng)絡(luò)啟動(dòng),將 linux鏡像文件和根文件系統(tǒng)都放到 Ubuntu下指定的文件夾中,這樣每次重新編譯 linux內(nèi)核或者 linux驅(qū)動(dòng)后只需要將其拷貝到這個(gè)指定的文件夾中即可,這樣就無需頻繁的燒寫 EMMC
可以通過 nfs或者 tftp從 Ubuntu中下載 zImage和設(shè)備樹文件,本文使用 tftp從 Ubuntu中下載 zImage和設(shè)備樹文件,默認(rèn)已經(jīng)將 zImage和設(shè)備樹文件放到 Ubuntu下的 tftp目錄中
設(shè)置 bootargs 和 bootcmd 這兩個(gè)環(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”命令,啟動(dòng)內(nèi)核,下圖結(jié)果表示內(nèi)核啟動(dòng)成功
4.U-Boot移植總結(jié)
uboot 移植到此結(jié)束,簡(jiǎn)單總結(jié)一下 uboot 移植的過程:
- 不管是購(gòu)買的還是自己做的開發(fā)板,基本都是參考半導(dǎo)體廠商的 dmeo板,半導(dǎo)體廠商會(huì)在他們的開發(fā)板上移植好 uboot、kernel和 rootfs等,最終制作好 BSP包提供給用戶。 我們可在官方提供的 BSP包的基礎(chǔ)上添加自已的板子,即俗稱的移植
- 購(gòu)買的或者自己做的開發(fā)板一般不會(huì)原封不動(dòng)的照抄半導(dǎo)體廠商的 demo板,都會(huì)根據(jù)實(shí)際情況來做修改,有修改就會(huì)涉及到 uboot下驅(qū)動(dòng)的移植
- 一般 uboot中需要解決串口、NAND、EMMC或 SD卡、網(wǎng)絡(luò)和 LCD動(dòng),因?yàn)?uboot的主要目的是啟動(dòng) Linux內(nèi)核,所以不用考慮太多的外設(shè)驅(qū)動(dòng)
- 在 uboot中添加自己的開發(fā)板信息,并根據(jù)實(shí)際情況來修改 uboot中的驅(qū)動(dòng)
-
NXP
+關(guān)注
關(guān)注
60文章
1289瀏覽量
185085 -
lcd
+關(guān)注
關(guān)注
34文章
4438瀏覽量
168115 -
Linux
+關(guān)注
關(guān)注
87文章
11342瀏覽量
210147 -
u-boot
+關(guān)注
關(guān)注
0文章
121瀏覽量
38288 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5121瀏覽量
97982
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論