首页 > 代码库 > SylixOS 启动浅析

SylixOS 启动浅析

1、SylixOS启动概述

  每个操作系统的启动都是多种多样,各有不同,SylixOS亦是如此,本文将浅析SylixOS启动层次和启动步骤两大方面。


2、SylixOS启动层次

  在专用的嵌入式开发板上运行嵌入式操作系统(如SylixOS、Linux等)已经变得越来越流行,通常从一个嵌入式操作系统的软件角度来看,引导加载程序和操作系统内核便是两个重要的层次,下面就简单介绍关于SylixOS这两大层次的关键点。


2.1 层次一:Boot过程

  一个裸机可执行程序的运行方法有两种:

  1、 将程序代码入口放在处理器复位向量地址处,处理器上电可直接运行;

  2、 使用bootloader将程序装载到指定的运行地址,再将cpu控制权交给需要运行的程序。

  SylixOS支持以上任意一种的启动方法,两种方法区别如表 21所示。

表 21  启动方法

方法

第一种

第二种

优点

启动速度快(系统上电后,操作系统立即就开始初始化并运行);

灵活性强(bootloader可初始化基础性部件,根据配置以不同顺序启动系统);

缺点

灵活性不够(系统稍有动,就需要重新固化代码);

代码执行速度慢;

启动速度稍慢;

  SylixOS推荐使用第二种方法启动系统,虽然SylixOS经过裁剪后也可以作为bootloader,但是为了移植的通用性和兼容性,故推荐使用u-boot这一类标准的bootloader。

  SylixOS自己作为bootloader:

  1、可以生成两个SylixOS可执行镜像,一个用来做bootloader使用第一种方法启动;

  2、从存储介质或通信煤质获取另一个SylixOS系统可执行代码镜像;

  3、把系统镜像拷贝到需要运行的地址处,将cpu控制权交给系统镜像,完成boot过程。


2.2 层次二:Image文件

  在RealEvo-IDE开发工具编译下,新建的bsp工程Debug目录下会生成一个.bin或.elf可执行镜像文件,故SylixOS系统本身就是一个执行镜像。

  一个程序的执行镜像大致可以分为3个区域:text、data、bss,SylixOS编译链接后也分为这3个区域,如表 22所示。

表 22 镜像划分区域

区域段名备注
text文字池段

一般由代码、表格常量组成,运行时不可修改

data数据段

需要初始化的全局变量,在C代码运行前需赋初值

bss清零段

需要清零的全局数据区,在C代码运行前需清零

  SylixOS可执行文件分为两类,纯程序运行代码和带有格式的镜像文件,这两类分别代表bin和elf文件。

  bin文件仅包含连续的数据,他可以是代码, 也可以是数据,一般在运行bin文件时:1、预先知道代码运行的入口地址;2、将bin文件拷贝或烧录到该地址以后的存储区。elf文件与bin文件完全不同,elf 并不是单纯的无格式数据文件, elf 是一种较复杂的程序文件, 分为多种类型, 这里所说的是个执行文件.elf 文件内部包含有对程序运行信息的描述, 数据的存放, 调试信息等等。

  elf 内部程序代码一般不包含有对 .data 段初始化的代码, 所以切记, 仅仅拷贝 elf 内部的代码, 是不能正确运行程序的,lf 内部一般由多分段组成, 每个分段都有物理地址(装载域)和虚拟地址(运行域)。当 .text 与 .data 连续时, 一般分段物理地址与虚拟地址相同, 所以只要根据文件信息将相关的数据拷贝入指定的内存即可。当 .text 与 .data 不连续时, 有些段的物理地址与虚拟地址将不再相同, 这时注意, 需要将文件数据拷贝入物理地址(装载域)指定的内存中,程序启动时会自动将物理地址(装载域)内的相关数据, 拷贝入虚拟地址(运行域). 这样完成对某些段(例如:.data)的初始化.

  所以说.text 与 .data 连续的可执行文件, 是不能轻易重启的, 必须由 bootloader 从新装载完成重启(推荐).在生成 bootloader 时, (即使用一个 sylixos 启动另一个系统), 推荐不要开启 MMU 和 DCACHE, 因为如果启动镜像小, 建立 MMU 页表的时间反而远远超过装载镜像的时间。

  注:RealEvo-Simulator模拟器类似于解析器,故使用的都是.elf文件。


3、SylixOS启动步骤

  SylixOS启动总体分为3个步骤:

  1、 系统复位,程序从复位向量处开始运行,此时运行的为启动代码startup.s;

  2、 初始化C程序运行环境,如堆栈、中断、总线等;

  3、 进入bspinit函数做一些必要的处理,完成SylixOS初始化工作。


3.1 步骤源码文件总结

  SylixOS启动主要有startup.s和bspinit.c两大源码文件。

  1、startup.s文件位于bsp工程/SylixOS/bsp目录下,主要负责初始化关键性运行环境,承担SylixOS启动的前两大步骤,如图 31所示。

技术分享

图 31 startup.s的初始化

   2、bspInit.c文件同样位于bsp工程/SylixOS/bsp目录下,其bspinit函数为SylixOS启动最后一大步骤,函数为C函数跳转入口,在bspInit函数中主要分为几个部分:

  •  启动内核,关键性运行环境数据搭建(API_KernelStart函数);

  •  SylixOS将控制权转交usrStartup函数进行回调,用户初始化相关功能;

  •  创建第一个任务(halBootThread函数),负责初始化所有系统资源,将SylixOS控制权转交给用户。

3.2 步骤部分函数总结

  1、 API_KernelStart函数为SylixOS启动内核函数。

  API_KernelStart函数原型:

  #include  < k_kernel.h >

  VOID  API_KernelPrimaryStart (PKERNEL_START_ROUTINE  pfuncStartHook,

                      PVOID             pvKernelHeapMem,

                      size_t            stKernelHeapSize,

                      PVOID             pvSystemHeapMem,

                     size_t             stSystemHeapSize)                  

  API_KernelStart函数原型分析:

  •  该函数为系统内核入口,只允许系统逻辑主核调用,一般cpu为0,当前为关中断状态;

  • 参数pfuncStartHook为系统启动中的用户回调;

  • 参数pvKernelHeapMem为内核堆内存首地址;

  • 参数stKernelHeapSize为内核堆大小;

  •   参数pvSystemHeapMem为系统堆内存首地址;

  •  参数stSystemHeapSize为系统堆大小;

  usrStartup函数作为参数pfuncStartHook传入API_KernelStart函数,用来初始化应用相关组件,创建操作系统的第一个任务。

  2、halBootThread函数负责初始化所有系统资源,如图 32所示。

技术分享

 图 32 halBootThread函数的初始化

   halBootThread函数原型:

   static  PVOID  halBootThread (PVOID  pvBootArg)

   halBootThread函数原型分析:

   halBootThread函数是usrStartup函数创建的t_boot线程下,用来多任务状态下的初始化启动任务函数。


4、参考资料


SylixOS 启动浅析