×

uboot中C语言代码入口函数(start_armboot)

消耗积分:10 | 格式:rar | 大小:42 | 2010-03-13

分享资料个

uboot中C语言代码入口函数(start_armboot)的注释

uboot中C语言代码入口函数(start_armboot)的注释

 //打印BANK的相关信息
 display_dram_config,
 NULL, //用以标识列表数组的结束
};
//------------start_armboot--------------------
//功能: 完成uboot第二阶级的一系列的
//  硬件初始化工作, 然后转入main函数.
//备注: 该函数是C程序的入口函数,从汇编语
//  言跳转到此 .
//---------------------------------------------
void start_armboot (void)
{
    init_fnc_t **init_fnc_ptr; //init_fnc_t 是各初始化函数的数组
    char *s;
#ifndef CFG_NO_FLASH
    ulong size;
#endif
#if defined(CONFIG_VFD) || defined(CONFIG_LCD)
    unsigned long addr;
#endif
  /* Pointer is writable since we allocated a register for it
      gd_t: 定义在 /include/asm-arm/Global_data.h中,包含一些全局通用的变量.
    _armboot_start: 代码的起始地址,它定义在start.S中的前几行中,定义为 _start
   当系统第一次加电时,指令是从0x0地址开始执行的,所以此时的 _start值
   应为0x0;而当uboot经过代码重定位后,指令会从 _TEXT_BASE 处开始执行,
   此时的 _start值就成了 _TEXT_BASE的值.
   CFG_MALLOC_LEN: 在/include/configs/smdk2440.h中有定义,该变量表示供
   malloc函数使用的内存池空间,代码中定义值为:0x10000+128*1024
 |-------|<--- _armboot_start基址
 |  4    | 
 |-------|<--- malloc函数池基址
 |  3    |
 |-------|<--- (gd_t)gd(全局变量表)基址
 |  2    |
 |-------|<--- (bt_t)bd(板卡信息表)基址
 |  1    |
  -------
   4 就是为malloc函数预留的数据空间
   3 是全信息表gd的数据区
 2 是板卡信息表bd的数据区
 网上找了个图片,更能反应这个空间的分配关系:
 
 */
     //分配区域 3 给 gd ,gd是一个全局静态变量
    gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));

    /* compiler optimization barrier needed for GCC >= 3.4 */
    __asm__ __volatile__("": : :"memory");
 //把gd变量的内容填充为0 ,填充 3 区的数据为0 ,即初始化gd表.注意:这里并没有
 //初始化bd表,在gd表中的bd成员只是一个指针,因为对初始化的是个指针地址
    memset ((void*)gd, 0, sizeof (gd_t));
 /*
  bd_t 结构体在/include/asm-arm/U-boot.h中定义, 定义板子的一些信息,包括:
  波特率,IP地址, 以太网地址, 架构编码,启动参数 ,BANK的起始地址和大小等
 */
 //分配区域 2 给bd, bd的基址 = gd的基址 - bd的尺寸
    gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
 
 //把区域 2 填充为 0 ,即初始化 bd 表
    memset (gd->bd, 0, sizeof (bd_t));
 /*monitor_falsh_len定义在 /lib_arm/Board.c
 
 在bin文件中 BSS 段和 TEXT 段和 DATA 段存放的顺序同前向后依次是:
  TEXT(代码段 RO)    DATA(已初始化数据段 RW)   BSS(未初始化数据段 ZI)
 所以 _bss_start 的基址等于 TEXT的长度加上DATA的长度.
 即: _bss_start(BSS段基址) = 代码段长度+数据段长度
 
 BSS(Block Started by Symbol)段是未被初始化的数据段,是存放程序中
  未被初始化的全局变量的一块内存区域,初始化时应清零;该段只有
  名称和大小却没有值;该段不包含任何数据,只是简单的维护开始和
  结束的地址,以便内存区能在运行时被有效地清零,它在应用程序的
  映像文件(ARM中也即bin文件)中并不存在.
 text :代码段,是包含程序代码的段
 dat  :已经初始化的数据段,保存已经初始化的全局变量.
 
    在嵌入式系统中,bin文件(又称Image文件)中只包含text和data段,
  而bss段不在其中,它是由系统初始化为零.
    */
  //_armboot_start 在start.S中定义为_start,而_start为代码的起始地址
    //只包含 RO(TEXT) 和 RW(DATA) 段.重定位前的值为0x0,此时指向flash,
 //重定位后则指向RAM中的某一地址
 //由此可以知道:  _bss_start - _armboot_start 的值即是在第一阶段从
 //flash中重定位到RAM中的那部分代码的长度,也即可TEXT和DATA数据段,
 //这个值与start.S中的重定位那部分代码所计算的值是相等的
 //所以,monitor_flash_len表示从flash中搬来的代码的长度
    monitor_flash_len = _bss_start - _armboot_start;  //_bss_start 在u-boot.lds中定位
 
 //各设置的初始化.当返回值不为0时表示初始化失败 ,此时会调用 hang()函数
 //打印一错误提示信息,然后进入死循环
    for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
        if ((*init_fnc_ptr)() != 0) {
            hang ();
        }
    }
//CFG_NO_FLASH 表示没有flash,如果没定义该常量则表示板子上有flash,此时调用flash_init()对其进行初始化.
#ifndef CFG_NO_FLASH
    /* configure available FLASH banks */
    size = flash_init ();
    display_flash_config (size); //打印flash的信息,这里仅输出它的大小
#endif /* CFG_NO_FLASH */
#ifdef CONFIG_VFD
#   ifndef PAGE_SIZE
#     define PAGE_SIZE 4096
#   endif
     /*
      * reserve memory for VFD display (always full pages)
      */
    /* bss_end is defined in the board-specific linker script */
    addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1); //???
    size = vfd_setmem (addr);
    gd->fb_base = addr;
#endif /* CONFIG_VFD */
#ifdef CONFIG_LCD
# ifndef PAGE_SIZE
#   define PAGE_SIZE 4096
# endif
     /*
      * reserve memory for LCD display (always full pages)
      *///为LCD分配RAM(内存)空间
     /* bss_end is defined in the board-specific linker script */
    addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
    size = lcd_setmem (addr);
    gd->fb_base = addr; //为显存缓冲区地址变量赋值
#endif /* CONFIG_LCD */
 /* armboot_start is defined in the board-specific linker script */
 //malloc函数使用缓冲区的初始化
    mem_malloc_init (_armboot_start - CFG_MALLOC_LEN); 
//如果定义了命令和NAND命令,则初始化nand
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
    puts ("NAND:  ");
    nand_init();  /* go init the NAND */
#endif
#ifdef CONFIG_HAS_DATAFLASH
    AT91F_DataflashInit();
    dataflash_print_info();
#endif
     /* initialize environment 环境的初始化,代码在common\env_common.c中 */
    env_relocate ();
#ifdef CONFIG_VFD
     /* must do this after the framebuffer is allocated */
    drv_vfd_init();
#endif /* CONFIG_VFD */
     /* IP Address 为全局变量的成员赋值:IP地址*/
    gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");//ipaddr在smdk2440.h中的CONFIG_IPADDR中出现,应该是该常量
 /* MAC Address *///高处MAC地址 ,并赋给gd的成员变量
 {
    int i;
    ulong reg;
    char *s, *e;
    char tmp[64];
    i = getenv_r ("ethaddr", tmp, sizeof (tmp));
    s = (i > 0) ? tmp : NULL;
    for (reg = 0; reg < 6; ++reg) {
    gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
    if (s)
        s = (*e) ? e + 1 : e;
}
#ifdef CONFIG_HAS_ETH1
  i = getenv_r ("eth1addr", tmp, sizeof (tmp));
  s = (i > 0) ? tmp : NULL;
  for (reg = 0; reg < 6; ++reg) {
   gd->bd->bi_enet1addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
   if (s)
    s = (*e) ? e + 1 : e;
  }
#endif
 }
 //这个函数涉及好多,我没深入分析,若哪位分析了希望能分享一下:cczy_english@163.com,将不胜感激
 devices_init (); /* get the devices list going. */
#ifdef CONFIG_CMC_PU2
 load_sernum_ethaddr ();
#endif /* CONFIG_CMC_PU2 */
//初始化跳转表,对gd中的jt(函数跳转表)数组进行初始化,其中保存着一些函数的入口地址

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'uboot中C语言代码入口函数(start_armboot)',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.obk20.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);