RT-Thread Smart(簡稱rt-smart)是基于RT-Thread操作系統(tǒng)衍生,面向帶MMU(Memory Management Unit),中高端應(yīng)用的芯片,例如ARM Cortex-A,MIPS,帶MMU的RISC-V芯片等。rt-smart在RT-Thread操作系統(tǒng)的基礎(chǔ)上啟用獨(dú)立、完整的進(jìn)程方式,同時(shí)以混合微內(nèi)核模式執(zhí)行。
自 V5.0.0 起,rt-smart 分支已合并至 rt-thread master 分支上,可以在 bsp 下通過 menuconfig 啟用Enable RT-Thread Smart (microkernel on kernel/userland)選項(xiàng)即可使用 rt-smart。
目前有 allwinner 下 d1/d1s , bouffalo_lab 下的 bl808/d0 ,raspi4-64,qemu-virt64-aarch64,qemu-virt64-riscv 等多個(gè)bsp已經(jīng)支持 rt-smart。
本文通過介紹 RISC-V64 架構(gòu)的 BL808,介紹適配 rt-smart 與 rt-thread 區(qū)別點(diǎn),從零開始適配一個(gè)支持 rt-smart 的 bsp。
BL808是RISC-V三核異構(gòu)架構(gòu),分別為m0(E907/RV32IMA)、lp(E902/RV32E[M]C)、d0,(C906/RV64IMA[FD]C[V])都采用的是平頭哥的玄鐵RISC-V核,
RISC-V有3種工作狀態(tài),分別為機(jī)器模式machine mode(M態(tài))、監(jiān)督模式supervisor mode(S態(tài))、用戶模式user mode(U態(tài))。
RISC-V架構(gòu)定義機(jī)器模式為必選模式,另外兩種模式為可選模式,通過不同的模式組合可以實(shí)現(xiàn)不同的系統(tǒng),C906同時(shí)支持M/S/U態(tài)。
rt-smart工作在S態(tài),需要MMU支持。C906 虛擬內(nèi)存管理 MMU兼容 RISC-V Sv39 虛擬內(nèi)存系統(tǒng)。rt-smart和工作在M態(tài)的RT-Thread 標(biāo)準(zhǔn)版有較多不同。
啟動(dòng)
在適配RT-Thread標(biāo)準(zhǔn)版本,芯片工作在M態(tài)(芯片啟動(dòng)默認(rèn)狀態(tài)),啟動(dòng)文件一般采用原廠SDK提供的啟動(dòng)文件完成硬件初始化(操作M態(tài)下的寄存器)、bss初始化等軟件初始化工作,跳轉(zhuǎn)到entry()函數(shù)即可開始rt-thread流程,剩下的工作在rt_hw_board_init()函數(shù)中完成。
bl808-d0核運(yùn)行在S態(tài),芯片啟動(dòng)默認(rèn)工作在M態(tài),芯片需要通過一些流程,將opensbi、kernel等相關(guān)代碼從flash上copy到ram上,并通過opensbi芯片切換到S態(tài)。opensbi完成一些了配置后跳轉(zhuǎn)到rt-smart(kernel)。
rt-smart此時(shí)工作在S態(tài),不能操作任何M態(tài)下的寄存器,只能操作S態(tài)下的寄存器,否則會(huì)發(fā)生異常。
C906啟動(dòng)文件startup_gcc.S在libcpu/risc-v/t-head/c906目錄下,在bsp下需要完成init_bss()、primary_cpu_entry()兩個(gè)函數(shù),這兩個(gè)函數(shù)作用為清除bss區(qū)、禁止全局中斷,調(diào)用entry()進(jìn)入rt-smart主流程。
此外 startupgcc.S 會(huì)調(diào)用 stack_start 變量和 STACKSIZE 宏,賦值給 sp , STACKSIZE 宏在 Kconfig 配置,內(nèi)置腳本會(huì)自動(dòng)生成 linkstacksize.lds 文件,并在 link.ld 文件中被調(diào)用,__stack_start
在 link.ld 中自動(dòng)生成。
進(jìn)入entry后,rt-thread初始化流程基本一致,內(nèi)核已經(jīng)通過RT_USING_SMART宏作了處理,在Kconfig開啟該宏即可。
ld文件
RT-Thread標(biāo)準(zhǔn)版適配的時(shí)候,一般也采用原廠SDK中提供的ld文件,做一些適當(dāng)?shù)男薷暮蠹纯墒褂谩?br /> bl808-d0核運(yùn)行在S態(tài)下,啟動(dòng)文件和ld文件都不能使用原廠SDK中的文件。RISC-V可參考 qemu-virt64-riscv 、 allwinner 下 d1/d1s 等bsp,復(fù)制對應(yīng)的 link.ld 文件,并根據(jù)自己的芯片、開發(fā)板內(nèi)存修改 Memory layout。
MEMORY
{
SRAM : ORIGIN = 0x50100000, LENGTH = 63M
}
SECTIONS
{
. = 0x50100000 ;
}
該地址為rt-smart程序開始地址,與bootload、opensbi等跳轉(zhuǎn)地址一致。
中斷
bl808-d0核工作在S態(tài),中斷相關(guān)操作與M態(tài)不一樣,同樣不能使用原廠SDK中的相關(guān)接口,rt-thread提供相關(guān)S態(tài)下中斷管理的一系列函數(shù)。包括:
rt_hw_interrupt_init()
rt_hw_interrupt_install()
rt_hw_interrupt_mask()
rt_hw_interrupt_umask()
操作S態(tài)下的外設(shè)中斷時(shí)需使用這一套接口,相關(guān)函數(shù)實(shí)現(xiàn)在libcpu/risc-v/t-head/c906/interrupt.c文件下。
Kconfig 配置
bl808-d0核運(yùn)行在S態(tài),必須開啟ARCH_RISCV64、ARCH_MM_MMU、RT_USING_CACHE這三個(gè)宏,否則會(huì)編譯不過。
bl808相關(guān)配置在bsp/bouffalo_lab/bl808/d0/board/Kconfig下。
config BSP_USING_BL808
bool
select ARCH_RISCV64
select RT_USING_COMPONENTS_INIT
select RT_USING_USER_MAIN
select RT_USING_CACHE
select ARCH_MM_MMU
select BL808_CORE_D0
default y
同時(shí)在上文啟動(dòng)相關(guān)流程中講到需要配置棧空間大小
config STACKSIZE
int "stack size for interrupt"
default 4096
相關(guān)配置在bsp/bouffalo_lab/bl808/d0/Kconfig下。
芯片相關(guān)PLIC地址、IRQ數(shù)量、STimer頻率配置
C906相關(guān)中斷管理、STimer管理都已經(jīng)在libcpu/risc-v/t-head/c906下實(shí)現(xiàn),需要對相關(guān)地址、數(shù)量通過宏配置。相關(guān)配置在bsp/bouffalo_lab/bl808/d0/board/Kconfig下
config C906_PLIC_PHY_ADDR
hex
default 0xe0000000
config IRQ_MAX_NR
int
default 64
config TIMER_CLK_FREQ
int
default 1000000
完成以上配置, bl808-d0 核可以正常工作在S態(tài)下,可以使用 RT-Thread 標(biāo)準(zhǔn)版,需要使用 rt-smart 版還需要完成一些 rt-smart 對應(yīng)的 mmu 初始化、頁表建立等工作。
SMART初始化
bl808-d0核可以正常工作在S態(tài)下,可以通過在Kconfig中選中 RT-Thread Kernel -> Enable RT-Thread Smart (microkernel on kernel/userland) 即可是能rt-smart。
使能 rt-smart 后,在Kconfig根選項(xiàng)中,會(huì)顯示 The virtural address of kernel start 選項(xiàng),該地址為內(nèi)核虛擬地址起始地點(diǎn),bl808-d0核配置為0x50000000。
heap和頁表地址配置
在board.h中根據(jù)實(shí)際芯片或開發(fā)板當(dāng)前RAM情況做配置
extern unsigned int __bss_start;
extern unsigned int __bss_end;
#ifndef RT_USING_SMART
#define KERNEL_VADDR_START 0x0
#endif
#define RT_HW_HEAP_BEGIN ((void *)&__bss_end)
#define RT_HW_HEAP_END ((void *)(RT_HW_HEAP_BEGIN + 16 * 1024 * 1024))
#define RT_HW_PAGE_START RT_HW_HEAP_END
#define RT_HW_PAGE_END ((void *)(KERNEL_VADDR_START + 64 * 1024 * 1024))
bl808芯片內(nèi)封了64M高速psarm,將64M內(nèi)存做了適當(dāng)劃分,分給heap和page。
并在board.c中做了相關(guān)page映射:
rt_region_t init_page_region = {(rt_size_t)RT_HW_PAGE_START, (rt_size_t)RT_HW_PAGE_END};
mmu頁表相關(guān)地址配置
struct mem_desc platform_mem_desc[] = {
{KERNEL_VADDR_START, (rt_size_t)RT_HW_PAGE_END - 1, (rt_size_t)ARCH_MAP_FAILED, NORMAL_MEM},
{0x1000, ((KERNEL_VADDR_START - 1) & 0xfffff000) - 1, (rt_size_t)ARCH_MAP_FAILED, DEVICE_MEM},
};
#define NUM_MEM_DESC (sizeof(platform_mem_desc) / sizeof(platform_mem_desc[0]))
其中DEVICE_MEM項(xiàng)將0x1000~0x4FFF1000做了1:1映射,這樣操作 bl808 外設(shè)的時(shí)候,在 0x50000000 之前的寄存器就不需要在做 ioremap 了。否則會(huì)出現(xiàn)如下異常
Unhandled Exception 7:Store/AMO Access Fault
scause:0x0000000000000007,stval:0x0000000010201000,sepc:0x00000000500248b4
--------------Dump Registers-----------------
Function Registers:
ra(x1) = 0x0000000050024cca user_sp = 0x000000005003f840
gp(x3) = 0x000000005003c0a0 tp(x4) = 0x0000000000000000
Temporary Registers:
t0(x5) = 0x0000000000004000 t1(x6) = 0x0000000000000000
t2(x7) = 0x0000000000000001
t3(x28) = 0x0000000000000000 t4(x29) = 0x0000000000000000
t5(x30) = 0x0000000000000000 t6(x31) = 0x0000000000000000
Saved Registers:
s0/fp(x8) = 0x000000005003f860 s1(x9) = 0x0000000000000000
s2(x18) = 0x0000000000000000 s3(x19) = 0x0000000000000000
s4(x20) = 0x0000000000000000 s5(x21) = 0x0000000000000000
s6(x22) = 0x0000000000000000 s7(x23) = 0x0000000000000000
s8(x24) = 0x0000000000000000 s9(x25) = 0x0000000000000000
s10(x26) = 0x0000000000000000 s11(x27) = 0x0000000000000000
Function Arguments Registers:
a0(x10) = 0x0000000000000000 a1(x11) = 0x0000000010201000
a2(x12) = 0x0000000000000004 a3(x13) = 0x0000000000000080
a4(x14) = 0x0000000000000000 a5(x15) = 0x0000000010201000
a6(x16) = 0xfefefefefefefeff a7(x17) = 0x0000000000000007
sstatus = 0x0000000200040100
Supervisor Interrupt Disabled
Last Time Supervisor Interrupt Disabled
Last Privilege is Supervisor Mode
Permit to Access User Page
Not Permit to Read Executable-only Page
satp = 0x800000000005006f
Current Page Table(Physical) = 0x000000005006f000
Current ASID = 0x0000000000000000
Mode = Page-based 39-bit Virtual Addressing Mode
-----------------Dump OK---------------------
--------------Thread list--------------
current thread: (NULL)
--------------Backtrace--------------
riscv64-unknown-linux-musl-addr2line -e rtthread.elf -a -f 00000000500248b0
在rt_hw_board_init()函數(shù)中,進(jìn)入函數(shù)后,添加
#ifdef RT_USING_SMART
/* init data structure */
rt_hw_mmu_map_init(&rt_kernel_space, (void *)(IOREMAP_VEND - IOREMAP_SIZE), IOREMAP_SIZE, (rt_size_t )MMUTable, PV_OFFSET);
/ init page allocator /
rt_page_init(init_page_region);
/ setup region, and enable MMU */
rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, NUM_MEM_DESC);
#endif
對mmu做地址映射,建立頁表等初始化工作,并在最后啟動(dòng) mmu。
然后與RT-Thread標(biāo)準(zhǔn)版流程一致,完成heap、interrupt、uart等硬件初始化后,就可以正常啟動(dòng)rt-smart了。
bl808 rt-thread bsp
當(dāng)前 bl80 8的 bsp 已實(shí)現(xiàn)三核同時(shí)啟動(dòng),位于 bsp/bouffalo_lab/bl808,三核分別采用了不同的 RT-Thread 版本。
-
ARM處理器
+關(guān)注
關(guān)注
6文章
361瀏覽量
41958 -
虛擬機(jī)
+關(guān)注
關(guān)注
1文章
949瀏覽量
28470 -
MMU
+關(guān)注
關(guān)注
0文章
92瀏覽量
18384 -
RT-Thread
+關(guān)注
關(guān)注
31文章
1306瀏覽量
40430 -
RISC-V
+關(guān)注
關(guān)注
45文章
2328瀏覽量
46675
發(fā)布評論請先 登錄
相關(guān)推薦
RT-Smart的資料合集
rt-smart中斷阻塞問題是怎么引起的
快速上手RT-Thread Smart入門指南
基于RT-Thread操作系統(tǒng)衍生rt-smart實(shí)時(shí)操作系統(tǒng)簡介
RT-Thread Smart快速上手入門指南
RT-Thread Smart快速上手
D1S使用rt-smart驅(qū)動(dòng)OLED
樹莓派上rt-smart的應(yīng)用編程入門
![樹莓派上<b class='flag-5'>rt-smart</b>的應(yīng)用編程入門](https://file.elecfans.com/web1/M00/EF/47/pIYBAGCcw_iABaJUAABIAMzjPho193.png)
rt-smart移植分析:從樹莓派3b入手
![<b class='flag-5'>rt-smart</b>移植分析:從樹莓派3b入手](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
RT-Thread Smart 上手指南
![<b class='flag-5'>RT</b>-Thread <b class='flag-5'>Smart</b> <b class='flag-5'>上手</b>指南](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評論