SylixOS BSP开发(十二)

gewenbin
gewenbin
gewenbin
188
文章
15
评论
2021年4月4日13:52:35 评论 2,546

SylixOS内核启动过程简单分析

通过前面的学习我们已经掌握了SylixOS BSP开发的最基础的内容,现在大家至少能快速地在一块开发板上移植SylixOS并且能启动到显示Logo阶段了。现在我们暂且把移植工作放一放,我们来简单的看下SylixOS内核在启动时大致做了哪些事情,以让我们对系统启动过程做到心中有数,这样我们才能以不变应万变。

当然我们现在只用了单核启动,所以分析的也是单核的启动流程,多核的启动流程会在后续章节进行讲解。我将SylixOS的启动流程大致总结成了10个步骤:

SylixOS BSP开发(十二)

1. 内核入口初始化

这个就是startup.S中做的工作,主要就是一些架构相关的初始化工作,这个在前面章节我们已经学习过。

2. 系统基础组件初始化

主核启动时在BSP中会调用API_KernelPrimaryStart 执行内核所有组件的初始化工作。首先会调用_KernelPrimaryLowLevelInit 接口来初始化系统一些基础组件,比如调度器、消息队列、内核堆管理器等等:

SylixOS BSP开发(十二)

3. BSP中断控制器初始化

通过调用bspIntInit 接口来初始化中断控制器,这个接口需要在bspLib.c中实现:

SylixOS BSP开发(十二)

4. 系统高级组件初始化

调用_KernelHighLevelInit 来初始化系统高级组件,比如信号系统、中断延迟队列、总线系统等等:

SylixOS BSP开发(十二)

5. VMM、Cache组件初始化

这是在bspInit.c中的usrStartup 函数中做的:

SylixOS BSP开发(十二)

6. 创建初始化启动任务

BSP中的大部分驱动初始化、设备创建等等工作都是在halBootThread 这个线程中做的。这个线程同样是在usrStartup 函数中创建,但是要注意的是这时仅仅是创建了这个线程,它并没有被调度运行,在内核所有工作都初始化完成后会调度这个线程进行工作。

SylixOS BSP开发(十二)

7. BSP系统TICK初始化

通过调用bspLib.c中的bspTickInit 接口来初始化系统TICK,其实就是初始化一个硬件定时器并让其以系统TICK频率开始工作:

SylixOS BSP开发(十二)

8. 启动内核,调度任务运行

到这里为止,内核的初始化工作哦基本已经完成了,这时就需要选择一个优先级最高的线程来运行了,这是通过调用_KernelPrimaryCoreStartup 来实现的:

SylixOS BSP开发(十二)

那么第一个被调度的线程是哪个线程呢,是我们之前在BSP中创建的halBootThread 这个线程吗?其实并不是,SylixOS内核是按优先级调度的,halBootThread 线程的优先级为50,在内核初始化的过程中会创建很多系统任务,这些任务中有三个优先级是比halBootThread 线程优先级高的(数值越小优先级越高):

SylixOS BSP开发(十二)

从优先级我们可以分析出t_except和t_isrdefer这两个线程肯定是最开始被调度运行的两个线程,但是这两个线程运行后马上就阻塞自己了,接着调度t_itimer线程运行,这个线程也将自己挂起,这时候halBootThread 线程才是就绪的优先级最高的线程,于是被调度运行。

9. 运行初始化启动任务

在这个初始化线程halBootThread 中会去初始化驱动、Posix组件、动态加载器、SylixOS Shell等等一些列的功能,这些初始化的顺序使用默认的即可,一般不需要太大的修改。这里只介绍几个调用到的比较重要的接口。

  • halBusInit:如果BSP需要使用I2C或者SPI,那么就需要将SylixOS的I2C和SPI总线初始化的代码加在这个函数中。
  • halDrvInit:驱动初始化函数,BSP开发者可以将自己的驱动初始化接口加在这个函数中。
  • halDevInit:设备创建函数,BSP开发者可以将自己驱动中设备创建接口加载这个函数中。

10. 创建t_main任务运行

这个线程主要就是创建一个SylixOS Shell以让用户可以和SylixOS进行交互:

int  t_main (void)
{
    struct utsname  name;
    
    uname(&name);
    
    printf("sysname  : %s\n", name.sysname);
    printf("nodename : %s\n", name.nodename);
    printf("release  : %s\n", name.release);
    printf("version  : %s\n", name.version);
    printf("machine  : %s\n", name.machine);
    
    Lw_TShell_Create(STDOUT_FILENO, LW_OPTION_TSHELL_PROMPT_FULL | LW_OPTION_TSHELL_VT100);
    
    return  (0);
}

经过上面的介绍,相信大家对SylixOS内核的基本启动流程有了一个大致的了解,到目前为止,SylixOS虽然可以启动起来,但是现在是只有"形"而没有"神",接下来就让我们继续实现中断控制器驱动和定时器驱动来赋予SylixOS真正的灵魂。

gewenbin
  • 本文由 发表于 2021年4月4日13:52:35
  • 转载请务必保留本文链接:http://www.databusworld.cn/10170.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: