为uboot添加网卡功能能够让uboot经过tftp下载内核, 方便咱们的开发, 对于网卡功能的移植,咱们依然在在一遍又一遍的实践这个uboot改造的套路。网络
为了实现ping、tftp下载、nfs挂载等功能,必须将uboot的网卡功能配置上,这个功能属于板级功能,
看README+经验+样板架构
须要在相应板级目录的xxx.c中配置,因此咱们找到了"board/samsung/xboot/xboot.c",这个文件的入口是board_init(),即1.找到了运行逻辑。dom
24 /* 25 * netdev.h - definitions an prototypes for network devices 26 */ 31 /* 32 * Board and CPU-specific initialization functions 33 * board_eth_init() has highest priority. cpu_eth_init() only 34 * gets called if board_eth_init() isn't instantiated or fails. 35 * Return values: 36 * 0: success 37 * -1: failure 38 */ 39 40 int board_eth_init(bd_t *bis); 41 int cpu_eth_init(bd_t *bis); 56 int dm9000_initialize(bd_t *bis);
//doc/README.drivers.eth 17 ---------- 18 Register 19 ---------- 20 21 When U-Boot initializes, it will call the common function eth_initialize(). 22 This will in turn call the board-specific board_eth_init() (or if that fails, 23 the cpu-specific cpu_eth_init()). These board-specific functions can do random 24 system handling, but ultimately they will call the driver-specific register 25 function which in turn takes care of initializing that particular instance. 26 27 Keep in mind that you should code the driver to avoid storing state in global 28 data as someone might want to hook up two of the same devices to one board. 29 Any such information that is specific to an interface should be stored in a 30 private, driver-defined data structure and pointed to by eth->priv (see below). 31 32 So the call graph at this stage would look something like: 33 board_init() 34 eth_initialize() 35 board_eth_init() / cpu_eth_init() 36 driver_register() 37 initialize eth_device 38 eth_register() 39
接下来就须要根据网卡手册进行配置,显然,写的都是裸板代码,这里,咱们的dm9000网卡的配置代码以下,此为2.根据运行逻辑编写相应的代码。this
31 struct exynos4_gpio_part2 *gpio2; 32 #ifdef CONFIG_DRIVER_DM9000 33 #define EXYNOS4412_SROMC_BASE 0X12570000 34 #define DM9000_Tacs (0x1) 35 #define DM9000_Tcos (0x1) 36 #define DM9000_Tacc (0x5) 37 #define DM9000_Tcoh (0x1) 38 #define DM9000_Tah (0xC) 39 #define DM9000_Tacp (0x9) 40 #define DM9000_PMC (0x1) 41 struct exynos_sromc { 42 unsigned int bw; 43 unsigned int bc[6]; 44 }; 45 /* 46 * s5p_config_sromc() - select the proper SROMC Bank and configure the 47 * band width control and bank control registers 48 * srom_bank - SROM 49 * srom_bw_conf - SMC Band witdh reg configuration value 50 * srom_bc_conf - SMC Bank Control reg configuration value 51 */ 52 void exynos_config_sromc(u32 srom_bank, u32 srom_bw_conf, u32 srom_bc_conf) 53 { 54 unsigned int tmp; 55 struct exynos_sromc *srom = (struct exynos_sromc *)(EXYNOS4412_SROMC_BASE); 56 /* Configure SMC_BW register to handle proper SROMC bank */ 57 tmp = srom->bw; 58 tmp&= ~(0xF << (srom_bank * 4)); 59 tmp |= srom_bw_conf; 60 srom->bw = tmp; 61 /* Configure SMC_BC register */ 62 srom->bc[srom_bank] = srom_bc_conf; 63 } 64 static void dm9000aep_pre_init(void) 65 { 66 unsigned int tmp; 67 unsigned char smc_bank_num = 1; 68 unsigned int 69 smc_bw_conf=0; 70 unsigned int 71 smc_bc_conf=0; 72 /* gpio configuration */ 73 writel(0x00220020, 0x11000000 + 0x120); 74 writel(0x00002222, 0x11000000 + 0x140); 75 /* 16 Bit bus width */ 76 writel(0x22222222, 0x11000000 + 0x180); 77 writel(0x0000FFFF, 0x11000000 + 0x188); 78 writel(0x22222222, 0x11000000 + 0x1C0); 79 writel(0x0000FFFF, 0x11000000 + 0x1C8); 80 writel(0x22222222, 0x11000000 + 0x1E0); 81 writel(0x0000FFFF, 0x11000000 + 0x1E8); 82 smc_bw_conf &= ~(0xf<<4); 83 smc_bw_conf |= (1<<7) | (1<<6) | (1<<5) | (1<<4); 84 smc_bc_conf = ((DM9000_Tacs << 28) 85 | (DM9000_Tcos << 24) 86 | (DM9000_Tacc << 16) 87 | (DM9000_Tcoh << 12) 88 | (DM9000_Tah << 8) 89 | (DM9000_Tacp << 4) 90 | (DM9000_PMC)); 91 exynos_config_sromc(smc_bank_num,smc_bw_conf,smc_bc_conf); 92 } 93 #endif 94 95 int board_init(void)
100 gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100UL); 101 #ifdef CONFIG_DRIVER_DM9000 102 dm9000aep_pre_init(); 103 #endif 104 return 0;
174 #endif 175 #ifdef CONFIG_CMD_NET 176 int board_eth_init(bd_t *bis) 177 { 178 179 int rc = 0; 180 #ifdef CONFIG_DRIVER_DM9000 181 rc = dm9000_initialize(bis); 182 #endif 183 return rc; 184 } 185 #endif
将网卡代码编写好以后,咱们来分析uboot的配置逻辑,这部分的大部份内容我已经在一文中进行了介绍,这里仅介绍和网卡相关的配置文件。和通用的配置文件同样,咱们首先须要将
在相关配置文件中添加网络支持,一文中已经介绍了uboot的配置原理,make config最后生成的结果文件是"include/configs/xxx.h",里面以宏的形式对板子的功能进行了配置,咱们这里须要的文件是"include/configs/xboot.h"。
咱们只须要打开或关闭相应的宏,就能够完成对某一功能的配置prototype
咱们主要的工做就是在头文件中打开相应的宏开关,虽然不使用这种宏开关的方式也能够将功能添加成功,可是移植的一个重要原则就是尊重原架构,这对后期维护和代码重用都颇有好处。code
85 #define CONFIG_CMD_PING //#undef CONFIG_CMD_PING
90 #define CONFIG_CMD_NET //#undef CONFIG_CMD_NET
155 /* Enable devicetree support */ 156 #define CONFIG_OF_LIBFDT 157 158 #ifdef CONFIG_CMD_NET 159 #define CONFIG_NET_MULTI 160 #define CONFIG_DRIVER_DM9000 1 161 #define CONFIG_DM9000_BASE 0x05000000 162 #define DM9000_IO CONFIG_DM9000_BASE 163 #define DM9000_DATA (CONFIG_DM9000_BASE + 4) 164 #define CONFIG_DM9000_USE_16BIT 165 #define CONFIG_DM9000_NO_SROM 1 166 #define CONFIG_ETHADDR 11:22:33:44:55:66 167 #define CONFIG_IPADDR 192.168.9.200 168 #define CONFIG_SERVERIP 192.168.9.120 169 #define CONFIG_GATEWAYIP 192.168.9.1 170 #define CONFIG_NETMASK 255.255.255.0 171 #endif 172 173 #endif /* __CONFIG_H */
最终的结果以下, 咱们能够看到dm9000已经启动了orm
也能够正常的加载并启动内核
blog