鸿蒙操作系统系列——LiteOS启动流程分析

目录

 

1.分析startup文件目录

2. 分析reset_vector_up.s

2.1 定义中断向量表

2.2 重定位系统镜像

2.3 初始化内核页表

2.4 初始化内核临时页表

2.5 设置mmu

2.6 初始化各个cpu模式下的栈

2.7 设置各个模式的栈地址

2.8 使能fpu+neon

2.9 bss段清零

2.10 跳转c语言main函数


1.分析startup文件目录

reset_vector_up.s在源码中的位置为kernel\liteos_a\arch\arm\arm\src\startup,在这个目录下有两个文件,如下图所示。

带up字样的应该是单核时启动用的,mp为多核时启动使用。

2. 分析reset_vector_up.s

2.1 定义中断向量表

如下图所示,中断向量表是放在.vectors段中,系统启动时最先执行的是reset_vector函数。

2.2 重定位系统镜像

我们接着来看reset_vector函数,先是关闭I/D cache和mmu,如下图所示

接着计算了内核运行(虚拟)地址和物理地址之间的差值保存在r11中,r11在后面代码中会被用于虚拟和物理地址之间的转换。那么内核的运行地址和物理地址是什么意思呢?

内核的运行地址就是内核设计者希望内核运行时在内存中的位置,这个地址一般在内核源码中有地方可以配置,并且链接脚本里也会用到这个地址,编译代码时所用到的跟地址相关的值都是以内核运行基址为基础进行计算的。

在liteos_a中,内核运行基址是在各个板子的board.h中配置的,如下图所示。

由于liteos_a是为带mmu的处理器设计的,所以这个内核运行基址的值是虚拟地址,这个KERNEL_VADDR_BASE在链接脚本board.ld.S(在kernel\liteos_a\platform\中)中会被用到,如下图所示。

从图中我们也可以看出,中断向量表所在的vectors段是被放在内核运行基址处的。

当内核被加载到内存中时,它的起始地址就叫做加载地址,因为内核是被uboot加载的,uboot中对mmu页表不会做太复杂的映射,一般也就是一一映射,也就是物理地址和虚拟地址值是一样的,所以可以认为内核加载地址值是物理地址。从reset_vector_up.s代码中我们也可以看出,内核设计者希望我们把内核加载到内存基址处运行,如下图所示。

但是我们并不能保证内核被加载到内存时所在的地址就是物理内存基址,如果不是的话,那么就需要对内核镜像做重定位操作,把内核从加载地址搬到物理内存基址处,如下图所示。

让我们回到代码里来,r11的值是内核虚拟地址和物理地址之间的差值,如果内核不需要重定位的话,这个值通过以下三条指令计算得出。

  •   adr r11, pa_va_offset。这条指令表示获取pa_va_offset变量的当前运行地址,由于这时候mmu已经被关闭,所以这个值就表示pa_va_offset变量的物理地址。pa_va_offset变量定义如下图所示,可以看出,这个变量是4字节大小,变量中的值表示变量的虚拟地址,这个地址是编译器在编译的时候确定的,而编译器编译时所用到的地址都是按虚拟地址来计算的。

  • ldr r0, [r11]。这条指令就是获取pa_va_offset变量的虚拟地址。
  • sub r11, r11, r0。将pa_va_offset变量物理地址-虚拟地址得到差值。

接着根据内核的加载地址是否等于物理内存基址来判断内核是否需要重定位,如下图所示。

SYS_MEM_BASE也是在各个板子的board.h中设置的,如下图所示。

如果内核不需要重定位,直接跳转到reloc_img_to_bottom_done处执行,如果需要重定位,则将内核从加载地址拷贝到内存基址处,重定位完后跳到新地址处运行并且校正r11的值,如下图所示。

那么这里是如何知道内核是有多大的呢?答案就是通过__bss_start-__exception_handlers得到内核大小。

在源码kernel\liteos_a\tools\build中有内核的链接脚本,如果使用gcc编译的,我们就看liteos.ld,如下图所示。

链接脚本首先包含了board.ld,这个就是前面我们看过的board.ld.S,也就是包含了vectors段,然后是text代码段,接着是只读数据段和可读写数据段,还有一些其他的段,如下图所示。

最后是bss段和临时页表,这个临时页表会在后面分析用到,如下图所示。

可以总结出内核镜像在内存中的大致布局如下图所示。

由于目前阶段有用的数据就是中断向量表+代码段+只读数据段+数据段,所以只需要复制__bss_start-__exception_handlers这么多数据到内存基址处就行了。

2.3 初始化内核页表

接着对内核页表进行清零,然后初始化页表,如下图所示。

 

核页表是用数组g_firstPageTable来表示的,这个数组在kernel\liteos_a\arch\arm\arm\src\los_arch_mmu.c中定义,如下图所示。

这个数组用了__attribute__修饰需要16KB地址对齐,这是arm架构要求的,页表基址需要16KB对齐,同时这个数组的大小也是16KB,因为内核页表是按1MB大小的段映射的,只有一级页表,32位地址空间物理空间最大4096MB,需要4096个段描述符,每个段描述符4字节大小,所以总共需要4096 * 4 = 16KB大小的页表空间。

我们来看看如何清零内核页表的:

  • ldr r4, =g_firstPageTable。获取内核页表的虚拟地址。
  • add r4, r4, r11。内核页表虚拟地址+r11=内核页表物理地址,保存在r4中。
  • bl page_table_clear。这个函数很简单,就是将内核页表内存清零,如下图所示。

内核页表清零后紧接着用PAGE_TABLE_SET这个宏对页表进行了设置,也就是建立物理地址和虚拟地址之间的映射,这个宏如下图所示。

这个宏有四个参数,分别是物理地址、虚拟地址、映射大小、映射属性。将这四个值保存在系统寄存器中后调用page_table_build函数进行映射关系建立,如下图所示。

注意这个函数会将物理地址、虚拟地址还有映射大小都对齐到1MB,因为内核页表是进行1MB段式映射,然后根据虚拟地址得到页表项索引,将物理地址和映射属性组合后填入对应的页表项,都是基操。

这里建立了5次物理和虚拟地址空间的映射,总结如下图所示。

可以看出不同的虚拟地址所对应的cache属性不一样,实际使用时根据不同的需求选择不同的空间使用。

2.4 初始化内核临时页表

内核临时页表在系统使能mmu到使用虚拟地址运行这段期间使用。内核临时页表使用__mmu_ttlb_begin来表示,其虚拟地址保存在g_mmuJumpPageTable这个指针中,g_mmuJumpPageTable在kernel\liteos_a\arch\arm\arm\src\los_arch_mmu.c中定义,如下图所示。

内核临时页表__mmu_ttlb_begin的位置在2.2小节已经分析过是在链接脚本中确定的。

系统首先将内核临时页表清零,这个操作和之前清零内核页表是一样的,如下图所示。

注意图中有一条语句:orr r8, r4, #MMU_TTBRx_FLAGS,这句话的意思的将内核页表物理基址值或上mmu属性标志后的值保存在r8中,这个值也就是页表寄存器的初始化值。

内核临时页表清零后接着计算当前代码的虚拟地址和物理地址分别是在哪两个个1MB段内,并对这两个段建立和当前代码所在的物理地址段映射,如下图所示。

 

其中一个段所对应的物理地址和虚拟地址是一一对应的,至于为什么要这样做,在分析mmu设置代码时会分析到,这里只要知道内核临时页表设置了两个页表项即可,如下图所示。

2.5 设置mmu

mmu的设置代码如下图所示。

我们这里只分析比较重要的操作,首先将内核临时页表物理基址和mmu属性或起来的值设置到页表基址寄存器中,如下图所示。

注意这时仅仅是设置了内核临时页表基址,mmu还未使能,紧接着操作系统寄存器使能mmu和i/d cache,如下图所示。

这时mmu使能了,使用的是内核临时页表,这时cpu访问内存不管是取指令还是访问数据都是需要进过mmu来翻译了,但是在mmu使能之前cpu使用的都是内核的物理地址,即使现在使能了mmu,cpu访问的地址值还是内核的物理地址值(这里仅仅从数值上来看),而又由于mmu使能了,所以cpu会把这个值当做虚拟地址的值到页表中去找其对应的物理地址来访问。所以现在明白了为什么要在内核临时页表里建立一个内核物理地址和虚拟地址一一映射的页表项了吧,因为建立了一一映射,cpu访问的地址经过mmu翻译得到的还是和原来一样的值,这样在cpu真正使用虚拟地址之前也能正常运行。

接着通过一句ldr pc, =1f来强制将cpu用虚拟地址工作,因为之前已经在内核临时页表中建立了内核虚拟地址和物理地址的映射关系,所以这时候cpu能正常工作,如下图所示。

接着重新设置了页表寄存器的值为r8的值,r8的值我们在2.4小节分析过,这时保存的是内核真正工作页表的初始化值,通过设置系统寄存器进行页表的切换,如下图所示。

因为lr中保存的是mmu使能之前返回地址的物理地址值,这时需要转换为虚拟地址,转换算法也很简单,虚拟地址=物理地址-r11,然后返回即可。

2.6 初始化各个cpu模式下的栈

首先判断当前cpu是否是主核,如果是主核则执行栈初始化操作,如果是从核的话就不需要初始化了,如下图所示。

接着对栈空间进行了初始化,如下图所示。

__undef_stack到__exc_stack_top之间的内存都是用作cpu各个模式下的栈空间,如下图所示。可以看出这里的栈是所有cpu核用的。

stack_init函数也很简单,就是用OS_STACK_INIT这个数值初始化整个栈空间,如下图所示。

STACK_MAGIC_SET这个宏如下图所示,这个宏有三个参数:

  • 栈起始地址
  • 栈大小
  • 栈要初始化的数值

excstack_magic函数也很简单,就是将栈空间设置为固定的值,如下图所示。

2.7 设置各个模式的栈地址

接着将各个模式下的栈地址设置到对应模式下的栈指针sp寄存器中,如下图所示。

EXC_SP_SET宏有三个参数,如下图所示。

  • 栈起始地址
  • 栈大小
  • 当前cpu id

sp_set函数就是根据cpu id来计算正确的栈地址值并设置到sp中,如下图所示。

2.8 使能fpu+neon

这个就是一些系统寄存器的操作,如下图所示。

2.9 bss段清零

首先判断当前cpu是不是主核,如果是主核,则执行bss段清零,如果是从核则不需要执行bbs段清零,如下图所示。

2.10 跳转c语言main函数

从汇编跳转c语言的前提是设置好栈地址,这个在前面已经设置好了,这里直接跳到main函数执行,main函数在kernel\liteos_a\platform\main.c中,如下图所示。

 

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
华为鸿蒙系统正式版PC下载是华为官方打造的操作系统,是建立在linux开源内核的基础上开发的,华为鸿蒙系统正式版PC下载不仅仅内置了火狐、谷歌、opera等主流浏览器的使用,还会为用户带来自带的办公软件使用,方便快捷,无需另外下载安装使用,可支持的游戏也是非常的多的,不会有广告、捆绑的软件,绿色安全可靠,是当前非常受欢迎的一款操作系统。 华为鸿蒙系统正式版PC下载介绍: 华为鸿蒙系统正式版PC下载基于微内核的全场景分布式的操作系统鸿蒙操作系统将基于四个框架为主题,分别是:分布架构、天生流畅、内核安全、生态共享,精简代码结构,将系统的代码全部都进行分布并细化处理,全面解决系统响应缓慢,操作简单,容易上手。 华为鸿蒙系统正式版PC下载亮点: 1、在智慧屏幕、穿戴设备、车机专有服务、音箱、手机等都会进行终端的无缝协同的体验。 2、还率先采用了高性能的IPC技术,将彻底解决系统性能不足、卡顿的问题。 3、Harmony鸿蒙OS采用全新的微内核的射击,保证系统流畅和信息安全这两块巨头。 4、是全世界第一个基于微内核的全场景OS,有分布式架构支撑,能带来天生流畅、内核级的安全和生态共享。 华为鸿蒙系统正式版PC下载四个框架说明: 1、分布架构 将每一个大的系统框架进行更为细致的细化,让应用对于软件的响应程度微乎其微,直接的提高了系统的使用效率。 2、天生流畅 精简大量底层的系统冗余程序代码,还原用户的系统体验流畅度。 3、内核安全 将在关键的用户交互方面下功夫,在用户与系统软件的交互方面,放置多层由安全中心响应的源生代码,从源头保证系统的整体安全。 4、生态共享 在每一个智能的终端设备上,都会就行在交互方面的自动适配,自动寻找最符合条件的那个设备。 华为鸿蒙系统正式版PC下载安装方法: 1.插入U盘,打开U盘制作软件rufus 3.1 2.入设备选项,选中下载的华为鸿蒙系统镜像文件,其他默认,点击开始。 3.链接下载点击是,勾选以ISO镜像模式写入。 4.点击OK,等待U盘启动制作并写入华为鸿蒙系统完成。 5.把制作好的U盘插入电脑,开机启动按F12,选择U盘启动,台式机一般为:Delete键笔记本一般为:F2键惠普笔记本一般为:F10键联想笔记本一般为:F12键苹果电脑为:C键。 6.从U盘启动后,选择“Start Newstart Dev”进入安装。 7.系统会进入到安装界面,我们点击“安装系统”开始安装。 8.选择将华为鸿蒙系统安装所在硬盘分区,再点击下一步。 9.设置完管理员密码后,在右下角点击“开始安装”进行安装系统。 10.进入安装,10多分钟就安装完成了,非常简单。安装过程中请保证电脑电量,而且不能拨插U盘,否则得重来。 11.安装成功后,点击“重启”,拨出U盘,系统重启后就进入登录界面,输入先前创建的用户名及密码,就可以体验华为鸿蒙系统。 华为鸿蒙系统正式版PC下载测评: 1、面向多终端设计,并且开源。可打通智慧屏、可穿戴设备、车机、音响、手机等。 2、能够实现每一个电子终端的资源互享,带来用户体验最佳的协同感。 3、系统软件轻量化、功能强大,将在大量的智能终端上进行率先应用。 4、通过对原生态的系统进行精简,删减掉那些用户在日常生活中用不到系统软件,还原系统的流畅度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值