微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM Linux 的启动过程

ARM Linux 的启动过程

时间:11-09 来源:互联网 点击:

  1. loc,_bss_start-_data);
  2. */
  3. cmpr4,r5@Copydatasegmentifneeded
  4. 1:cmpner5,r6
  5. ldrnefp,[r4],#4
  6. strnefp,[r5],#4
  7. bne1b
  8. /*将BSS段,也即从_bss_start到_end的内存清零。*/
  9. movfp,#0@ClearBSS(andzerofp)
  10. 1:cmpr6,r7
  11. strccfp,[r6],#4
  12. bcc1b
  13. /*r4=processor_id,
  14. *r5=__machine_arch_type
  15. *r6=__atags_pointer
  16. *r7=cr_alignment
  17. *sp=init_thread_union+THREAD_START_SP
  18. *为什么将栈顶指针设置为init_thread_union+THREAD_START_SP
  19. *init_head_union变量是一个大小为THREAD_SIZE的union,它在编译时,放到数据段的前面。
  20. *初步估计这块空间是内核堆栈。故在跳入C语言代码时,它SP的值设置为init_thread_union+THREAD_START_SP。
  21. *注意THREAD_START_SP定义为THREAD_SIZE–8,中间为什么留出8个字节呢?是与ARM的堆栈操作有关吗?还有用专向start_kernel函数传递参数?
  22. */
  23. ldmiar3,{r4,r5,r6,r7,sp}
  24. strr9,[r4]@SaveprocessorID
  25. strr1,[r5]@Savemachinetype
  26. strr2,[r6]@Saveatagspointer
  27. bicr4,r0,#CR_A@ClearAbit
  28. /*cr_alignment变量的后面接着放置cr_no_alignment,
  29. *r0为打开alignment检测时,控制寄存器的值,而r4为关闭时的值,
  30. *这里分将将打开和关闭alignment检查的控制寄存器的值写到
  31. *cr_alignment和cr_no_alignement变量中。
  32. */
  33. stmiar7,{r0,r4}@Savecontrolregistervalues
  34. /*跳到start_kernel函数,此函数代码用纯C来实现,它会调用各个平台的相关初始化函数,
  35. *来实现不同平台的初始化工作。至此,armlinux的启动工作完成。
  36. */
  37. bstart_kernel
  38. ENDPROC(__mmap_switched)

[cpp]view plaincopy

  1. .type__switch_data,%object
  2. __switch_data:
  3. .long__mmap_switched
  4. .long__data_loc@r4
  5. .long_data@r5
  6. .long__bss_start@r6
  7. .long_end@r7
  8. .longprocessor_id@r4
  9. .long__machine_arch_type@r5
  10. .long__atags_pointer@r6
  11. .longcr_alignment@r7
  12. .longinit_thread_union+THREAD_START_SP@sp
  13. /*
  14. *ThefollowingfragmentofcodeisexecutedwiththeMMUoninMMUmode,
  15. *andusesabsoluteaddresses;thisisnotpositionindependent.
  16. *
  17. *r0=cp#15controlregister
  18. *r1=machineID
  19. *r2=atagspointer
  20. *r9=processorID
  21. */
  22. __mmap_switched:
  23. adrr3,__switch_data+4
  24. /*r4=__data_loc,r5=_data,r6=_bss_start,r7=_end*/
  25. ldmiar3!,{r4,r5,r6,r7}
  26. /*下面这段代码类似于这段C代码,即将整个数据段从__data_loc拷贝到_data段。
  27. *if(__data_loc==_data||_data!=_bass_start)
  28. *memcpy(_data,__data_loc,_bss_start-_data);
  29. */
  30. cmpr4,r5@Copydatasegmentifneeded
  31. 1:cmpner5,r6
  32. ldrnefp,[r4],#4
  33. strnefp,[r5],#4
  34. bne1b
  35. /*将BSS段,也即从_bss_start到_end的内存清零。*/
  36. movfp,#0@ClearBSS(andzerofp)
  37. 1:cmpr6,r7
  38. strccfp,[r6],#4
  39. bcc1b
  40. /*r4=processor_id,
  41. *r5=__machine_arch_type
  42. *r6=__atags_pointer
  43. *r7=cr_alignment
  44. *sp=init_thread_union+THREAD_START_SP
  45. *为什么将栈顶指针设置为init_thread_union+THREAD_START_SP
  46. *init_head_union变量是一个大小为THREAD_SIZE的union,它在编译时,放到数据段的前面。
  47. *初步估计这块空间是内核堆栈。故在跳入C语言代码时,它SP的值设置为init_thread_union+THREAD_START_SP。
  48. *注意THREAD_START_SP定义为THREAD_SIZE–8,中间为什么留出8个字节呢?是与ARM的堆栈操作有关吗?还有用专向start_kernel函数传递参数?
  49. */
  50. ldmiar3,{r4,r5,r6,r7,sp}
  51. strr9,[r4]@SaveprocessorID
  52. strr1,[r5]@Savemachinetype
  53. strr2,[r6]@Saveatagspointer
  54. bicr4,r0,#CR_A@ClearAbit
  55. /*cr_alignment变量的后面接着放置cr_no_alignment,
  56. *r0为打开alignment检测时,控制寄存器的值,而r4为关闭时的值,
  57. *这里分将将打开和关闭alignment检查的控制寄存器的值写到
  58. *cr_alignment和cr_no_alignement变量中。
  59. */
  60. stmiar7,{r0,r4}@Savecontrolregistervalues
  61. /*跳到start_kernel函数,此函数代码用纯C来实现,它会调用各个平台的相关初始化函数,
  62. *来实现不同平台的初始化工作。至此,armlinux的启动工作完成。
  63. */
  64. bstart_kernel
  65. ENDPROC(__mmap_switched)

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top