Chinaunix首页 | 论坛 | 博客
  • 博客访问: 144027
  • 博文数量: 29
  • 博客积分: 717
  • 博客等级: 上士
  • 技术积分: 352
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-16 16:17
文章分类

全部博文(29)

文章存档

2013年(4)

2012年(4)

2011年(21)

我的朋友

分类: LINUX

2011-05-17 20:53:59

在uboot第一阶段引导的最后一步做了一下代码
  1. ldr pc, _start_armboot
  2. 33f800f0: e51ff004 ldr pc, [pc, #-4] ; 33f800f4 <_start_armboot>
  3. 33f800f4 <_start_armboot>:
  4. 33f800f4: 33f80be0 mvnccs r0, #229376 ; 0x38000
该指令是把当前指令地址+4的内存地址的值赋值为PC,PC=0x33f80be0;
第一阶段的代码是地址无关代码,但是现在PC却指向了0x33f80be0处,此处的代码在uboot(1.1.6)的根目录下/lib_arm/board.c中的start_armboot函数,主要是一些初始化。其中关系到两个数据结构
  1. typedef struct global_data {
  2. bd_t *bd;
  3. unsigned long flags;
  4. unsigned long baudrate;
  5. unsigned long have_console; /* serial_init() was called */
  6. unsigned long reloc_off; /* Relocation Offset */
  7. unsigned long env_addr; /* Address of Environment struct */
  8. unsigned long env_valid; /* Checksum of Environment valid? */
  9. unsigned long fb_base; /* base address of frame buffer */
  10. #ifdef CONFIG_VFD
  11. unsigned char vfd_type; /* display type */
  12. #endif
  13. void **jt; /* jump table */
  14. } gd_t;
 #define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8")
gd指针的值存放在r8寄存器里,register是将gd指针和r8绑定在一起,volatile关键字的意思是每次使用该变量时都直接存取原始地址,和内核中的task_struct结构中的state变量一样
  1. typedef struct bd_info {
  2. int bi_baudrate; /* serial console baudrate */
  3. unsigned long bi_ip_addr; /* IP Address */
  4. unsigned char bi_enetaddr[6]; /* Ethernet adress */
  5. struct environment_s *bi_env;
  6. ulong bi_arch_number; /* unique id for this board */
  7. ulong bi_boot_params; /* where this board expects params */
  8. struct /* RAM configuration */
  9. {
  10. ulong start;
  11. ulong size;
  12. } bi_dram[CONFIG_NR_DRAM_BANKS];

  13. #ifdef CONFIG_HAS_ETH1
  14. /* second onboard ethernet port */
  15. unsigned char bi_enet1addr[6];
  16. #endif
  17. } bd_t;
在start_armboot函数里先是gd的初始化然后再进行系统初始化,在2011.03版本中这两部分的初始化是放在两个函数里,而且gd的初始化是在relocate_code之前进行的。
gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
从这里可以发现gd的数据在内存里存放的地址是位于uboot代码和malloc区域的上方,由于传统栈的生长方向满递减,所以gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
接下来是把初始化队列里的函数按顺序执行下来,如果执行错误,则执行hang(),实际是死循环。
接着是flash的初始化,
malloc区域的初始化,
uboot的环境的初始化先是在malloc区域申请指定大小的内存,再是初始化,并设置好gd结构里相应的标志位,和该区域的地址,
  1. #ifdef ENV_IS_EMBEDDED
  2. /*
  3. * The environment buffer is embedded with the text segment,
  4. * just relocate the environment pointer
  5. */
  6. env_ptr = (env_t *)((ulong)env_ptr + gd->reloc_off);
  7. DEBUGF ("%s[%d] embedded ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
  8. #else
  9. /*
  10. * We must allocate a buffer for the environment
  11. */
  12. env_ptr = (env_t *)malloc (CFG_ENV_SIZE);
  13. DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
  14. #endif
  15. ......
  16. ......
  17. memset (env_ptr, 0, sizeof(env_t));
  18. memcpy (env_ptr->data,
  19. .....
  20. gd->env_valid = 1;
  21. ......
  22. gd->env_addr = (ulong)&(env_ptr->data);
ip地址的配置并将地址放到gd结构里等网卡的初始化时再去读取,
初始化板子上有的设备,例如usb,keyboard,lcd等,
  1. /* Initialize the list */
  2. devlist = ListCreate (sizeof (device_t));
  3. if (devlist == NULL) {
  4. eputs ("Cannot initialize the list of devices!\n");
  5. return -1;
  6. }
  7. #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
  8. i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
  9. #endif
  10. ......
  11. ......
  12. return (0);
填充jumptable里的数据
  1. gd->jt[XF_get_version] = (void *) get_version;
  2. gd->jt[XF_malloc] = (void *) malloc;
  3. gd->jt[XF_free] = (void *) free;
  4. gd->jt[XF_getenv] = (void *) getenv;
  5. gd->jt[XF_setenv] = (void *) setenv;
  6. gd->jt[XF_get_timer] = (void *) get_timer;
  7. gd->jt[XF_simple_strtoul] = (void *) simple_strtoul;
  8. gd->jt[XF_udelay] = (void *) udelay;
  9. #if defined(CONFIG_I386) || defined(CONFIG_PPC)
  10. gd->jt[XF_install_hdlr] = (void *) irq_install_handler;
  11. gd->jt[XF_free_hdlr] = (void *) irq_free_handler;
  12. #endif /* I386 || PPC */
  13. #if (CONFIG_COMMANDS & CFG_CMD_I2C)
  14. gd->jt[XF_i2c_write] = (void *) i2c_write;
  15. gd->jt[XF_i2c_read] = (void *) i2c_read;
  16. #endif /* CFG_CMD_I2C */
再就是控制台的初始化,开启中断,初始化相应的网卡,最后进入了main_loop。




阅读(1424) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~