觀察上次移植的uboot的序列槽輸出:
U-Boot 2017.11 (Jan 07 2018 - 11:50:48 +0800)
CPU: Freescale i.MX6Q rev1.5 at 792 MHz
Reset cause: POR
Board: MX6Q-Armadillo2
DRAM: 2 GiB
MMC: FSL_SDHC: 0, FSL_SDHC: 1
In: serial
Out: serial
Err: serial
Net: FEC
Error: FEC address not set.
Hit any key to stop autoboot: 0
=>
有一個錯誤提示:Error: FEC address not set.
這個錯誤是情理之中的因為我們的網絡驅動還沒有移植。
下面進行相關修改移植:
根據錯誤提示搜尋:grep "address not set" ./* -rn
./net/eth_legacy.c:163: printf("\nError: %s address not set.\n",
找到在我們編譯進uboot中的這個檔案有這個輸出,然後我們打開這個檔案:vim ./net/eth_legacy.c +163
發現是在下面這個函數裡面輸出的這個錯誤資訊。
int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
int eth_number)
{
unsigned char env_enetaddr[ARP_HLEN];
int ret = 0;
eth_env_get_enetaddr_by_index(base_name, eth_number, env_enetaddr);
if (!is_zero_ethaddr(env_enetaddr)) {
if (!is_zero_ethaddr(dev->enetaddr) &&
memcmp(dev->enetaddr, env_enetaddr, ARP_HLEN)) {
printf("\nWarning: %s MAC addresses don't match:\n",
dev->name);
printf("Address in SROM is %pM\n",
dev->enetaddr);
printf("Address in environment is %pM\n",
env_enetaddr);
}
memcpy(dev->enetaddr, env_enetaddr, ARP_HLEN);
} else if (is_valid_ethaddr(dev->enetaddr)) {
eth_env_set_enetaddr_by_index(base_name, eth_number,
dev->enetaddr);
} else if (is_zero_ethaddr(dev->enetaddr)) {
#ifdef CONFIG_NET_RANDOM_ETHADDR
net_random_ethaddr(dev->enetaddr);
printf("\nWarning: %s (eth%d) using random MAC address - %pM\n",
dev->name, eth_number, dev->enetaddr);
#else
printf("\nError: %s address not set.\n",
dev->name);
return -EINVAL;
#endif
}
if (dev->write_hwaddr && !eth_mac_skip(eth_number)) {
if (!is_valid_ethaddr(dev->enetaddr)) {
printf("\nError: %s address %pM illegal value\n",
dev->name, dev->enetaddr);
return -EINVAL;
}
ret = dev->write_hwaddr(dev);
if (ret)
printf("\nWarning: %s failed to set MAC address\n",
dev->name);
}
return ret;
}
在輸出錯誤提示資訊的函數裡面有個宏CONFIG_NET_RANDOM_ETHADDR,這個宏如果被定義就執行net_random_ethaddr(dev->enetaddr);
net_random_ethaddr這個函數會生成一個随機的位址儲存在dev->enetaddr中。是以就在配置的頭檔案中找一個合适位置
添加這個宏。
vim vim include/configs/mx6qarm2.h
#define CONFIG_NET_RANDOM_ETHADDR /*add by xcl*/
編譯:make
提示出錯:
net/built-in.o: In function `net_random_ethaddr':
/home/xcl/imx6q/uboot/u-boot-2017.11/include/net.h:818: undefined reference to `rand_r'
發現提示rand_r這個函數沒有實作。
查找改函數:grep "rand_r" -rn
發現:lib/rand.c:15:unsigned int rand_r(unsigned int *seedp)
檢視:ls lib/rand.*
發現隻有lib/rand.c,rand.c沒有被編譯,
檢視Makefile:vim lib/Makefile
發現:obj-$(CONFIG_LIB_RAND) += rand.o
說明需要定義CONFIG_LIB_RAND這個宏rand.c才能被編譯,是以就在配置的頭檔案中找一個合适位置
添加這個宏。
vim vim include/configs/mx6qarm2.h
#define CONFIG_LIB_RAND /*add by xcl*/
編譯下載下傳重新開機序列槽輸出:
U-Boot 2017.11 (Jan 08 2018 - 21:22:25 +0800)
CPU: Freescale i.MX6Q rev1.5 at 792 MHz
Reset cause: POR
Board: MX6Q-Armadillo2
DRAM: 2 GiB
MMC: FSL_SDHC: 0, FSL_SDHC: 1
In: serial
Out: serial
Err: serial
Net: FEC
Warning: FEC (eth0) using random MAC address - 5a:b7:8b:df:73:11
Hit any key to stop autoboot: 0
這個時候發現生成了随機的mac位址,為了試一試網卡驅動能用不,輸入指令:
=> setenv ipaddr 192.168.0.200
=> setenv serverip 192.168.0.106
=> saveenv
Saving Environment to MMC...
Writing to MMC(0)... done
=> ping 192.168.0.106
Using FEC device
host 192.168.0.106 is alive
=> ping 192.168.0.107
Using FEC device
ARP Retry count exceeded; starting again
ping failed; host 192.168.0.107 is not alive
=> tftp 12000000 a.bin
Using FEC device
TFTP from server 192.168.0.106; our IP address is 192.168.0.200
Filename 'a.bin'.
Load address: 0x12000000
Loading: ######################
455.1 KiB/s
done
Bytes transferred = 319135 (4de9f hex)
=>
哇卡!!!!!!貌似能用
雖然這兒感覺能ping通,能夠下載下傳,但是還是去檢查和修改一下初始化網卡的流程。
vim common/board_f.c
static const init_fnc_t init_sequence_f[]數組裡面的board_early_init_f函數。
該函數位置:board/freescale/mx6qarm2/mx6qarm2.c
源代碼為:
int board_early_init_f(void)
{
setup_iomux_uart();
setup_iomux_enet();
return 0;
}
setup_iomux_enet函數代碼:
static void setup_iomux_enet(void)
{
imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
}
追蹤enet_pads到:
iomux_v3_cfg_t const enet_pads[] = {
MX6_PAD_KEY_COL1__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_KEY_COL2__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
};
發現我們參考的這個闆和我們的闆引腳連結方式一大部分都是相同的,雖然
上面測試貌似能用但是還是參照原理圖(下圖)去把有差異的引腳修改一下。
修改後:
/* modefied by xcl */
iomux_v3_cfg_t const enet_pads[] = {
MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET_RXD1__GPIO1_IO26 | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_ENET_CRS_DV__GPIO1_IO25 | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
};
配置了複用引腳,然後将ar8035收發器複位友善後期的使用,是以添加函數:
/* add by xcl */
static void reset_ar8035(void)
{
volatile unsigned int i = 0x88888;
unsigned int reg = *((unsigned int*)(GPIO1_BASE_ADDR + 0x04));
reg |= ~0x2000000;
*((unsigned int*)(GPIO1_BASE_ADDR + 0x04)) = reg;
reg = *((unsigned int*)(GPIO1_BASE_ADDR + 0x00));
reg &= ~0x2000000;
*((unsigned int*)(GPIO1_BASE_ADDR + 0x00)) = reg;
while(i--)
;
reg = *((unsigned int*)(GPIO1_BASE_ADDR + 0x00));
reg |= ~0x2000000;
*((unsigned int*)(GPIO1_BASE_ADDR + 0x00)) = reg;
}
在board_early_init_f函數中調用。
/* modefied by xcl */
int board_early_init_f(void)
{
setup_iomux_uart();
setup_iomux_enet();
reset_ar8035();
return 0;
}
最後編譯下載下傳重新開機測試......
測試通過就算移植完成。