• RT-Thread 内核启动流程


    内核启动流程

    1.概述

    内核启动流程可以分为2步骤(非官方):

    • 启动(汇编)

      • 使用汇编代码编写,涉及非常底层的设置,比如CPU设置等等
      • 地址映射也在这里实现
      • 它最终会调用rtthread_startup函数
    • rtthread_startup函数(C函数)

      • 以后的代码,基本都是使用C语言编写了
      • 主要工作是:
        • 单板级别的初始化:rt_hw_board_init
        • 定时器初始化:rt_system_timer_init
        • 调度器初始化:rt_system_scheduler_init
        • 信号初始化:rt_system_signal_init
        • 创建init线程:rt_application_init
        • 创建timer线程:rt_system_timer_thread_init
        • 创建idle线程:rt_thread_idle_init
        • 自动调度器:rt_system_scheduler_start

    2. 启动文件分析

    rt-smart\kernel\libcpu\arm\cortex-a\vector_gcc.S开始阅读代码,它是向量表。
    板子启动后执行reset向量,即b _reset
    _reset在rt-smart\kernel\libcpu\arm\cortex-a\start_gcc.S中定义,流程如下:

    Created with Raphaël 2.3.0 start 映射内核程序本身所在内存的地址 使能MMU 设置栈 清除BSS 映射所有内存的地址 切换页表 调用rtthread的C入口函数 end

    3. rtthread_startup函数分析

    rtthread_startup函数在这个文件里rt-smart\kernel\src\components.c
    流程如下:

    Created with Raphaël 2.3.0 start rtthread_startup rt_hw_interrupt_disable rt_hw_board_init rt_show_version rt_system_timer_init rt_system_scheduler_init rt_system_signal_init rt_application_init rt_system_timer_thread_init rt_thread_idle_init rt_system_scheduler_start end

    4.跟移植相关的代码

    移植内核时,涉及地址映射、中断控制器、串口驱动、Timer驱动。

    • 地址映射:rt-smart\kernel\libcpu\arm\cortex-a\start_gcc.S
    • 中断控制器、串口驱动、Timer驱动:入口都是
    rtthread_startup
        rt_hw_board_init
        	rt_hw_interrupt_init
        	rt_components_board_init  // 调用某个段里的所有函数
        		rt_hw_uart_init        // 它被放在某个段里 
    		    rt_hw_timer_init       // 它被放在某个段里
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    下面是个索引,后续课程在深入讲解。
    学有余力的同学可以根据索引自行学习。

    4.1地址映射

    4.1.1 映射内核程序所处内存

    代码:rt-smart\kernel\libcpu\arm\cortex-a\mmu.c

    #ifdef RT_USING_USERSPACE
    void init_mm_setup(unsigned int *mtbl, unsigned int size, unsigned int pv_off) {
        unsigned int va;
    
        for (va = 0; va < 0x1000; va++) {
            unsigned int vaddr = (va << 20);
            if (vaddr >= KERNEL_VADDR_START && vaddr - KERNEL_VADDR_START < size) {
                mtbl[va] = ((va << 20) + pv_off) | NORMAL_MEM;
            } else if (vaddr >= (KERNEL_VADDR_START + pv_off) && vaddr - (KERNEL_VADDR_START + pv_off) < size) {
                mtbl[va] = (va << 20) | NORMAL_MEM;
            } else {
                mtbl[va] = 0;
            }
        }
    }
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4.1.2映射整个内存

    代码:rt-smart\kernel\libcpu\arm\cortex-a\start_gcc.S

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T9bqyKkF-1660549067247)(pic/04_添加一个单板/01_map_whole_mem.png)]

    数组位于:rt-smart\kernel\bsp\qemu-vexpress-a9\drivers\board.c

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ubPPPjHe-1660549067250)(pic/04_添加一个单板/02_array_for_mem_map.png)]

    4.2 中断控制器

    调用过程:

    rtthread_startup
        rt_hw_board_init
        	rt_hw_interrupt_init
    
    • 1
    • 2
    • 3

    4.3 串口驱动

    代码:rt-smart\kernel\bsp\qemu-vexpress-a9\drivers\serial.c
    调用过程:

    rtthread_startup
        rt_hw_board_init
        	rt_components_board_init  // 调用某个段里的所有函数
        		rt_hw_uart_init       // 它被放在某个段里
    
    • 1
    • 2
    • 3
    • 4

    4.4 Timer驱动

    代码在kernel\bsp\qemu-vexpress-a9\drivers\drv_timer.c
    调用过程:

    rtthread_startup
        rt_hw_board_init
        	rt_components_board_init   // 调用某个段里的所有函数
        		rt_hw_timer_init       // 它被放在某个段里
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    Dijkstra求最短路—priority堆优化;
    缓存问题解决方案
    【深度学习】分类问题探究(多标签分类转为多个二分类,等)
    本周的error记录
    论文笔记:Universal Value Function Approximators
    HTML数字倒计时效果附源码
    [附源码]计算机毕业设计疫情管理系统Springboot程序
    多态的定义 以及 虚函数重写(覆盖)
    前端面试题46(vue路由如何根据权限动态控制路由的显示?)
    安装java编译器
  • 原文地址:https://blog.csdn.net/qq_39217004/article/details/126348018