前言

我属于提前批拿到哪吒开发板的,兴奋之余开始研究如何去运行自己的裸机程序,美其名曰:操作系统.

和 mcu 不一样, sbc 级别的 cpu 跑起来要复杂的多,不过好在系统级别的领域,不同的软件分工明确, 我们的裸机程序作为 kernel 部分,等着被引导就好.

尽管 sbc 的系统很复杂, 不过要跑起我们的小小的代码,我们刚开始关心的东西不必要很多.

走出第一步,才能看到后面的广阔天空.

由于没有自己的 OS , 这里用 rt-thread 的 rt-smart 来作为实验验证对象.

uboot

和我们接触的第一个对象就是 uboot , uboot 是哪吒开发板的 bootloader,所以我们要和他搞好关系,了解他,才能让他帮我们完成 kernel 的引导.

哪吒开发板的引导路径大致是这样: BROOM -> spl -> uboot -> [nand | mmc]

通过简单的把玩,发现以下规律, BROOM 中的一级 bootloader 会检测 mmc 和 nand 设备, 如果存在 mmc 设备就会 load mmc boot 分区中的 spl 继续工作, nand 同理.

开发板上有 256MB 的 nand flash, 可以有足够的空间存放我们的程序了, 所以就不考虑 mmc 了.

哪吒的 uboot 和 nand

开发板,接上串口工具,上电,串口中就可以看到系统启动信息了, 如果你什么都不操作就会进入 tina 环境了, 所以开机的时候,连按 s 键盘(和 PC 开机按 F2或者 F10 一样吧) 就可以进入 uboot 环境

如下界面:

先用 mtdparts 查看 nand 信息

mdtparts default
mtdparts
# 输出如下:
device nand0 <nand>, # parts = 4#: name                size            offset          mask_flags0: boot0               0x00100000      0x00000000      11: uboot               0x00300000      0x00100000      12: secure_storage      0x00100000      0x00400000      13: sys                 0x0fb00000      0x00500000      0active partition: nand0,0 - (boot0) 0x00100000 @ 0x00000000defaults:
mtdids  : nand0=nand
mtdparts: mtdparts=nand:1024k@0(boot0)ro,3072k@1048576(uboot)ro,1024k@4194304(secure_storage)ro,-(sys)

从上面可以看到, nand 有四个分区, 前面两个 bootloader , 第三 secure_storage 和我们也没有什么关系, 第四个分区 sys 就是保存用户 os 的地方, 目前就是 tina linux 系统.

查看一下 sys 中的信息

ubi part sys
ubi info l
# 输出如下:
Volume information dump:vol_id          0reserved_pebs   1alignment       1data_pad        0vol_type        4name_len        3usable_leb_size 258048used_ebs        1used_bytes      258048last_eb_bytes   258048corrupted       0upd_marker      0name            mbr
Volume information dump:vol_id          1reserved_pebs   1alignment       1data_pad        0vol_type        3name_len        13usable_leb_size 258048used_ebs        1used_bytes      258048last_eb_bytes   258048corrupted       0upd_marker      0name            boot-resource
Volume information dump:vol_id          2reserved_pebs   1alignment       1data_pad        0vol_type        3name_len        3usable_leb_size 258048used_ebs        1used_bytes      258048last_eb_bytes   258048corrupted       0upd_marker      0name            env
Volume information dump:vol_id          3reserved_pebs   1alignment       1data_pad        0vol_type        3name_len        10usable_leb_size 258048used_ebs        1used_bytes      258048last_eb_bytes   258048corrupted       0upd_marker      0name            env-redund
Volume information dump:vol_id          4reserved_pebs   29alignment       1data_pad        0vol_type        3name_len        4usable_leb_size 258048used_ebs        29used_bytes      7483392last_eb_bytes   258048corrupted       0upd_marker      0name            boot
...

我们看到了一些熟悉的信息,系统镜像的分区表, 就是 tina sdk 打包出来的产物.

那么 uboot 如何引导 nand 中的系统的呢?
使用 printenv 查看一下 uboot 的环境变量,下面列出重要的部分:

boot_normal=sunxi_flash read 45000000 ${boot_partition};bootm 45000000
boot_partition=boot
bootcmd=run setargs_nand_ubi boot_normalpartitions=mbr@ubi0_0:boot-resource@ubi0_1:env@ubi0_2:env-redund@ubi0_3:boot@ubi0_4:rootfs@ubi0_5:dsp0@ubi0_6:recovery@ubi0_7:UDISK@ubi0_8:
root_partition=rootfssetargs_nand_ubi=setenv bootargs ubi.mtd=${mtd_name} ubi.block=0,${root_partition} earlyprintk=${earlyprintk} clk_ignore_unused initcall_debug=${initcall_debug} console=${console} loglevel=${loglevel} root=${nand_root} rootfstype=${rootfstype} init=${init} partitions=${partitions} cma=${cma} snum=${snum} mac_addr=${mac} wifi_mac=${wifi_mac} bt_mac=${bt_mac} specialstr=${specialstr} gpt=1
ubi_attach_mtdnum=3

就以上这几行就可以了, 对我们来说关键作用的只有前 3 行.
bootcmd 这个是 uboot 启动时候执行的变量, 内容是 run setargs_nand_ubiboot_normal

其中 setargs_nand_ubi 是设置 bootargs 的, 是 Linux 关心的东西.
我们主要看 boot_normal

boot_normal 大致含义是 flash 工具读取 ${boot_partition}(解析后是 boot) 位置的数据到内存 0x45000000 的位置, 然后 bootm 引导 0x45000000 位置的内核.

所以,简单的方法就是我们把我们自己的 OS 程序,写入到 nand 中 boot 分区的位置,理论上就可以了.

构建 nand 和引导自己的系统

起初本来想用 xboot 的 xfel 工具将数据写入 nand, 然后发现没有实现,所以先跳过, 等后续支持了就会更方便了.

tina sdk 中 device/config/chips/d1/configs/nezha_min/sys_partition.fex 这个文件是 pack 的配置信息 , 根据文件知道 pack 命令会把 boot.img 打包到 nand 的 boot 分区, 这个就是我们所要的,所以最简单的方法就是把我们自己的 bin 文件替换调 boot.img , 然后 tina sdk 中执行pack ,生成的产物tina_d1-nezha_min_uart0.img中就包含了我们的代码了.

然后用全志的工具,将 tina_d1-nezha_min_uart0.img 烧录到哪吒主板上.第一步就完成了.

这样就可以正常引导了么? 答案是否定的.

在前面 uboot 的引导指令用的是 bootm 45000000, bootm 是引导 linux kernel 的,包含了引导协议的一些东西, 我们作为一个裸机程序,我们可以使用 uboot 的 go 命令之间跳转到 0x45000000处运行, 将 boot_normal 改为 sunxi_flash read 45000000 ${boot_partition};go 45000000 即可, 但是目前 tina 默认的 uboot 没有编译 go 指令, 进入 lichee/brandy-2.0/u-boot-2018 目录, 执行 make menuconfig, 然后在 Command line interface --> Boot commands 中选中 go 指令,保存后,重新编译, 在打包一次就可以了.

tina uboot 默认的环境变量信息在文件 device/config/chips/d1/configs/nezha/env.cfg 里面,可以将 boot_normal 改好后再编译,就不用在 uboot 交互界面中修改环境变量了.

上电

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qwsSFSuY-1645581860288)(/assets/uploads/files/1623079923978-d1-rt-smart.png)]

bingo!

少年, 下一步就开始在哪吒上运行你的 Dreeam OS 吧!

最后的补充注意事项: RISC-V 芯片运行在 SBI 环境, S Mode 下,所以如果裸机程序 M 模式的代码是无法正常运行的.

原贴链接:https://bbs.aw-ol.com/topic/132/
全志在线开发者交流企鹅群(客服机器人24小时在线解答):498263967
资源获取、问题讨论可以到全志在线开发者社区进行:https://www.aw-ol.com/
全志及开发者最新动态可以关注全志在线微信公众号

全志D1-H哪吒上裸机执行 rt-thread 的 rt-smart os相关推荐

  1. RT Thread根据开发板制作BSP方法

    之前一直不懂怎么使用RT Thread的软件包,感谢网上的大神,看了你们的博客后大概了解一些,在此做下记录.用RT Thread软件包需要RT Thread的系统,但是RT Thread和RT Thr ...

  2. 使用sshpass在Linux服务器上批量执行脚本

    用途描述: 如果Linux服务器未配置免密登录,每次使用ssh执行远程脚本时,都需要输入密码. 使用sshpass命令可以在多个Linux服务器上批量执行脚本,操作步骤如下: 1.安装sshpass ...

  3. mac linux 计划任务,Mac上,执行定时任务:launchctl

    在Mac上定时执行任务 在Mac上,执行定时任务,有两种方式: 使用launchctl 沿袭Linux常用的crontab命令 毕竟咱是在mac上开发,这里只讲launchctl的用法 1.首先需要编 ...

  4. 如何在Linux系统上自动执行任务

    How to automate tasks on a Linux system 如何在Linux系统上自动执行任务 https://www.linux.org/threads/how-to-autom ...

  5. GCD6: 在GCD上异步执行非UI相关任务

    讨论:在主队列.串行队列和并发队列上异步执行代码块才能见识到 GCD 的真正实力. 要在分派队列上执行异步任务,你必须使用下面这些函数中的其中一个: dispatch_async为了异步执行向分派队列 ...

  6. 解决.net定时器在iis7上不执行问题

    解决.net定时器在iis7上不执行问题 参考文章: (1)解决.net定时器在iis7上不执行问题 (2)https://www.cnblogs.com/zxayxh1314/p/5103111.h ...

  7. centos上自动执行脚本执行php文件

    centos上自动执行脚本执行php文件 1 先编写执行PHP文件的脚本 vi php.sh #!/bin/sh /usr/bin/php /etc/1.php 2把php.sh添加到自动执行任务中 ...

  8. 关于VMware 15:在部分链上无法执行所调用的函数,请打开父虚拟磁盘

    问题:当使用VMware给虚拟机扩展硬盘容量时,显示无法扩展容量并提示:在部分链上无法执行所调用的函数,请打开父虚拟磁盘. 原因: 在创建虚拟机时使用的是将虚拟磁盘拆分成多个文件(如下图),这个会导致 ...

  9. android游戏基址,Android上可执行ELF文件中的段不能有基址

    Android上可执行ELF文件中的段不能有基址 @(Android研究)[android] [TOC] 场景 我使用Android NDK的编译工具交叉编译qemu项目(编译可在Android上运行 ...

最新文章

  1. Quality Center Issue with CAPICOM.DLL not prop...
  2. json 格式化工具_如何在命令行中优雅地处理JSON
  3. 计算机领域专业术语中英文对照(时常更新)
  4. JS+CSS全力打造的一级横向滑动,二级竖向下拉综合菜单
  5. Uploadify 3.2 参数属性、事件、方法函数详解以及配置
  6. 爱奇艺漫威等系列电影因版权到期下架 会员无补偿
  7. [Swift]LeetCode978. 最长湍流子数组 | Longest Turbulent Subarray
  8. 字符串参数传递与返回值(转)
  9. SharePoint 2010 PowerShell 系列 之 Create List and Field --Lookup
  10. scrapy vs requests+beautifulsoup
  11. 算法:求数的幂次方powx-n
  12. ElastcSearch的Mapping映射建立
  13. Tuxedo 介绍与安装
  14. cfe刷机教程 斐讯k3_玩转斐讯K3详细刷机——直接刷LEDE
  15. Word文档文字尾部加下划线(基于Office 2016)
  16. 罗森伯格成功布线五星蕴海建国饭店
  17. Excel中的LEN和LENB,VBA中的Len和LenB
  18. Vue3+Ant-design项目启用ts/typescript
  19. linux 中dirname的用法
  20. 【Unity Shader】学习顶点/片元着色器

热门文章

  1. 智障者失踪3年被发现在服刑 家属疑其系顶罪
  2. 台历式月历设计制作(C语言)
  3. 如何在Android上恢复已删除的短信
  4. 本地生活小程序有什么功能_本地生活小程序的优势
  5. 什么项目适合采用网络监控系统
  6. 贝医生创始人章骏:做出更适合于中国人的牙刷
  7. Android 热缓解框架解析
  8. Windows 10系统如何打开安全模式
  9. 软件推荐1-mac后端(java)开发常用软件
  10. iOS仿写计算器中缀转后缀 表达式求值