OpenHarmony LiteOS C-SKY指令集移植指北


摘要:本文介紹在OpenHarmony社區LiteOS-M項目中新增C-SKY指令集的開發流程,以及適配相應qemu工程的方法和步驟,供LiteOS內核相關開發者學習交流。

本文分享自華為雲社區《OpenHarmony LiteOS指令集移植指南(C-SKY)》,作者: Lionlace。

C-SKY指令集體系結構(ISA)是指第二代獨立的指令集體系結構CK-Core系列知識產權指令集體系結構。CSKY ISA具有高性能、高代碼密度、低功耗和可擴展性等特點。

SmartL_E802采用C-SKY V2自主指令架構的E802處理器,是平頭哥半導體有限公司自主研發的低功耗、低成本嵌入式CPU核。其中,SmartL平台是用於E801/E802/E803S/E804/E805/E902/E906/E907集成和調試仿真的綜合演示平台。

本文介紹在OpenHarmony社區LiteOS-M項目中新增C-SKY指令集的開發流程,以及適配相應qemu工程的方法和步驟,供LiteOS內核相關開發者學習交流。

環境搭建

SmartL_E802需要使用官方提供的csky編譯器和qemu工程,以下介紹安裝步驟。

編譯工具鏈安裝

• 獲取csky-elfabiv2編譯器

$ mkdir csky_toolchain && cd csky_toolchain
$ wget https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource/1356021/1619529111421/csky-elfabiv2-tools-x86_64-minilibc-20210423.tar.gz
$ tar -xf csky-elfabiv2-tools-x86_64-minilibc-20210423.tar.gz

• 將編譯工具鏈新增到環境變量

打開~/.bashrc文件

$ vim ~/.bashrc

在末尾加入如下命令行並保存

export PATH=$PATH:用戶自定義路徑/csky_toolchain/bin

使環境變量生效

$ source ~/.bashrc

qemu安裝

• 獲取qemu軟件

$ mkdir csky_qemu && cd csky_qemu
$ wget https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource/1356021/1612269502091/csky-qemu-x86_64-Ubuntu-16.04-20210202-1445.tar.gz
$ tar -xf csky-qemu-x86_64-Ubuntu-16.04-20210202-1445.tar.gz

• 將qemu加入環境變量(user_qemu_xxx_path修改為自己的安裝路徑)

打開~/.bashrc文件

$ vim ~/.bashrc

在末尾加入如下命令行並保存

e export PATH=$PATH:用戶自定義路徑/csky-qemu/bin

使環境變量生效

$ source ~/.bashrc

• 安裝依賴

使用ldd指令查看缺少的依賴庫文件並下載。

$ ldd qemu_installation_path/bin/qemu-system-cskyv2

注:更詳細的安裝指導,請參考官方指南:

碼源獲取

源碼獲取教程請參考:

移植

移植過程按照已實現的riscv的qemu開發板目錄結構新增csky的qemu的目錄結構,並在kernel、device和vendor中實現csky指令集及開發板相關代碼。

新增目錄結構

分別在device、vendor和kernel創建SmartL_E802開發板所需文件。

• 在device/qemu目錄下創建SmartL_E802文件夾,並在該文件夾中新增如下內容:

表1 SmartL_E802文件夾目錄

• 在vendor/ohemu目錄下創建qemu_csky_mini_system_demo文件夾,並在該文件夾中新增如下內容:

表2 開發板文件夾目錄

• 在kernel/liteos_m/kernel/arch目錄下創建csky文件夾,並在該文件夾中新增如下內容:

表3 csky文件夾目錄

修改kernel代碼

在kernel/liteos_m/kernel/arch下創建csky文件夾,並完成以下步驟。

• 新增csky架構的選項

在kernel/BUILD.gn下新增對csky架構的選擇:

else if ("$board_cpu" == "e802") {
deps = [ "arch/csky/v2/gcc:arch" ]
}

• 編寫架構代碼

在kernel/liteos_m/kernel/arch中編寫架構代碼。

a.編寫異常文件-los_exc.S

將前32位異常統一入口為HandleEntry,在HandleEntry函數中保存當前棧 和異常地址並傳參給HalExcHandleEntry函數。該函數將會通過中斷號、g_newTask的值和入參判斷異常發生時所處位置類型(初始化、任務、中斷),並調用OsExcInfoDisplay函數輸出內存檢測結果、函數調用棧回溯結果、任務描述塊信息、異常類型及原因和異常時寄存器狀態。

表4 異常向量分配(圖片來源:平頭哥玄鐵E802用戶手冊)

b.編寫調度代碼-los_dispatch.S

在los_dispatch.S中編寫HalStartToRun函數和HalTaskContextSwitch函數,通過保存及恢復R0~R15、epc、epsr和psr幾個寄存器,實現任務的上下文切換。在los_context.c中適配系統邏輯,編寫任務棧初始化函數並在該文件中調用調度函數。

表5 通用寄存器(圖片來源:平頭哥玄鐵E802用戶手冊)

c.編寫系統中斷文件-los_interrupt.c

將VIC中斷地址VIC_REG_BASE並轉換成結構體,按手冊描述編寫中斷的優先級,屏蔽、使能和清除功能。使用相關中斷匯編指令實現中斷開關,讀取中斷號等功能。

表6 緊耦合IP的內存地址分配(圖片來源:平頭哥玄鐵E802用戶手冊)

d.編寫定時器文件-los_timer.c

取定時器地址CORE_TIM_BASE並轉換成對應的地址結構體,按手冊編寫控制和重載等功能。適配系統獲取cycle等接口。

表7 系統計時器寄存器定義(圖片來源:平頭哥玄鐵E802用戶手冊)

e.在kernel/arch/csky/v2/gcc/BUILD.gn中添加所編寫的文件

static_library("arch") {
…(加入需要編譯鏈接的文件)
}

• 編寫csky架構的backtrace

a.在components/backtrace中增加csky架構的backtrace的相關代碼。通過棧回溯找到函數調用過程中的lr地址並保存,最后在OsExcInfoDisplay中輸出,為用戶分析異常原因提供參考。

b.在kernel/include/los_config.h的LOSCFG_BACKTRACE_TYPE上增加csky架構backtrace的描述。

5: Call stack analysis for c-sky by scanning the stack.

注:架構相關內容詳情請查看平頭哥玄鐵E802用戶手冊。

修改device代碼

在device/qemu下新增SmartL_E802文件夾,並完成以下步驟。

• 移植SDK中代碼到device目錄下

a.將SmartL_E802 SDK驅動代碼整理拷貝到driver目錄內,並編寫BUILD.gn文件編譯驅動代碼。

b.參考SDK中的gcc_csky.ld中寄存器配置修改liteos.ld文件,分配代碼到指定區間。

{
I-SRAM : ORIGIN = 0x0 , LENGTH = 0x20000 /* I-SRAM 128KB */
D-SRAM : ORIGIN = 0x20000000 , LENGTH = 0x20000 /* D-SRAM 128KB */
O-SRAM : ORIGIN = 0x50000000 , LENGTH = 0x800000 /* off-chip SRAM 8MB */
SRAM : ORIGIN = 0x60000000 , LENGTH = 0x20000 /* on-chip SRAM 128KB */
}
…

c.參考SDK中的startup.S文件,刪除vector定義並編寫中斷總入口

.text
.align 2
.global IrqE
IrqEntry:
psrset ee
subi sp, 72
stm r0-r15, (sp)
mfcr r0, epsr
stw r0, (sp, 64)
mfcr r0, epc
stw r0, (sp, 68)
jbsr HalInterrupt
ldw r0, (sp, 68)
mtcr r0, epc
ldw r0, (sp, 64)
bseti r0, r0, 6
mtcr r0, epsr
ldm r0-r15, (sp)
addi sp, 72
rte

• 編寫串口驅動

參考SDK中串口demo和printf實現邏輯,編寫dprintf.c/.h並在main.c中調用串口初始化。

• 適配文件系統

參考LiteOS代碼,將fs適配層文件移植到SmartL_E802中。

• 編寫config.gni文件

參考device/qemu/riscv32_virt中config.gni 的格式,再參考SDK中的編譯選項和需要對外調用的接口,在liteos_m文件夾下編寫config.gni文件。

• 編寫test測試代碼

參考device/qemu/riscv32_virt編寫測試代碼。

• 編寫BUILD.gn文件

編寫BUILD.gn文件,將fs適配層,driver開發板驅動代碼等編譯出來的靜態庫合成liteos可執行文件。

• 編寫README.md

在SmartL_E802文件夾下編寫中英文用戶指南:README_zh.md及README.md,並修改device/qemu目錄下的中英文文檔,新增對csky開發板的介紹。

修改vendor代碼

在vendor/ohemu下創建qemu_csky_mini_system_demo文件夾,並完成以下步驟。

• 拷貝hals/utils文件夾

參考vendor/ohemu/qemu_riscv32_mini_system_demo,在qemu_csky_mini_system_demo文件夾下新增hals/utils文件夾。

• 編寫BUILD.gn文件

參考vendor/ohemu/qemu_riscv32_mini_system_demo,編寫BUILD.gn文件並增加./qemu-run腳本的使用。

• 修改config.json文件

參考vendor/ohemu/qemu_riscv32_mini_system_demo,將其中riscv內容修改為csky相關內容。

• 編寫qemu_run.sh腳本

使用./qemu-run對應的架構腳本,參考vendor/ohemu/qemu_riscv32_mini_system_demo和平頭哥官方提供的qemu使用手冊()編寫該腳本。

編譯運行

編譯

• 執行hb set命令並選擇項目qemu_csky_mini_system_demo;

• 執行hb clean && hb build命令構建產生 liteos 可執行文件。

$ hb set
$ hb clean && hb build

在Qemu中運行鏡像

• 啟動qemu(不配合GDB)

$ ./qemu-run

• 啟動qemu(配合GDB)

a.啟動GDB服務器,等待連接

$ ./qemu-run -g

b.新建終端並使用GDB連接qemu

$ csky-abiv2-elf-gdb out/SmartL_E802/qemu_csky_mini_system_demo/unstripped/bin/liteos -ex "target remote localhost:1234"

注:

1.默認使用帶符號表的elf文件;

2.qemu退出方式為:按下ctrl加a鍵,然后松開再按下x鍵。

qemu運行結果關鍵日志如下:

entering kernel init...
Entering scheduler
Register littlefs done.
../../../third_party/littlefs/lfs.c:1072:error: Corrupted dir pair at {0x0, 0x1}
Littlefs mount at /littlefs/ done.
Littlefs inited.
TaskSampleEntry1 running...
TaskSampleEntry2 running...

本次移植適配的相關源代碼路徑為:

kernel : 

qemu : 

vendor : 

 

點擊關注,第一時間了解華為雲新鮮技術~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM