上面算是把初始化的第一个阶段完成,下面还需要接着初始化
<lib_arm/board.c>
void start_armboot (void)
298
299 mem_malloc_init (_armboot_start - CONFIG_SYS_MALLOC_LEN,
300 CONFIG_SYS_MALLOC_LEN);
CONFIG_SYS_MALLOC_LEN = 192K
<common/dlmalloc.c>
1525 void mem_malloc_init(ulong start, ulong size)
1526 {
1527 mem_malloc_start = start;
1528 mem_malloc_end = start + size;
1529 mem_malloc_brk = start;
1531 memset((void *)mem_malloc_start, 0, size);
1532 }
将0x33f50000到0x33f80000这192K内存初始化,此后三个malloc相关的全局变量
mem_malloc_start = 0x33f50000
mem_malloc_end = 0x33f80000
mem_malloc_brk = 0x33f50000
<lib_arm/board.c>
350
351 env_relocate ();
<common/env_common.c>
225 void env_relocate (void)
226 {
246
249 env_ptr = (env_t *)malloc (CONFIG_ENV_SIZE);
250 DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
253 if (gd->env_valid == 0) {
257 puts ("*** Warning - bad CRC, using default environment\n\n");
258 show_boot_progress (-60);
260 set_default_env();
261 }
262 else {
263 env_relocate_spec ();
264 }
265 gd->env_addr = (ulong)&(env_ptr->data);
270 }
第249行分配64K内存用来存放env_t
第260行void set_default_env(void),采用默认环境变量
第263行<common/env_flash.c>
333 void env_relocate_spec (void)
334 {
335 #if !defined(ENV_IS_EMBEDDED) || defined(CONFIG_ENV_ADDR_REDUND)
336 #ifdef CONFIG_ENV_ADDR_REDUND
337 if (gd->env_addr != (ulong)&(flash_addr->data)) {
338 env_t * etmp = flash_addr;
339 ulong ltmp = end_addr;
341 flash_addr = flash_addr_new;
342 flash_addr_new = etmp;
344 end_addr = end_addr_new;
345 end_addr_new = ltmp;
346 }
348 if (flash_addr_new->flags != OBSOLETE_FLAG &&
349 crc32(0, flash_addr_new->data, ENV_SIZE) ==
350 flash_addr_new->crc) {
351 char flag = OBSOLETE_FLAG;
353 gd->env_valid = 2;
354 flash_sect_protect (0, (ulong)flash_addr_new, end_addr_new);
355 flash_write(&flag,
356 (ulong)&(flash_addr_new->flags),
357 sizeof(flash_addr_new->flags));
358 flash_sect_protect (1, (ulong)flash_addr_new, end_addr_new);
359 }
361 if (flash_addr->flags != ACTIVE_FLAG &&
362 (flash_addr->flags & ACTIVE_FLAG) == ACTIVE_FLAG) {
363 char flag = ACTIVE_FLAG;
365 gd->env_valid = 2;
366 flash_sect_protect (0, (ulong)flash_addr, end_addr);
367 flash_write(&flag,
368 (ulong)&(flash_addr->flags),
369 sizeof(flash_addr->flags));
370 flash_sect_protect (1, (ulong)flash_addr, end_addr);
371 }
373 if (gd->env_valid == 2)
374 puts ("*** Warning - some problems detected "
375 "reading environment; recovered successfully\n\n");
376 #endif
377 #ifdef CMD_SAVEENV
378 memcpy (env_ptr, (void*)flash_addr, CONFIG_ENV_SIZE);
379 #endif
380 #endif
381 }
没啥好说的,就是环境变量存在哪里
<lib_arm/board.c>
362
363 gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");
365 stdio_init ();
367 jumptable_init ();
第362行获取环境变量里面的ip地址
第365行<common/stdio.c>
202 int stdio_init (void)
203 {
216
217 INIT_LIST_HEAD(&(devs.list));
223 i2c_init (CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
232 drv_keyboard_init ();
237 drv_system_init ();
239 serial_stdio_init ();
242 drv_usbtty_init ();
245 drv_nc_init ();
248 drv_jtag_console_init ();
251 return (0);
252 }
第217行初始化链表头
struct stdio_dev {
int flags;
int ext;
char name[16];
int (*start) (void);
int (*stop) (void);
void (*putc) (const char c);
void (*puts) (const char *s);
int (*tstc) (void);
int (*getc) (void);
void *priv;
struct list_head list;
};
第237行
71 static void drv_system_init (void)
72 {
73 struct stdio_dev dev;
75 memset (&dev, 0, sizeof (dev));
77 strcpy (dev.name, "serial");
78 dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
85 dev.putc = serial_putc;
86 dev.puts = serial_puts;
87 dev.getc = serial_getc;
88 dev.tstc = serial_tstc;
91 stdio_register (&dev);
105 }
第91行<common/stdio.c>
151 int stdio_register (struct stdio_dev * dev)
152 {
153 struct stdio_dev *_dev;
155 _dev = stdio_clone(dev);
156 if(!_dev)
157 return -1;
158 list_add_tail(&(_dev->list), &(devs.list));
159 return 0;
160 }
133 struct stdio_dev* stdio_clone(struct stdio_dev *dev)
134 {
135 struct stdio_dev *_dev;
137 if(!dev)
138 return NULL;
140 _dev = calloc(1, sizeof(struct stdio_dev));
142 if(!_dev)
143 return NULL;
145 memcpy(_dev, dev, sizeof(struct stdio_dev));
146 strncpy(_dev->name, dev->name, 16);
148 return _dev;
149 }
先将dev复制到_dev,然后把_dev->list加入devs.list中
其他的都差不多,将设备通过函数stdio_register()加入devs.list中
<lib_arm/board.c>
374 console_init_r ();
385
386 enable_interrupts ();
408
409 if ((s = getenv ("loadaddr")) != NULL) {
410 load_addr = simple_strtoul (s, NULL, 16);
411 }
434 eth_initialize(gd->bd);
437 reset_phy();
440
441 for (;;) {
442 main_loop ();
443 }
445
446 }
第374行<common/console.c>
651 int console_init_r(void)
652 {
653 struct stdio_dev *inputdev = NULL, *outputdev = NULL;
654 int i;
655 struct list_head *list = stdio_get_list();
656 struct list_head *pos;
657 struct stdio_dev *dev;
672
673 list_for_each(pos, list) {
674 dev = list_entry(pos, struct stdio_dev, list);
676 if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) {
677 inputdev = dev;
678 }
679 if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) {
680 outputdev = dev;
681 }
682 if(inputdev && outputdev)
683 break;
684 }
686
687 if (outputdev != NULL) {
688 console_setfile(stdout, outputdev);
689 console_setfile(stderr, outputdev);
690 #ifdef CONFIG_CONSOLE_MUX
691 console_devices[stdout][0] = outputdev;
692 console_devices[stderr][0] = outputdev;
693 #endif
694 }
696
697 if (inputdev != NULL) {
698 console_setfile(stdin, inputdev);
699 #ifdef CONFIG_CONSOLE_MUX
700 console_devices[stdin][0] = inputdev;
701 #endif
702 }
704 gd->flags |= GD_FLG_DEVINIT;
706 stdio_print_current_devices();
708
709 for (i = 0; i < 3; i++) {
710 setenv(stdio_names[i], stdio_devices[i]->name);
711 }
719 return 0;
720 }
第655行,先获取dev->list链表
第673-684行,检查输入输出设备,由flag DEV_FLAGS_INPUT和DEV_FLAGS_OUTPUT标示
第686-701行,设定系统输入输出设备
第704行,表示设备初始化完成
第706-720行,将设置的结果保存到环境变量中
<lib_arm/board.c>
第386行调用enable_interrupts开中断
<lib_arm/interrupts.c>
55
56 void enable_interrupts (void)
57 {
58 unsigned long temp;
59 __asm__ __volatile__("mrs %0, cpsr\n"
60 "bic %0, %0, #0x80\n"
61 "msr cpsr_c, %0"
62 : "=r" (temp)
63 :
64 : "memory");
65 }
调整格式一下
mrs temp, cpsr
bic temp, temp, #0x80
msr cpsr_c, temp
arm的cpsr寄存器bit7和bit6分别管理中断和快速中断的使能和禁止
这里是将bit7置1,即使能中断
<lib_arm/board.c>
第409-411行
从环境变量中获取loadaddr的值
第434行
调用eth_initialize(gd->bd);
<net/eth.c>
186 int eth_initialize(bd_t *bis)
187 {
188 unsigned char env_enetaddr[6];
189 int eth_number = 0;
191 eth_devices = NULL;
192 eth_current = NULL;
194 show_boot_progress (64);
196 miiphy_init();
198
200 if (board_eth_init(bis) < 0)
201 cpu_eth_init(bis);
209 if (!eth_devices) {
210 puts ("No ethernet found.\n");
211 show_boot_progress (-64);
212 } else {
213 struct eth_device *dev = eth_devices;
214 char *ethprime = getenv ("ethprime");
216 show_boot_progress (65);
217 do {
218 if (eth_number)
219 puts (", ");
221 printf("%s", dev->name);
223 if (ethprime && strcmp (dev->name, ethprime) == 0) {
224 eth_current = dev;
225 puts (" [PRIME]");
226 }
228 eth_getenv_enetaddr_by_index(eth_number, env_enetaddr);
230 if (memcmp(env_enetaddr, "\0\0\0\0\0\0", 6)) {
231 if (memcmp(dev->enetaddr, "\0\0\0\0\0\0", 6) &&
232 memcmp(dev->enetaddr, env_enetaddr, 6))
233 {
234 printf ("\nWarning: %s MAC addresses don't match:\n",
235 dev->name);
236 printf ("Address in SROM is %pM\n",
237 dev->enetaddr);
238 printf ("Address in environment is %pM\n",
239 env_enetaddr);
240 }
242 memcpy(dev->enetaddr, env_enetaddr, 6);
243 }
245 eth_number++;
246 dev = dev->next;
247 } while(dev != eth_devices);
250
251 if (eth_current) {
252 char *act = getenv("ethact");
253 if (act == NULL || strcmp(act, eth_current->name) != 0)
254 setenv("ethact", eth_current->name);
255 } else
256 setenv("ethact", NULL);
256 setenv("ethact", NULL);
259 putc ('\n');
260 }
262 return eth_number;
263 }
<include/net.h>
95 struct eth_device {
96 char name[NAMESIZE];
97 unsigned char enetaddr[6];
98 int iobase;
99 int state;
101 int (*init) (struct eth_device*, bd_t*);
102 int (*send) (struct eth_device*, volatile void* packet, int length);
103 int (*recv) (struct eth_device*);
104 void (*halt) (struct eth_device*);
105 #ifdef CONFIG_MCAST_TFTP
106 int (*mcast) (struct eth_device*, u32 ip, u8 set);
107 #endif
108 struct eth_device *next;
109 void *priv;
110 };
结构体eth_device
第194行
show_boot_progress (64);
通过板子上的led灯显示系统boot到了那个步骤
第196行
初始化miiphy设备链表mii_devs
第200行
< board/sbc2410x/sbc2410x.c>
184 #ifdef CONFIG_CMD_NET
185 int board_eth_init(bd_t *bis)
186 {
187 int rc = 0;
188 #ifdef CONFIG_CS8900
189 rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
190 #endif
191 return rc;
192 }
193 #endif
传入参数struct bd_t
<drivers/net/cs8900.c>
304 int cs8900_initialize(u8 dev_num, int base_addr)
305 {
306 struct eth_device *dev;
307 struct cs8900_priv *priv;
309 dev = malloc(sizeof(*dev));
310 if (!dev) {
311 return 0;
312 }
313 memset(dev, 0, sizeof(*dev));
315 priv = malloc(sizeof(*priv));
316 if (!priv) {
317 free(dev);
318 return 0;
319 }
320 memset(priv, 0, sizeof(*priv));
321 priv->regs = (struct cs8900_regs *)base_addr;
323 dev->iobase = base_addr;
324 dev->priv = priv;
325 dev->init = cs8900_init;
326 dev->halt = cs8900_halt;
327 dev->send = cs8900_send;
328 dev->recv = cs8900_recv;
330
331 cs8900_get_enetaddr(dev);
333 sprintf(dev->name, "%s-%hu", CS8900_DRIVERNAME, dev_num);
335 eth_register(dev);
336 return 0;
337 }
传入参数:设备序号和设备寄存器基地址,前者从后面看是用来给设备命名用的
struct cs8900_priv {
struct cs8900_regs *regs;
};
结构体cs8900_priv就是cs8900寄存器列表指针
第321行
把传入参数设备寄存器基地址赋值给priv->regs
第323行-328行
初始化struct eth_device *dev结构体成员
第331行
132 void cs8900_get_enetaddr(struct eth_device *dev)
133 {
134 int i;
136
137 if (get_reg_init_bus(dev, PP_ChipID) != 0x630e)
138 return;
139 cs8900_reset(dev);
140 if ((get_reg(dev, PP_SelfSTAT) &
141 (PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) ==
142 (PP_SelfSTAT_EEPROM | PP_SelfSTAT_EEPROM_OK)) {
144
145 for (i = 0; i < 3; i++) {
146 u32 Addr;
148 Addr = get_reg(dev, PP_IA + i * 2);
149 dev->enetaddr[i * 2] = Addr & 0xFF;
150 dev->enetaddr[i * 2 + 1] = Addr >> 8;
151 }
152 }
153 }
传入参数struct eth_device *dev,就是要赋值dev->enetaddr成员
第137行
读取设备寄存器的设备id信息,看是否是cs8900的片子,这里面就用到了前面赋值的dev->priv->regs作为基地址
第139行
99 static void cs8900_reset(struct eth_device *dev)
100 {
101 int tmo;
102 u16 us;
104
105 put_reg(dev, PP_SelfCTL, get_reg(dev, PP_SelfCTL) | PP_SelfCTL_Reset);
107
108 udelay(200000);
109
111 tmo = get_timer(0) + 1 * CONFIG_SYS_HZ;
112 while ((((us = get_reg_init_bus(dev, PP_SelfSTAT)) &
113 PP_SelfSTAT_InitD) == 0) && tmo < get_timer(0))
114 ;
115 }
第105行
写网卡寄存器,实现reset功能
第108行
实现us延时,通过ARM中的时钟寄存器实现
第111-115行,等待一段时间,等待片子reset完成
第140-152行,从片子的eeprom中读取了mac地址
第333行,给设备赋值名字
第335行
<net/eth.c>
161 int eth_register(struct eth_device* dev)
162 {
163 struct eth_device *d;
165 if (!eth_devices) {
166 eth_current = eth_devices = dev;
167 #ifdef CONFIG_NET_MULTI
168
169 {
170 char *act = getenv("ethact");
171 if (act == NULL || strcmp(act, eth_current->name) != 0)
172 setenv("ethact", eth_current->name);
173 }
174 #endif
175 } else {
176 for (d=eth_devices; d->next!=eth_devices; d=d->next);
177 d->next = dev;
178 }
180 dev->state = ETH_STATE_INIT;
181 dev->next = eth_devices;
183 return 0;
184 }
如果eth_devices==NULL(表示还没有网络设备被初始化),运行eth_current = eth_devices = dev,后面讲eth设备链起来
将ethprime设为当前网络设备,再将所有网卡信息打印出来
<lib_arm/board.c>
第422行,进入main_loop(),不再回来。
原文见:http://blog.sina.com.cn/s/blog_559f6ffc0100mimg.html