LiteOS树莓派移植指南(二)
移植介绍
对于嵌入式设备,由于芯片型号和外设差异较大,且资源有限,所以物联网操作系统无法像 Windows/Linux 那样适配集成所有驱动,因此通常会先适配部分芯片/开发板。为了让操作系统运行在其他芯片/开发板上,首先需要进行移植。
硬件信息
开发板:Raspberry Pi 3 Model B(树莓派3B)
CPU:Broadcom BCM2837
主频:1.2GHz
内存:1GB
Gpu: VideoCore IV GPU
移植准备
由于armv8-A AArch32 完全向后兼容armv7,因此可以通过参考树莓派2B《LiteOS树莓派移植指南》来适配树莓派3B。
硬件环境
本次移植使用了Raspberry Pi 3 Model B开发板、USB转TTL模块、SDcard和读卡器。
软件环境
本次移植需要先按照码云(gitee)上的LiteOS教程搭建好linux开发环境(make、arm-none-eabi编译工具链)。环境搭建教程为:https://gitee.com/LiteOS/LiteOS/blob/master/doc/LiteOS_Build_and_IDE.md。
本次移植需要下载树莓派官方的镜像制作工具(Raspberry Pi Imager),
下载地址为:https://www.raspberrypi.org/software/ 。
移植步骤
在Raspberry_Pi3B开发板上移植适配LiteOS的主要步骤如下:
创建目录结构
在targets目录下复制Raspberry_Pi2B目录并重命名为Raspberry32_Pi3B。拷贝targets\qemu-virt-a53\include\asm\dma.h文件到Raspberry32_Pi3B\include\asm目录下:
目录/文件 |
说明 |
Inc |
芯片外设配置的头文件 |
include |
系统相关配置头文件 |
os_adapt |
适配的接口文件 |
Src |
芯片外设配置的源文件 |
liteos.ld |
当前开发板工程的链接文件 |
Makefile |
当前开发板工程的Makefile |
los_startup_gcc.S |
芯片启动文件 |
表1 目录结构
设置异常向量表
在los_startup_gcc.S中设置System Control Register寄存器的第13bit为0,表示异常向量表的基地址从0开始。代码如下所示:
/* set vector base 0x00000000 */
mrc p15, 0, r0, c1, c0, 0
bic r0, #(1 << 13)
mcr p15, 0, r0, c1, c0, 0
System Control Register寄存器第13bit如下所示:
[13] |
V |
V Vectors bit. This bit selects the base address of the exception vectors: 0:Normal exception vectors, base address 0x00000000. Software can remap this base address usingthe VBAR. 1:High exception vectors, base address 0xFFFF0000. This base address is never remapped.The primary input VINITHI defines the reset value of the V bit. |
添加MMU功能
MMU(Memory Management Unit):主要用于虚拟地址到物理地址的转换和访问权限控制。更多MMU功能请参考文末链接。
• 设置L1页表表项
在main.c增加如下设置L1页表表项代码(本次MMU只涉及L1页表),将4G虚拟内存线性映射到物理地址。
VOID MmuSectionInit(VOID)
{
UINT32 ttbBase = (UINTPTR)g_firstPageTable;
/* First clear all TT entries - ie Set them to Faulting */
(VOID)memset_s((VOID *)(UINTPTR)ttbBase, MMU_16K, 0, MMU_16K);
/* Set all mem 4G as uncacheable & rw first */
X_MMU_SECTION(0, 0, (MMU_4G >> SHIFT_1M),
UNCACHEABLE, UNBUFFERABLE, ACCESS_RW, NON_EXECUTABLE, D_CLIENT);
X_MMU_SECTION(0, 0, ((AUX_BASE - 1) >> SHIFT_1M),
CACHEABLE, BUFFERABLE, ACCESS_RW, EXECUTABLE, D_CLIENT);
}
• 在los_startup_gcc.S文件中添加以下代码开启MMU
1.无效TLB所有表项
mcr p15, #0, r0, c8, c7, #0
注:TLB(Translation Lookaside Buffer)相当于页表的Cache。
2.设置DOMAIN0和DOMAIN01的访问权限
mov r0, #(DOMAIN0 | (DOMAIN1 << 2))
mcr p15, 0, r0, c3, c0
注:CP15中的寄存器C3定义了ARM处理器的16个域的访问权限。(具体请参考文末相关文档)
3.设置MMU L1页表基地址
ldr r0, =g_firstPageTable
mcr p15, #0, r0, c2, c0, #0
4.开启MMU和cache
/* enable mmu */
mrc p15, #0, r0, c1, c0, #0
orr r0, r0, #1
mcr p15, #0, r0, c1, c0, #0
/* enable icache */
mrc p15, #0, r0, c1, c0, #0
orr r0, r0, #(1 << ICACHE_BIT)
mcr p15, #0, r0, c1, c0, #0
mrc p15, #0, r0, c1, c0, #0
orr r0, r0, #(1 << DCACHE_BIT)
mcr p15, #0, r0, c1, c0, #0
注:更多协处理器请参考链接:https://developer.arm.com/documentation/ddi0464/f?lang=en 。
添加SMP功能
• 在los_startup_gcc.S文件中增加如下代码:
1. 增加获取cpu id代码
mrc p15, 0, r11, c0, c0, 5
and r11, r11, #MPIDR_CPUID_MASK
MPIDR寄存器bit[1:0]如下所示:
[1:0] |
CPU ID |
Indicates the processor number in the Cortex-A7 MPCore processor. For: • One processor, the CPU ID is 0x0. • Two processors, the CPU IDs are 0x0 and 0x1. • Three processors, the CPU IDs are 0x0, 0x1, and 0x2. • Four processors, the CPU IDs are 0x0, 0x1, 0x2, and 0x3. |
2.增加如下判断(用于避免全局资源重复初始化):
cmp r11, #0
bne excstatck_loop_done
3. 增加其他核入口(secondary_cpu_start函数具体实现请参考main.c中的实现):
cpu_start:
#ifdef LOSCFG_APC_ENABLE
bl setup_mmu
#ifdef LOSCFG_KERNEL_SMP
bl secondary_cpu_start
#endif
#endif
b .
• 在main.c中添加如下代码:
for (coreId = 1; coreId < LOSCFG_KERNEL_CORE_NUM; coreId++) {
/* per cpu 4 mailbox */
mailbox->writeSet[coreId * 4 + MAILBOX3_IRQ - MAILBOX0_IRQ] = (UINT32)reset_vector;
asm volatile ("sev");
}
while (LOS_AtomicRead(&g_cpuNum) < LOSCFG_KERNEL_CORE_NUM) {
asm volatile("wfe");
}
注:主核通过mailbox机制唤醒其他核,并等待其他核启动。
• 在drivers/interrupt/arm_control.c文件添加ipi中断代码。参考树莓派官方芯片手册中的mailbox机制来实现HalIrqSendIpi函数和HalSmpIrqInit函数。
适配编译配置
• 在targets/kconfig.raspberry文件添加如下代码:
config LOSCFG_PLATFORM_RASPBERRY32_PI3B
bool "Raspberry32_Pi3B"
select LOSCFG_ARCH_CORTEX_A53_AARCH32
select LOSCFG_USING_BOARD_LD
select LOSCFG_PLATFORM_ARM_CONTROL
select LOSCFG_RASPBERRY_PI_SYSTICK
• 修改以下Makefile:
driver/timer/Makefile
driver/interrupt/Makefile
targets/Raspberry32_Pi3B/Makefile
注:树莓派3B开启SMP功能后systick使用generic time,否则使用arm side timer。
制作启动SDcard
使用Raspberry Pi Imager工具制作Raspberry Pi系统。
Raspberry Pi Imager 下载链接:https://www.raspberrypi.org/software/
• 将编译生成的kernel7.img文件替换掉SDcard中kernel7.img文件。
• 将写入镜像文件的SDcard插入树莓派3B中并上电,树莓派3B即可运行LiteOS系统。
运行结果如下:
********Hello Huawei LiteOS********
LiteOS Kernel Version : 5.1.0
Processor : Cortex-A53 * 4
Run Mode : SMP
build time : Aug 21 2021 10:15:24
**********************************
OsAppInit
cpu 0 entering scheduler
cpu 1 entering scheduler
cpu 2 entering scheduler
cpu 3 entering scheduler
Huawei LiteOS #
至此,LiteOS系统成功启动和运行。该移植工程已经在Gitee LiteOS社区上线,
相关代码链接地址为:https://gitee.com/LiteOS/LiteOS/tree/master/targets/Raspberry32_Pi3B 。
相关文档地址
MMU 访问权限控制:https://blog.csdn.net/llf021421/article/details/6330102
MMU 访问权限控制:https://blog.csdn.net/llf021421/article/details/6330102
MMU cache和writebuffer:https://blog.csdn.net/fcglx/article/details/87924578
MMU 页表:https://blog.csdn.net/czg13548930186/article/details/74979222
树莓派官方芯片手册:
https://datasheets.raspberrypi.org/bcm2835/bcm2835-peripherals.pdf
结语
至此,LiteOS系统成功启动和运行。该移植工程已经在Gitee LiteOS社区上线,相关代码链接地址为:https://gitee.com/LiteOS/LiteOS/tree/master/targets/APM32F103_Geehy
感谢您的阅读,有任何问题、建议,都可以留言给我们,让我们一起进步:
https://gitee.com/LiteOS/LiteOS/issues
为了更容易找到“LiteOS”代码仓,建议访问https://gitee.com/LiteOS/LiteOS,关注“ Watch”、点赞“Star”、并“Fork”到自己账号下,如下图。
-end-
- 点赞
- 收藏
- 关注作者
评论(0)