• arm cortex-a9的qemu仿真与启动文件解释


    启动文件,其实也就是裸机编程文件

    关于这个问题,三种解决方法:

    • 自己找博客、github、技术手册等,看看a9的启动文件,然后买块a9的开发板,自己烧录下载,运行。缺点:需要买板子,而且没有好用的IDE支撑(虽然eclipse经过一定的配置后也能行),下载程序很困难(可能需要sd卡反复插拔),调试可能更困难了,还需要买个jlink调试器,还只能gdb命令行调试(当然也有一些gdb前端调试软件,比如ozone等)。我这个博客也有写这个 windows上运行qemu仿真stm32板子a9板子实例_标biao的博客-CSDN博客
    • Linux的bootloader,一般是uboot是最为通用的bootloader,里面就有这样的代码。缺点:太复杂,扒拉出来学习成本太高。嵌入式杂记(uboot启动流程,简单易懂!!!)_标biao的博客-CSDN博客
    • 通过虚拟机qemu仿真a9板子。优点:程序的下载和调试都方便了;缺点:可能下载调试运行等操作比较慢,毕竟是仿真嘛,依赖于电脑性能。

    三者我都尝试过,这里我建议选第三种方法吧。(而且我现在是在windows系统上搞这个,网上大部分教程都是在Ubuntu系统,对初学者不友好)

    没必要重复造轮子,我们直接找现成的,国产嵌入式实时操作系统 rtthread 这方面就做得比较好,在各种处理器体系都有适配。

    rtthread 官网:RT-Thread, RTOS, 物联网操作系统 - RT-Thread物联网操作系统

    1. 去下载它们的免费IDE,RT-Thread Studio
    2. 新建一个基于开发板的项目,开发板选择 VExpress-A9,这个是arm官方做产品测试搞出来的开发板,这里是对它进行了qemu的模拟,还能看到启动qemu用了哪些命令,自己命令行就可以借鉴使用了。

      下载命令:
      qemu-system-arm.exe -M vexpress-a9 -nographic        -kernel Debug/rtthread.bin

      调试命令:
      qemu-system-arm.exe -M vexpress-a9 -nographic -S -s       -kernel Debug/rtthread.elf

      关于每个选项什么意思,大家自己百度一下吧。

      注:经过RT-Thread Studio的github主页介绍,以及我的测试,rthread确实只支持a9这个板子的qemu仿真模拟(而且只能是单核,尽管我们可以在debug设置界面设置为多核,调试就会报错了,其它的,比如stm32f4这些都不支持(虽然有些地方说支持,是假的)。究其原因,RT-Thread Studio后台调用的是qemu-system-arm.exe这个软件,而不是qemu-system-guneclipse.exe这个(可以参考我的博客qemu的详细资料大全(入门必看!!!)_标biao的博客-CSDN博客)。

    3. 傻瓜式的构建项目,下载,调试就行。这也说明这个IDE做得真不错
    4. 启动文件在这儿



       
    5. a9的启动文件,rtthread封装得挺好,注释写得很清楚
      (1)设置处理器模式
      (2)设置FPU
      (3)设置一个栈
      (4)初始化bss段
      (5)设置是否适用多核的配置
      (6)设置mmu
      (7)跳入C语言函数

      自己可以打个断点,在这个IDE里调试运行一下,就全部明白了。

      同理其它处理器的启动文件如何搞(比如stm32,sparc等处理器的启动文件),也通过这个IDE新建工程就能看啦,但是不支持qemu仿真了。
    1. _reset:
    2. /* set the cpu to SVC32 mode and disable interrupt */
    3. cps #Mode_SVC
    4. #ifdef RT_USING_FPU
    5. mov r4, #0xfffffff
    6. mcr p15, 0, r4, c1, c0, 2
    7. #endif
    8. /* disable the data alignment check */
    9. mrc p15, 0, r1, c1, c0, 0
    10. bic r1, #(1<<1)
    11. mcr p15, 0, r1, c1, c0, 0
    12. /* setup stack */
    13. bl stack_setup
    14. /* clear .bss */
    15. mov r0,#0 /* get a zero */
    16. ldr r1,=__bss_start /* bss start */
    17. ldr r2,=__bss_end /* bss end */
    18. bss_loop:
    19. cmp r1,r2 /* check if data to clear */
    20. strlo r0,[r1],#4 /* clear 4 bytes */
    21. blo bss_loop /* loop until done */
    22. #ifdef RT_USING_SMP
    23. mrc p15, 0, r1, c1, c0, 1
    24. mov r0, #(1<<6)
    25. orr r1, r0
    26. mcr p15, 0, r1, c1, c0, 1 //enable smp
    27. #endif
    28. /* initialize the mmu table and enable mmu */
    29. ldr r0, =platform_mem_desc
    30. ldr r1, =platform_mem_desc_size
    31. ldr r1, [r1]
    32. bl rt_hw_init_mmu_table
    33. bl rt_hw_mmu_init
    34. /* call C++ constructors of global objects */
    35. ldr r0, =__ctors_start__
    36. ldr r1, =__ctors_end__
    37. ctor_loop:
    38. cmp r0, r1
    39. beq ctor_end
    40. ldr r2, [r0], #4
    41. stmfd sp!, {r0-r1}
    42. mov lr, pc
    43. bx r2
    44. ldmfd sp!, {r0-r1}
    45. b ctor_loop
    46. ctor_end:
    47. /* start RT-Thread Kernel */
    48. ldr pc, _rtthread_startup
    49. _rtthread_startup:
    50. /* 这里就是把rtthread_startup这个函数地址放在这儿了,实现上面的跳入C语言函数了 */
    51. .word rtthread_startup

  • 相关阅读:
    使用 PyQT 和 Qt 设计器进行 Python GUI 开发
    MySQL数据库增删改查操作和常用命令
    Java Class.forName()具有什么功能呢?
    DataGrip操作Oracle
    成人自考-英语二-连词
    Python中的map()、apply()、applymap()的区别
    React中的useEffect(副作用)
    nginx出现504 Gateway Time-out错误的原因分析及解决
    力扣labuladong——一刷day32
    java 多线程笔记四 线程状态
  • 原文地址:https://blog.csdn.net/kangkanglhb88008/article/details/126374063