[deepin exploration] (转载)将操作系统移植到新的芯片架构
Tofloor
poster avatar
李成小飞
deepin
2024-09-27 19:23
Author

RT-Thread 维护者从将嵌入式系统操作系统移植到不同的芯片架构中学到了什么:

image.png

曾经有人问我,为什么计算机被称为“计算机”,因为它们所做的不仅仅是计算数字。现代 PC 可以浏览 Internet、播放音频和视频、为视频游戏和电影生成精美的图形、模拟和预测复杂的天气模式和流行病学风险、使建筑和工程蓝图栩栩如生等等。

计算机之所以能做到这一切,是因为所有这些问题都可以用数值方程式来表示,而计算机的 CPU(它的中央处理单元)实际上只不过是一个简单的计算器。

要让 CPU 向硬盘驱动器发送信号以写入数据或向监视器发送信号以显示图像,它必须接收指令。这些指令以 “code” 的形式出现,这是一种简洁的方式,表示必须有人编写一个与 CPU “说”相同语言的程序。CPU 理解机器语言,机器语言是大多数人类懒得手动写出的几乎难以理解的位数组。相反,我们使用 C、C++、Java、Python 等编程语言。这些语言被解析并编译成机器语言,然后传送到 CPU。

如果您尝试用 CPU 不理解的语言指示 CPU,CPU 将不知道该怎么做。通过尝试从 x86_64 RHEL 映像引导 Raspberry Pi,您可以体验到这种错误通信尝试的相当不引人注目的结果。如果它能奏效就好了,但事实并非如此。

将操作系统移植到新架构

RT-Thread 项目为嵌入式系统程序员提供了一个开源操作系统 (OS)。嵌入式空间非常多样化,有很多物联网 (IoT)、定制工业和业余爱好者设备。RT-Thread 的目标是让每个人都能轻松进行嵌入式编程,无论您使用什么设备。有时,这意味着将操作系统移植到新的架构,无论是相同架构但指令集略有不同的芯片,还是完全不同的新架构。

一开始解决这个问题可能有点吓人——你可能不知道从哪里开始或如何开始。本文收集了 RT-Thread 维护者在将 RTOS 移植到新芯片架构时学到的经验教训。

开始之前需要了解的内容

这是一个看似不可逾越的过程的高级视图。这可能因您的项目而异,但从概念上讲,这是相对通用的,即使某些细节不同:

准备 C 语言执行环境

确认可以通过串行端口发送和接收字符

确认上下文切换代码有效

获取支持的硬件计时器

确认中断例程可以通过串行端口接收和解析数据

执行模型

对于大多数高级体系结构,操作系统和用户应用程序以不同的权限级别运行。这可以防止故障代码影响操作系统的集成和安全性。例如,在 ARMv7-A 架构中,操作系统通常以系统模式运行,而在 ARMv8-A 中,操作系统可以在 EL2 或 EL3 权限级别运行。

通常,芯片在开机时以最高权限级别执行启动代码。但是,在此之后,OS 会将权限级别切换到其目标模式。

1. 执行 C 代码

此步骤中的关键操作是将块起始符号 (.bss) 部分设置为零并设置堆栈指针。

在 C 语言实现中,未初始化的全局变量和静态变量通常存储在 .bss 部分中,该部分不占用存储设备中的任何空间。加载程序时,将在内存中分配相应的空间并初始化为零。当操作系统启动时,它必须自己完成这项工作。

另一方面,OS 必须初始化堆栈空间并设置堆栈指针。由于 C 语言程序在进入和退出函数时会在堆栈上保存和恢复局部变量,因此必须在调用任何 C 函数之前设置堆栈指针。RT-Thread 必须为每个新创建的线程执行此步骤。

2. 至少使用一个串行驱动器

RT-Thread 通过串口输出信息和日志,这也有助于在移植过程中调试代码。在此阶段,不需要通过串行端口接收数据。当我们第一次在串行端口上看到我们友好、熟悉的 RT-Thread 标志时,我们知道我们走在正确的轨道上!

3. 确认上下文切换逻辑

任务的上下文是其整个执行环境,其中包含泛型寄存器、程序计数器、堆栈帧的位置等。当创建新线程时,RT-Thread 必须手动分配和设置其上下文,以便调度器可以切换到新线程,就像对其他线程所做的那样。

有三件事需要注意:

首先,当 RT-Thread 启动时,中断默认是关闭的。首次启用任务计划程序时,将启用它们;此过程在上下文切换期间以汇编语言实现。

其次,下一个调度将在线程退出时开始,此时拥有的资源被空闲线程回收。

第三,数据被推送到堆栈中的顺序必须与数据从堆栈中弹出的顺序一致。

通常,您希望正常进入 main 功能和 msh 控制台。但是,由于未实现串行输入中断,因此在此阶段无法实现 input control。当 serial interrupts 被实现时,可以进行 msh 输入。

4. 设置计时器

RT-Thread 需要一个定时器来周期性地产生中断;这用于计算自系统启动以来经过的时钟周期。Tick 数字用于提供软件中断功能,并指示内核何时开始调度任务。

设置时间片的值可能是一项棘手的工作。通常是 10 毫秒到 1 毫秒。如果您在较慢的 CPU 上选择较小的时间片,则大部分时间都花在任务切换上,从而不利于完成其他任何事情。

5. 确认串口工作正常

在这一步中,我们通过串口与 RT-Thread msh 进行了交互。我们发送命令,按 Enter,然后观察 msh 执行命令并显示结果。

这个过程通常不难实现。不过,需要注意的是:在处理串行端口中断后,不要忘记清除某些平台上的中断标志。

一旦串行端口正常工作,移植过程就基本完成了!

忙碌起来

要将项目移植到不同的芯片架构,您需要非常清楚目标芯片的架构。熟悉项目最关键点的底层代码。通过交叉引用芯片手册,结合大量的实际工作经验,您将学习芯片权限模式、寄存器和编译方法。

原文将操作系统移植到新的芯片架构

Reply Favorite View the author
All Replies
放屁大王
deepin
2024-09-27 20:15
#1

沙发

Reply View the author
放屁大王
deepin
2024-09-27 20:15
#2

like like

Reply View the author
Oli
deepin
2024-09-27 21:00
#3

涨知识了

Reply View the author
乾豫恒益
deepin
2024-09-28 09:16
#4

like like

Reply View the author
麻烦告诉我小浣熊哪里有
deepin
2024-09-28 22:56
#5

like like

Reply View the author
hinata
deepin
2024-10-01 22:21
#6

要不说你能学到知识么

Reply View the author
新手来啦~
deepin
2024-10-02 22:44
#7

like

Reply View the author