我是靠谱客的博主 明亮篮球,这篇文章主要介绍全志D1-H哪吒上裸机执行 rt-thread 的 rt-smart os前言uboot哪吒的 uboot 和 nand构建 nand 和引导自己的系统上电,现在分享给大家,希望可以做个参考。

前言

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

和 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 信息

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
mdtparts default mtdparts # 输出如下: device nand0 <nand>, # parts = 4 #: name size offset mask_flags 0: boot0 0x00100000 0x00000000 1 1: uboot 0x00300000 0x00100000 1 2: secure_storage 0x00100000 0x00400000 1 3: sys 0x0fb00000 0x00500000 0 active partition: nand0,0 - (boot0) 0x00100000 @ 0x00000000 defaults: 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 中的信息

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
ubi part sys ubi info l # 输出如下: Volume information dump: vol_id 0 reserved_pebs 1 alignment 1 data_pad 0 vol_type 4 name_len 3 usable_leb_size 258048 used_ebs 1 used_bytes 258048 last_eb_bytes 258048 corrupted 0 upd_marker 0 name mbr Volume information dump: vol_id 1 reserved_pebs 1 alignment 1 data_pad 0 vol_type 3 name_len 13 usable_leb_size 258048 used_ebs 1 used_bytes 258048 last_eb_bytes 258048 corrupted 0 upd_marker 0 name boot-resource Volume information dump: vol_id 2 reserved_pebs 1 alignment 1 data_pad 0 vol_type 3 name_len 3 usable_leb_size 258048 used_ebs 1 used_bytes 258048 last_eb_bytes 258048 corrupted 0 upd_marker 0 name env Volume information dump: vol_id 3 reserved_pebs 1 alignment 1 data_pad 0 vol_type 3 name_len 10 usable_leb_size 258048 used_ebs 1 used_bytes 258048 last_eb_bytes 258048 corrupted 0 upd_marker 0 name env-redund Volume information dump: vol_id 4 reserved_pebs 29 alignment 1 data_pad 0 vol_type 3 name_len 4 usable_leb_size 258048 used_ebs 29 used_bytes 7483392 last_eb_bytes 258048 corrupted 0 upd_marker 0 name boot ...

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

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

复制代码
1
2
3
4
5
6
7
8
boot_normal=sunxi_flash read 45000000 ${boot_partition};bootm 45000000 boot_partition=boot bootcmd=run setargs_nand_ubi boot_normal partitions=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=rootfs setargs_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前言uboot哪吒的 uboot 和 nand构建 nand 和引导自己的系统上电的全部内容,更多相关全志D1-H哪吒上裸机执行内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部