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)