摘要:本文介绍在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

注:更详细的安装指导,请参考官方指南:https://occ.thead.cn/community/download?id=636946310057951232

码源获取

源码获取教程请参考:https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/get-code/sourcecode-acquire.md

移植

移植过程按照已实现的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使用手册(https://occ.t-head.cn/community/download?id=636946310057951232)编写该脚本。

编译运行

编译

• 执行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 : https://gitee.com/openharmony/kernel_liteos_m/tree/master/kernel/arch/csky/v2/gcc

qemu : https://gitee.com/openharmony/device_qemu/tree/master/SmartL_E802

vendor : https://gitee.com/openharmony/vendor_ohemu/tree/master/qemu_csky_mini_system_demo

点击关注,第一时间了解华为云新鲜技术~

OpenHarmony LiteOS C-SKY指令集移植指北的更多相关文章

  1. git宝典—应付日常工作使用足够的指北手册

    最近公司gitlab又迁移,一堆git的命令骚操作,然鹅git命令,感觉还是得复习下——其实,git现在界面操作工具蛮多,比如intellij 自带的git操作插件就不错,gitlab github ...

  2. Python 简单入门指北(二)

    Python 简单入门指北(二) 2 函数 2.1 函数是一等公民 一等公民指的是 Python 的函数能够动态创建,能赋值给别的变量,能作为参传给函数,也能作为函数的返回值.总而言之,函数和普通变量 ...

  3. Python 简单入门指北(一)

    Python 简单入门指北(一) Python 是一门非常容易上手的语言,通过查阅资料和教程,也许一晚上就能写出一个简单的爬虫.但 Python 也是一门很难精通的语言,因为简洁的语法背后隐藏了许多黑 ...

  4. 可能比文档还详细--VueRouter完全指北

    可能比文档还详细--VueRouter完全指北 前言 关于标题,应该算不上是标题党,因为内容真的很多很长很全面.主要是在官网的基础上又详细总结,举例了很多东西.确保所有新人都能理解!所以实际上很多东西 ...

  5. 关于supervisor的入门指北

    关于supervisor的入门指北 在目前这个时间点(2017/07/25),supervisor还是仅支持python2,所以我们要用版本管理pyenv来隔离环境. pyenv 根据官方文档的讲解, ...

  6. 关于Gevent的使用指北

    关于Gevent的使用指北 只是看了入门指南,和一个翻译文档.写一下个人读书心得. 其实看完之后,第一个反映就是asyncio这个系统库,感觉gevent现在所做的一些事情是与asyncio很像的,但 ...

  7. Celery入门指北

    Celery入门指北 其实本文就是我看完Celery的官方文档指南的读书笔记.然后由于我的懒,只看完了那些入门指南,原文地址:First Steps with Celery,Next Steps,Us ...

  8. 后端API入门到放弃指北

    后端API入门学习指北 了解一下一下概念. RESTful API标准] 所有的API都遵循[RESTful API标准]. 建议大家都简单了解一下HTTP协议和RESTful API相关资料. 阮一 ...

  9. 颓废选手在 Ubuntu/Noilinux 下的生存指北

    颓废选手在 Ubuntu/Noilinux 下的生存指北 Hint: 这里的 "#" 都是假注释,复制的时候记得删除 一些基本的生存命令 ctrl + alt + t #调出终端 ...

随机推荐

  1. javascript 比较版本号大小 字符串

    * 不用系统比较大小的函数 // 不考虑字母 function s2i(s) { return s.split('').reduce(function(a, c) { var code = c.cha ...

  2. 获取HTML网页中option标签元素的值

    在进行表单元素的操作时,难免会遇到对option元素的挑选,下面的示例代码能够很好的获取到你option元素选择的值,如果要传递给后端,可通过ajax或者其他方式传递即可. 示例代码 <!doc ...

  3. 洛谷3320 SDOI2015寻宝游戏(set+dfs序)(反向迭代器的注意事项!)

    被\(STL\)坑害了一个晚上,真的菜的没救了啊. 准确的说是一个叫\(reverse\ iterator\)的东西,就是我们经常用的\(rbegin()\) 有一个非常重要的性质 在反向迭代器中,+ ...

  4. Perl 编程 基础用法

    Perl 编程 标准头部写法 #!/usr/bin/perl -w # 标准的头部写法,-w意为显示警告 变量 $a=$b+10 # $a和$b都不需要定义,拿过来就用 Note: $flag=0 如 ...

  5. yum源安装nginx

    nginx使用yum源安装 安装步骤 使用yum源安装依赖 yum install yum-utils 配置nginx.repo的yum文件 vim /etc/yum.repos.d/nginx.re ...

  6. HTTP状态码 详细解析汇总

    一.状态码的类别: 类别 原因短语1XX Informational(信息性状态码) 接受的请求正在处理2XX Success(成功状态码) 请求正常处理完毕3XX Redirection(重定向状态 ...

  7. Bubble和BubbleButton气泡框

    from kivy.app import App from kivy.uix.boxlayout import BoxLayout from kivy.lang.builder import Buil ...

  8. python png图片生成gif

    有时候写代码就是这样别人把代码写好你在后面加一个句号就行了 我很懒不想写成函数,你自己来吧.有注释就不错了 这个依赖一个图像处理库pillow,轮子就是轮他不是车 import imageio imp ...

  9. BUAA_2019_OO_第一单元总结

    一.基于度量来分析自己的程序结构 1.第一次作业 1.1类图: 第一次作业由于比较简单,我采用了面向过程的编程方式.在Polynomail类的构造函数中将项直接求导输出.这样的弊端显而易见,不能进行优 ...

  10. 21.6.17 test

    \(NOI\) 模拟赛. \(T1\) 正解树形DP,由于不是很熟悉概率和期望所以打了个20pts暴力,说不定见多了概率能打出60pts半正解?最后的虚树更不会. \(T2\) 又是概率,还有坐标数量 ...