從0移植uboot(六) _實現網絡功能

爲uboot添加網卡功能能夠讓uboot經過tftp下載內核, 方便咱們的開發, 對於網卡功能的移植,咱們依然在在一遍又一遍的實踐這個uboot改造的套路。網絡

  1. 找運行邏輯,即插入代碼的位置。
  2. 根據運行邏輯編寫功能代碼。
  3. 找配置邏輯,即修改哪些文件使配置生效。
  4. 根據配置邏輯修改配置使功能代碼生效。
  5. 從新編譯燒寫uboot。

1. 找運行邏輯

爲了實現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

2. 編寫功能代碼

接下來就須要根據網卡手冊進行配置,顯然,寫的都是裸板代碼,這裏,咱們的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

3. 找配置邏輯

將網卡代碼編寫好以後,咱們來分析uboot的配置邏輯,這部分的大部份內容我已經在一文中進行了介紹,這裏僅介紹和網卡相關的配置文件。和通用的配置文件同樣,咱們首先須要將
在相關配置文件中添加網絡支持,一文中已經介紹了uboot的配置原理,make config最後生成的結果文件是"include/configs/xxx.h",裏面以宏的形式對板子的功能進行了配置,咱們這裏須要的文件是"include/configs/xboot.h"
咱們只須要打開或關閉相應的宏,就能夠完成對某一功能的配置prototype

4. 修改配置

咱們主要的工做就是在頭文件中打開相應的宏開關,雖然不使用這種宏開關的方式也能夠將功能添加成功,可是移植的一個重要原則就是尊重原架構,這對後期維護和代碼重用都頗有好處。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 */

5. 從新編譯and燒寫

最終的結果以下, 咱們能夠看到dm9000已經啓動了orm

也能夠正常的加載並啓動內核
blog

相關文章
相關標籤/搜索