范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

编译器是如何将芯片执行的第一个指令放到芯片起始地址的?

  编译器是如何将芯片执行的第一个指令放到芯片起始地址的?
  芯片上电后,会自动跳到第一需要执行的指令,那么编译器和链接器是做了哪些工作才让第一条指令被放在了正确的地方, 以 ar m 为例, uboo t 编译后为何能确 保 rese t 被放在了起始地址呢?
  本 人 8 年嵌入 式 Linux BS P 开发经验,关 于 U-Boo t 的开发经验如下:
  ·  平台开发:涉 及 ARM32/6 4 、 MIP S 架构 , MT K 、海思等不 下 5 个厂 商 U-Boo t 的 BS P 开发
  ·  版本升级:将某平台的低版 本 U-boo t 升级至最 新 u-boot-2022.0 1 版本
  ·  架构设计:将业务代码 从 U-Boo t 中剥离,灵活适配不 同 U-boo t 版本、所有产品不同平台不同架构的不同单板
  所以,相信有资格回答这个问题。
  本 文 800 0 多字,掏心带你深入理解背后的原理,需要你耐心往下看。除了问题本身,你还将收获:
  ·  什么是链接脚本 , U-Boo t 下的链接脚本长什么样?
  ·  U-Boo t 编译时是怎么链接的?
  ·  U-Boo t 下这么多 start.s ,当前设备跑的到底是哪一个?
  正文
  这个问题往深了说就涉及到了编译原理。
  在计算机世界中,其实每一次链接过程都是由链接脚本控制的。那么什么是链接脚本呢?简单说就是由链接器命令语言书写的,给链接器看的,主要的目的是描述输入文件中的段( 如 tex t 段 、 dat a 段 、 bs s 段等)如何在输出文件中组装,并控制输出文件的存储布局。
  那么上面提到的链接器、链接脚本、输入文件、输出文件分别是指什么呢?
  读万卷书,不如走一步路。动动手指,编译一 下 U-Boo t 就知道了,如果你还不清楚怎么编译或者没有环境的话,建议你参考我的文章搭建一个:
  闪光 吧 Linu x :走进嵌入 式 Linu x 大门的第二 步 — — 构建最 新 u-boo t 学习环境 9  赞 同  · 0  评论 文章
  下面是编译结果,截取重点如下:
  $ make CROSS_COMPILE=aarch64-linux-gnu- V=1
  ....
  aarch64-linux-gnu-ld.bfd -pie --gc-sections -Bstatic --no-dynamic-linker -z notext --build-id=none -Ttext 0x00000000 -o u-boot -T u-boot.lds arch/arm/cpu/armv8/start.o --whole-archive arch/arm/cpu/built-in.o arch/arm/cpu/armv8/built-in.o arch/arm/lib/built-in.o board/emulation/common/built-in.o board/emulation/qemu-arm/built-in.o boot/built-in.o cmd/built-in.o common/built-in.o disk/built-in.o drivers/built-in.o drivers/usb/cdns3/built-in.o drivers/usb/common/built-in.o drivers/usb/dwc3/built-in.o drivers/usb/emul/built-in.o drivers/usb/eth/built-in.o drivers/usb/host/built-in.o drivers/usb/mtu3/built-in.o drivers/usb/musb-new/built-in.o drivers/usb/musb/built-in.o drivers/usb/phy/built-in.o drivers/usb/ulpi/built-in.o env/built-in.o fs/built-in.o lib/built-in.o net/built-in.o --no-whole-archive -L /usr/lib/gcc-cross/aarch64-linux-gnu/9 -lgcc -Map u-boot.map; true
  aarch64-linux-gnu-objcopy --gap-fill=0xff -j .text -j .secure_text -j .secure_data -j .rodata -j .data -j .u_boot_list -j .rela.dyn -j .got -j .got.plt -j .binman_sym_table -j .text_rest -j .dtb.init.rodata -j .efi_runtime -j .efi_runtime_rel -O srec u-boot u-boot.srec
  aarch64-linux-gnu-objcopy --gap-fill=0xff -j .text -j .secure_text -j .secure_data -j .rodata -j .data -j .u_boot_list -j .rela.dyn -j .got -j .got.plt -j .binman_sym_table -j .text_rest -j .dtb.init.rodata -j .efi_runtime -j .efi_runtime_rel -O binary u-boot u-boot-nodtb.bin && { echo " start=$(aarch64-linux-gnu-nm | grep __rel_dyn_start | cut -f 1 -d """ """); end=$(aarch64-linux-gnu-nm | grep __rel_dyn_end | cut -f 1 -d """ """); tools/relocate-rela $start $end"; start=$(aarch64-linux-gnu-nm u-boot | grep __rel_dyn_start | cut -f 1 -d " "); end=$(aarch64-linux-gnu-nm u-boot | grep __rel_dyn_end | cut -f 1 -d " "); tools/relocate-rela u-boot- nodtb.bin  0x00000000 $start $end; } || { rm -f u-boot-nodtb.bin; false; }
  start=$(aarch64-linux-gnu-nm | grep __rel_dyn_start | cut -f 1 -d " "); end=$(aarch64-linux-gnu-nm | grep __rel_dyn_end | cut -f 1 -d " "); tools/relocate-rela $start $end
  cp u-boot-nodtb.bin u-boot.bin
  aarch64-linux-gnu-objdump -t u-boot > u-boot.sym
  ....
  这里的链接器就 是  aarch64-linux-gnu-ld.bf d 。链接脚本就 是 u-boot.ld s , 用 " - T " 命令行选项来指定。输入文件就是各个目录下编译好 的 build-in. o 以 及 li b 库。输出文件就 是 u-boo t ,通 过 " - o " 命令行选项来指定。
  千呼万唤始出来,我们来看 看 u-boot.ld s 这个链接脚本长的帅不帅:
  linuxer@linuxer-virtual-machine:~/work/u-boot-2022.01$ vim u-boot.lds
  OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
  OUTPUT_ARCH(aarch64)
  ENTRY(_start)
  SECTIONS
  {
  . = 0x00000000;
  . = ALIGN(8);
  .text :
  {
  *(.__image_copy_start)
  arch/arm/cpu/armv8/start.o (.text*)
  }
  .efi_runtime : {
  __efi_runtime_start = .;
  *(.text.efi_runtime*)
  *(.rodata.efi_runtime*)
  *(.data.efi_runtime*)
  __efi_runtime_stop = .;
  }
  .text_rest :
  {
  *(.text*)
  }
  . = ALIGN(8);
  . rodata  : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
  . = ALIGN(8);
  .data : {
  *(.data*)
  }
  . = ALIGN(8);
  . = .;
  . = ALIGN(8);
  .u_boot_list : {
  KEEP(*(SORT(.u_boot_list*)));
  }
  . = ALIGN(8);
  .efi_runtime_rel : {
  __efi_runtime_rel_start = .;
  *(.rel*.efi_runtime)
  *(.rel*.efi_runtime.*)
  linuxer@linuxer-virtual-machine:~/work/u-boot-2022.01$ cat u-boot.lds
  OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
  OUTPUT_ARCH(aarch64)
  ENTRY(_start)
  SECTIONS
  {
  . = 0x00000000;
  . = ALIGN(8);
  .text :
  {
  *(.__image_copy_start)
  arch/arm/cpu/armv8/start.o (.text*)
  }
  .efi_runtime : {
  __efi_runtime_start = .;
  *(.text.efi_runtime*)
  *(.rodata.efi_runtime*)
  *(.data.efi_runtime*)
  __efi_runtime_stop = .;
  }
  .text_rest :
  {
  *(.text*)
  }
  . = ALIGN(8);
  .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
  . = ALIGN(8);
  .data : {
  *(.data*)
  }
  . = ALIGN(8);
  . = .;
  . = ALIGN(8);
  .u_boot_list : {
  KEEP(*(SORT(.u_boot_list*)));
  }
  . = ALIGN(8);
  .efi_runtime_rel : {
  __efi_runtime_rel_start = .;
  *(.rel*.efi_runtime)
  *(.rel*.efi_runtime.*)
  __efi_runtime_rel_stop = .;
  }
  . = ALIGN(8);
  .image_copy_end :
  {
  *(.__image_copy_end)
  }
  . = ALIGN(8);
  .rel_dyn_start :
  {
  *(.__rel_dyn_start)
  }
  .rela. dyn  : {
  *(.rela*)
  }
  .rel_dyn_end :
  {
  *(.__rel_dyn_end)
  }
  _end = .;
  . = ALIGN(8);
  .bss_start : {
  KEEP(*(.__bss_start));
  }
  .bss : {
  *(.bss*)
  . = ALIGN(8);
  }
  .bss_end : {
  KEEP(*(.__bss_end));
  }
  /DISCARD/ : { *(.dynsym) }
  /DISCARD/ : { *(.dynstr*) }
  /DISCARD/ : { *(.dynamic*) }
  /DISCARD/ : { *(.plt*) }
  /DISCARD/ : { *(.interp*) }
  /DISCARD/ : { *(.gnu*) }
  }
  咋一看是不是挺帅的,好,那我们来认识一下这位大帅哥。
  他首先是一个文本文件,里面有一系列命令。其 中 SECTION S 该命令用于描述输出文件的内存布局,它后面跟着花括号中的一些列符号分配和输出段的描述。该命令的第一行设定了特殊符 号 " . " 的值 , " . " 值是位置计数器。如果不用其他方式指定输出段的地址,地址从位置计数器的当前值开始计算。 在 SECTION S 命令的最开始,位置计数器的值 是 0 。
  接下来定义输出 段 " .tex t " 。冒号是必需的格式。在输出段的名称后有一个花括号,里面可以列举放入该输出段的输入段 。 " * " 是匹配任何文件名的通配符。表达 式 " *(.__image_copy_start ) " 表示所有输入文件中的所 有 " .__image_copy_star t " 输入段。接下来是表达 式 " arch/arm/cpu/armv8/start.o  ( .text * ) " 表示所有输入文件中 的 " .tex t " 段 的 arch/arm/cpu/armv8/start. o 。
  题主的关切点来了:
  U-Boo t 执行的第一条指令用链接脚本中的术语叫 做 " 入口点 " 。链接脚本中使 用 ENTR Y 命令来设置。参数是一个符号名称 : ENTRY(symol ) ,这里的符号就 是 "_start " 。这里 的 " _star t " 是什么呢?就 是 0x 0 ,查看方式如下:
  那 么 0x 0 后面放什么呢?摘取关键部分如下:
  . =  0x00000000 ;
  . = ALIGN(8);
  .text :
  {
  *(.__image_copy_start)
  arch/arm/cpu/armv8/start.o (.text*)
  }
  0x 0 后面 放 tex t 段 , tex t 段里面先放什么呢?就 是 " *(.__image_copy_start ) " ,是什么呢,还 是 0x 0 :
  下面就是主角的真面目了,就 是 arch/arm/cpu/armv8/start.o (.text* ) ,再揭开面纱一睹真容:
  linuxer@linuxer-virtual-machine:~/work/u-boot-2022.01$ vim arch/arm/cpu/armv8/start.S
  *************************************************************************/
  .globl _start
  _start:
  b reset
  .align 3
  ....
  懂了吧,现在知道为 啥 " b rese t " 就会放在存储介质 的 0 地址了吧,圆满解答题主的问题。
  2022/04/0 3 更新(没想到阅读量已 快 1 千,感谢知友的赞同和追更):
  关于链接脚本的入口点的补充:
  前面提到,可以使 用 ENTR Y 链接脚本命令设置入口点。其实链接器支持多种方式设置入口点,会按照如下优先顺序尝试设定入口点:
  .  " - e " 入口命令行选项。
  .  链接脚本中 的 ENTR Y ( symbo l )命令。
  .  已经定义的目标特定符号的值。通常 是 star t 。
  .  链接脚本段中第一个字节的地址。
  .  地 址 0 。
  光说不练假把式,实验来检验。
  实验一:屏蔽链接脚本中 的 " ENTRY(_start) " 和 "arch/arm/cpu/armv8/start.o"
  重新编译后,查看映射表不再是 从 " b rese t " 开始了,直接 是 " __arm_smccc_sm c " 函数:
  $ less System.map
  0000000000000000 T __arm_smccc_smc
  0000000000000000 T __efi_runtime_start
  0000000000000000 T __image_copy_start
  000000000000002c T __arm_smccc_hvc
  0000000000000058 T invoke_psci_fn
  00000000000000d4 T efi_reset_system
  0000000000000130 W efi_get_time
  0000000000000138 W efi_set_time
  这种情况直接走顺 序 4 , 而 .tex t 段描述并没有指定具体内容,顺着肯定就 是 .efi_runtim e 段的第一个字节了。
  实验二:保 留 ENTRY(_start ) ,并 将 " arch/arm/cpu/armv8/start. o " 替换 为 " *(.text) * " :
  这种情况扔能通 过 "ENTRY(_start) " 找到对应入口:
  $ less System.map
  0000000000000000 T __image_copy_start
  0000000000000000 T _start
  0000000000000008 T _TEXT_BASE
  0000000000000010 T _end_ofs
  0000000000000018 T _bss_start_ofs
  0000000000000020 T _bss_end_ofs
  0000000000000028 t reset
  000000000000002c T save_boot_params_ret
  但无法直接看出是哪 个 . o ,实际确实 是 " arch/arm/cpu/armv8/start. o " ,因为只 有 "arch/arm/cpu/armv8/start.S " 定义 了 ".globl _start " 。
  这种情况直接走顺 序 3 。
  实验三:删 除 " ENTRY(_start) " ,并 将 " arch/arm/cpu/armv8/start. o " 替换 为 " *(.text) * " :
  扔能找 到 arch/arm/cpu/armv8/start. S 作为入口:
  $ less System.map
  0000000000000000 T __image_copy_start
  0000000000000000 T _start
  0000000000000008 T _TEXT_BASE
  0000000000000010 T _end_ofs
  0000000000000018 T _bss_start_ofs
  0000000000000020 T _bss_end_ofs
  0000000000000028 t reset
  000000000000002c T save_boot_params_ret
  这种情况直接走顺 序 4 。
  剩下的实验就交给你啦。

陈萌晒朱小伟送的中秋节礼物,对其称呼引热议,网友实在人大家应该都知道,朱小伟和二婚妻子陈萌,已经顺利地拍完了婚纱照,下一步就是去影楼选片,等待拿到属于他们的照片了。依稀记得小伟和陈亚男离婚就在昨天似的,结果人家的第二段婚姻马上就要举办被4岁儿子锁在阳台暴晒一下午的妈妈回应了,网友你真的活该家庭教育一直是我们教育的一部分,家庭教育是否成功,决定学生出入社会之后,是不是讨喜,能不能成长为一个合格善良的大人。家庭教育,千人千面。每个家庭的教育方式都不同,尤其是在一些生活中急!孩子出现这种情况,6小时内必须送医,晚了很可能影响生育大家好,我是豆妈。今天想跟大家聊一聊睾丸扭转这件事,因为这关系到孩子一生的幸福,但很多家长对此却知之甚少。之前杭州市中医院发布过一个病例,说一名9岁的男孩突然下体不适,家长以为只是李玉成公开分手原因,称新欢人品不行总利用他,网友终于醒了不知网友们发现没有,现在李玉成的身边已经没有了新欢的身影,他也重新回归到了马玉琴的身边,视频风格也变成了和马玉琴一起吃饭的风格。李玉成的突然转变令我们感到很吃惊,毕竟之前他和新欢之王诗龄入英国名校,甜馨晒欧美妆,两明星妈妈教育成果正逐渐展露9月6日,李湘在社交平台上发布了一则关于女儿王诗龄入学的动态。画面中,李湘与女儿王诗龄均在英国,而王诗龄入学的学校也很快被网友扒出,正是英国博奈顿女校,英国目前最好的寄宿制女校。这到过泰山西湖泰山秀城,密接次密接4人活动轨迹公告9月7日凌晨泰安旅游经济开发区发布关于密切接触者活动轨迹的公告关于密切接触者活动轨迹的公告9月6日2220,泰安旅游经济开发区接到肥城市疾病预防控制中心推送协查密切接触者1密切接触2022年,调整国家ampampquot法定节假日ampampquot的建议将迎来ampampquot2取消1增加ampampquot当节日到来的时候,很多人都非常开心,一方面是因为节日热闹,许久未见的人也能有理由相聚在一起,还有最重要的原因就是大部分工作和学习过节都会休息,国家也有法定节假日。有些法定节假日会和老北京的胡同真的能吃?还别说,看完不流口水算我输首先川大爷先做一下检讨,检讨什么呢,众所周知,川大爷平日里不是介绍吃的,就是介绍玩的,美食旅游比较在行,但是今天川大爷要说的,也不知道到底是吃的,还是玩的,反正川大空懵了,大家自行去云南大理治好了我的旅游景区餐厅恐惧症上一篇旅途探店的推文居然是去年11月份的事情了,最近终于去了一次云南,回来迫不及待想写推文了。第一次去云南,两个目的地昆明和大理。昆明都在喝咖啡,大理都在吃吃吃。脑子里的咖啡和美食温铁军数字经济重塑农业产业链,农业数字化困局怎么破?数字经济与金融资本产业资本结合之后再进入农业领域,面临的主要困难在于世界上的大多数农业生产基本还是一个自然过程,尚未达到高度资本化农业生产的程度,即完全脱离自然环境的高度设施化的农与八家单位签氢能产业链建设合作协议中石化锚定中国第一氢能公司与八家单位签氢能产业链建设合作协议中石化锚定中国第一氢能公司文本刊记者潘伟国资报告杂志2022年第7期刚才,中国石化与八家兄弟企业和单位签署了氢能产业链建设合作协议。我希望这只是一
梅西比肩马拉多纳?卡卡聊C罗下一站?快手大晚上聊个球精彩收官历经一个月的比拼厮杀,阿根廷队与法国队顶峰相见,为全世界球迷贡献出了一场精彩绝伦的史诗级对决。梅西若夺得冠军将比肩马拉多纳世界杯决赛是一场火星撞地球式的激烈对抗C罗的眼泪属于所有热国内成品油调价三连跌价格基本回到2022年初水平南都讯近日,国家发改委宣布下调国内成品油价格。广东省发改委价格处发布最新消息,自2022年12月19日24时起,在现行价格的基础上,省内汽柴油价格每吨分别下调480元和460元。这日本科学家在小行星龙宫表面发现太空风化的痕迹新华社东京12月21日电(记者钱铮)日本宇宙航空研究开发机构京都大学九州大学等组成的研究团队20日发布新闻公报说,他们通过分析隼鸟2号探测器从小行星龙宫带回的样本发现,龙宫表层的水研究社交媒体依赖与人格特质的关系,便于指导个体合理利用手机大学生作为使用智能手机的较大群体,对其的使用时间和粘性都已经达到了空前的高度。尹静汝在对宁夏地区大学生进行研究时,发现该群体中95。6有智能手机,其中选择全天24小时开机的占75。广西大学与国际合作团队观测发现宇宙中X射线偏振度最高的天体12月22日,广西大学召开成果发布会。陈周硕摄中新网南宁12月22日电(黄艳梅罗颖佳)广西大学22日召开成果发布会,介绍该校天文与空间科学技术团队与国际团队合作取得的重大科学发现。冬至来临,建议大家少吃牛羊肉,多吃三白汤,润燥又去寒冬至来临,眼看着天气一天比一天冷,很多人为了驱寒保暖,往往会买上许多的牛羊肉,像北方的朋友,就会选择每天喝汤,比如我们常见的牛肉汤羊肉汤驴肉汤等各种汤,不过,汤喝多了容易上火。虽然即便岁月无常,也要笑着活下去文微光心知(原创)贾乙丙丁不知何因,楼下传来一阵一阵,女子的嚎啕大哭。哭的撕心裂肺,哭得肝肠寸断。令听者动容,心里五味杂陈。突然想起昨天,和朋友的聊天。朋友说,她初入婆家,便不受待任天野女友怀孕就结婚,一心相爱16年无绯闻,支持父亲再娶娇妻虽然荧幕上一直以硬汉形象示人。但任天野却有着一段并不美好的童年经历。每次父母吵架,都需要自己下跪才能化解。或许对于那个时候的任天野来说,什么家庭和睦美满幸福全都是奢侈。8岁那年母亲恒天翼智慧渔港与华为鲲鹏平台完成兼容助力渔业安全迈步新台阶2022年中国信创生态市场研究和选型评估报告显示,我国信创产业规模近五年复合增长率为35。7,预计2025年将突破2万亿元。信创产业作为战略性新兴产业,国家不断出台相关政策对行业的15万年前工业痕迹,在青海显现?地球文明真的在循环往复吗?人类出现距今约七万年,但在青海的白云山却出现了十五万年前的工业痕迹,铁管神奇的成分和离奇的年代,更为白公山披上了一层神秘面纱,引来外界的普遍关注,也引发了不少大胆的猜测。十五万年前内华达鱼龙遗址或为远古产房据美联社12月19日报道,科学家们发现了有关内华达州一处令人好奇的化石遗址的新线索,该遗址是数十头巨型海洋爬行动物的墓地。事实上它并非人们此前所怀疑的大规模死亡现场,而可能是一个远