本文记载深圳OS项目实习的一些见闻。
8月2日 向南
疫情后的湖北(宜昌),还是一种比较严肃的气氛。
似乎高速公路的通行上仍存在一定问题(这个问题应该存在了几年了),跨省界时需要转小型车,再转为宜昌交运客车。当地的客车似乎更高级一些,设备更新,座位有重力感应,这样与安全带插扣联合在一起,便可以保证安全带的使用——只是,空座位上确实不能放置物品了。
听说这几天深圳强降水,有些庆幸选择了高铁前往。如果是飞机,可能又要延误(之后发现确实有人延误。。)。我为数不多的飞行体验中,就有一次接近半天的延误。人们常常夸赞航班的超高安全性,但我却不以为然。飞机的安全性是通过全面“规避风险”来获得的,这意味着飞行本身是一件高风险的事。而火车或者汽车则不一样,它们的基础风险是很低的,它们规避风险的需求也更少。
但,“规避风险”是一件非常强调主观能力的事情。
窗外突然开始下雨。刮大风。并且能见度变得很低。可以在空中看到明显的风雨轨迹。隧道中的应急车道上停靠了大量避雨的私家车。但过了一段距离,雾渐散了。雨也消了。
看到崇山峻岭间有些鬼斧式的地貌。公路和车辆在森林中一闪而过。
人对自然的改造。也是脉络式的改造。
崇山峻岭也隐去了,平原,城市的轮廓浮现出来。
世界太大了。单独的人,单独的建筑,都显得很渺小。思维超出个体时,行为是否能超出个体呢?
高铁上可以明显感到与之前的交通工具在速度上的差异。出发时还是早晨,天气晴朗,云海只淡淡的一层,并形成起伏的波浪线。
没想到中途的站点竟经停武汉。
病毒的风险,何尝又不是一种主观能力上的风险规避。跟航班也有一些相似性。
体验了一把在高铁上点外卖的感觉。结论:太贵。
无论如何舒适的环境,坐久了都会变得不是很舒适。可能还不够舒适?
深圳的城市从宏观上跟北京之类的大都会没有什么区别。但是,细节之处却相当不同。深圳有专门的出租车集散地,这是我在其他省市所从未见过的,深圳的交通似乎更加严格,也许这是一种“先行区”的表现吧?深圳是一座很有活力的城市,从街景的设计中可以看出,一些蓝色的吉祥物(没有认出来是什么),还有雕塑。深圳的非机动车道和人行道镶嵌粘合在一起,这也是其他城市我所未见的新。深圳也许暂时我没有体味到创造的新,但是标新立异的新,确实令人侧目。
到了酒店,直观的感受就是,高端的生活方式真是难以想象的舒适。
室友是来自数学系的大佬,听说为了契合自己的计划,甚至故意挂了科从而可以留校留级。这种认知是反常的,然而在了解之后又立马显得十分自然。
8月3日 实验室
六点多醒了。悠哉游哉到鹏程实验室,脚程大约3分钟。
早餐自助。还是很好吃的。
安排也大致有了:https://github.com/rcore-os/zCore/wiki/zcore-summer-of-code。
今天大概是:rCore 开发历史和选题介绍。
与同学交流选题
上午11:00 B栋一楼合影,3楼参观
中午二楼就餐
晚上:聚餐和小活动
安排。:)
中午吃多了。。控制控制。。
第二届开源操作系统技术研讨会。
没有做完实验的,先把前面六个实验全部做完。
操作系统的用户态、内核态的转换,在rust设计中得到了优化。通过异步的办法,让操作系统的性能有一个巨大的提升。(用户态中断?)
对于传统操作系统,异步的编写很麻烦。在rust中,则可以由编译器来负责完成。rust语言有可能对操作系统有一个本质性的影响。
信号:比如键盘信号,用户态的一个信号。信号处理函数在用户态,平时不激活。很诡异地一个设计,需要把很多东西凑合到一起。
RISC-V中有一个用户态中断。这件事完成后,那么就可以实现在用户态完成信号机制。
第二阶段没有什么参考,所以需要自己规划。
目的:做开源社区。
明天下午国科大本科毕设分享:RISC-V处理器流片背后的故事。
对于树莓派,PCB开源但GPU不开源,ucore移植的图形显示很不好搞,图形渲染不好弄,只能弄图形点阵。
目前有一个对标树莓派的全开源项目,似乎。
周四去华为参观?
龙芯杯似乎有点内卷。。QAQ
我的树莓派4已经吃灰一年了感觉。。未来10年间主流指令集会从x86过渡到arm?
关于zCore-Tutorial的一些特点。自顶向下。逐步替换底层实现。
网络集群的特点就是,每个人都很有特点。这其实有点循环论证的问题。
大二的同学竟然有7位。不禁感叹时光流逝。当年我在大二时,大概才开始学习算法,那年的算法课我也不过是60分飘过。
开源协议赶紧再记一下:
今晚真的要聚餐。
8月4日 一生一芯
今天迟到了。不过好像问题不大。匆匆吃完外带的早餐。
貌似github.io被墙了。
说实话zCore-Tutorial这个东西,现在想参与还是比较无力的。作者wrj本身也就写了一点点内容。但他把一些大纲拟好。
hal(硬件抽象层,Hardware Abstraction Layer),与硬件隔离。
目前支持裸机(Bare Metal),和Linux/Mac OS环境。
rust-analyzer听说很好用。clion听说很好用。
大概了解了一下zCore的结构。
进度资料:2019年操作系统专题训练大实验-Fuchsia OS调研。抽时间了解一下他们都做了些什么,以及进度。
“非典型”微内核。(勉强算微内核)
Fuchsia是Google开发的,可能将用于取代Android。
rCore有实现微内核的潜力,这最终形成了zCore?
国科大本科毕设研讨会——“一生一芯”项目访谈
今天的研讨会终于给人比较正式的感觉。上午的自由讨论,最终只剩下自由,而没有讨论。
注意:一生一芯是指,每一个学生设计一个芯片。
介绍,开发经验,经历分享,未来展望。
余子濠、金越(验证测试)、王华强(前端/DEBUG)、王凯帆(核参数/应用)、张林隽(TLB)、张紫飞(微结构)
第一环节 介绍
- 芯片基本情况
- “果壳”,NutShell
- 一款功能完整的RISC-V处理器
- 国产110nm工艺完成流片(面积10 mm^2),流片一次二十万???
- 有对应的果壳板卡
- SDRAM大型内存操作系统只能跑200MHz。其他内存占用小的OS可以到350MHz。
- SDRAM中途还换了颗粒,一开始只能测试小程序最多128K左右
- 跑分一般
- 4个月的前端开发
自产自销QAQ- 疫情原因,芯片测试并没有实际参与
- 第一版芯片电路(电源线)接错,取指成功,但是会烧掉板子(烧了两块,然后回厂)
- 现在回过头来看, 流片难吗?
- 五位同学主要接触的是前端设计的工作
- 与流片相关的工作:时序逻辑设计要求比较严格
- 流片的时间节点的压力比较大
- 如果之后有问题的话,无法修改
- 爆肝
王凯帆同学中途出国被反复鞭尸QAQ,他的一些软件任务由余博士完成
- 五位同学主要接触的是前端设计的工作
- 什么时候认识到项目的复杂性? 如何应对?
- 课程中老师常常把一些东西黑盒化,但是在项目中需要接触验证的环境(测试程序的正确性),DEBUG比较艰难——了解每一行代码的细节
加强版的龙芯杯QAQ,版本管理很重要- 前期可以黑盒,但后期必须了解硬件外设的细节,比如几千行的 verilog 代码
- 后期开始参与用户态使用时,感觉到复杂性。可能需要引入编程范式?
- 一步一步,任务驱动,一层一层慢慢解开黑盒
- 阅读大型项目的方法~~~
第二环节 开发
使用
Chisel
有什么感想?Scala
(相对于Rust
)更强调函数式编程、面向对象编程Chisel
就是基于Scala
Chisel
描述硬件的语言方式是非常抽象高级的,Verilog
的抽象层次很低,可以视作“电路设计中的汇编语言”- 在
Chisel
里面 DEBUG 一般直接打印信息- 传统看波形:通过信号周期(几千几万的那种)跟踪,太难了
- 有些功能
Chisel
解决不了或者实现会很复杂- 多时钟可以搞,但是会更复杂一点
- DDR的复杂度很高,Contrler很难搞
- CPU和SDRAM的时钟频率不一样,需要转换桥?
使用chisel如何调试?
- 处理器在线差分测试仿真验证
- nemu是一个简版的qemu,在qemu里面自定义DEBUG很麻烦,而且封装过度当需要很小(获取一个寄存器的值)开销很大
- nemu里面可以直接通过函数调用来获取DEBUG信息
- nemu和qemu可以相互映证
- 直接用qemu可能会有一些坑
- 模拟器作为动态链接库连接到仿真程序
- 处理器在指令完成时发出比对信息,当比对信息不一致时立刻报错并输出当前处理器状态
- nemu是一个简版的qemu,在qemu里面自定义DEBUG很麻烦,而且封装过度当需要很小(获取一个寄存器的值)开销很大
- 处理器在线差分测试仿真验证
如何测试验证模块的正确性?
设计对比实验,如果结果相同则认为正确
TLB中可以自行设计测例,来验证多种的功能
行为是否符合预期?
没有BUG的情况下,如果提升性能?
微结构设计?。。
写一些比较小的模块/程序,观察一个请求究竟做了什么事情,做周期级别的时间分析(打日志)。定位性能倒退的原因。
(参数化框架)配置的组合数很大,可能需要用到回归测试,遍历所有的系统模块的组合
适配操作系统的过程中遇到哪些困难? 如何克服?
- 流片前开发(六个系统软件/OS)
- Nanas-lite:用户空间和内核空间共用同一个1GB空间,导致PTE覆盖
- FreeRTOS
- RT-thread:Idscript有ALIGN(4),4全部改成8跑通了
- xv6:不刷TLB(qemu里面没有刷TLB的概念)此时fork的时候Copy on Write机制会出现问题,还有load的时候?
- 只有运行一些很小的程序才会高几率出现此BUG,大程序可能会把TLB刷下去
- Linux kernel:编了一份SMP
- 运行的时候随机爆炸
- 上周的多核linux刷TLB又重新弄了一下
- 其他没有太多的坑
- Debian:跨页的4字节指令
- 流片后测试
- 4字节flash读取会导致一些读写取指相关的错误
- XIP(eXecute In Place):用flash取指执行,用sdram来读写数据
- 只适合“一个程序”
- 多个独立程序加载时会产生覆盖
- 程序段之间有2MB的空洞,如果直接全部加载进来,很浪费(总共只有4MB的内存)
- 因此将BBL和linux做成了一个程序
- linux数据段默认按页对齐,但XIP要求存储连续
- 修改链接脚本,把所有数据段合并成一个
- 段间空洞改为段内空洞,对XIP透明化
- 修改链接脚本,把所有数据段合并成一个
- 只适合“一个程序”
- 内核识别到的内存大小为0
- 实际RAM地址超出了默认内存地址空间的范围(1GB的间隔)
- 强行硬编码增加了1GB的空间。。
- 执行内核线程hello
- 执行用户线程hello
- 由于前面设计的锅,sdram中不能直接执行代码,所以分页的时候对进程页面要拦截并进行手动地址映射设置到flash
- 对flash读8字节,将ld指令魔改位lw的4字节指令
- vDSO(Virtual dynamic shared object)
- 一个映射到用户空间的so文件,可以在不陷入内核的情况下执行一些简单的系统调用
- 每次取指都需要从flash中取,需要成千上万个周期,变成了实际意义上的多周期
- 流片前开发(六个系统软件/OS)
第三环节 经历
- 印象最深刻的bug
- 使用测试框架定位复杂BUG
- 模拟器和处理器的行为不太一样,33亿条指令时捕捉到错误。。。
- 边界测例:一条指令横跨了两个页面(前半和后半被分开,会产生PAgeFault)
- 特殊的Page Fault需要在指令集手册上查找,需要往特定的寄存器中写入值
- 硬件引脚输出问题
- 换成显式的硬件逻辑,突然就跑通了
- 对硬件手册信息(约定)的理解有错,“N”,低位全部接成了高位引脚
- TLB取地址
- TLB转换对了,但取出来的值不对
- 看了4天log信息,在x86中打印流程
- 最终师兄2小时找出,是x86的软件的一个BUG(没有刷TLB)
- Cache(SRAM)黑盒爆炸
- BUG不断修锅,然后不断出新BUG
- 去Cache中间层
- 整个核的行为发生很大变化
- 握手信号初始化的小问题
- 但是性能显著降低
- 分支预测器隐含的条件,去掉Cache后就不满足了
- 使用测试框架定位复杂BUG
- 有没有坑过队友/被队友坑过?
- 主要还是硬件方面的事情
- Cache流水线(同时访问)有仲裁级相关的问题
- 和龙芯杯相比有什么不同?
- 验证环境更好(极大提高DEBUG生产效率)
- 代码质量需要一定的水平
- 第一次对项目进行可配置化, 感觉如何?
- 相比 verilog 好上很多了,要改的东西更少——敏捷开发(3周)
- 外设的验证工作有什么挑战?
- 多维度的复杂性:设备多样性、场景多样性、扩展多样性。
- 课堂上没讲过硬件填充的TLB, 你是如何实现正确的?
- TLB实现需要满足实验手册的约定,但需要自己去实现
- 从状态机开始,不断扩充、成型(有点搞科研的味道;不确定性)
- Nextline预取器听上去很简单, 但你花了两个月才实现正确, 有什么坑?
- 功能:给一个地址,取这个地址+1
- 最初实现预取器发现性能倒退:L1 Cache访问比较频繁,如果放到L1前面就会性能下降(每次预取器加倍消耗)。所以又采用了L2 Cache,放到了L2 Cahce的前面,
第四环节 未来
- 一生一芯的经验对大家做毕设有什么帮助?
- 假设论证、心态。。
- 坚持、走通一条路。
- quick and dirty麻雀原则:先弄出来,再疯狂改进。
- 对前景要有认识,要意识到后续工作的改进瓶颈
- 保证良好的可扩展性
- 第一次设计推倒重来很正常,多次之后前景逐渐明朗
- 对参加下一届一生一芯项目的学弟学妹有什么建议?
- 基础设施很重要
- 对linux的魔改都是现在nemu中运行
- 其它的硬件环境运行测试起来都很难
- 对linux的魔改都是现在nemu中运行
- 系统能力很重要
- 不要害怕犯错
- 注重代码质量,commit水平,版本管理
- 总揽全局,对整个项目有接口性把握
- 对下一届的期望?
- 看实力水平,改进或者从头来走一遍(试错)?
- 水平不够,走一些弯路也是可以的?
- 基础设施很重要
zCore整体设计
前面讲的和以前的差不多。
async
async-await
用同步风格编写异步代码。Rust的一个特性。
- 本质:无栈协程(共享同一个栈,面向任务的轻量级线程),协作式调度(非抢占式)
- 语法糖。同步管理被封装透明化了,所以写法上与一般代码差不多。
- 协程特点:共享栈,满足每个协程使用栈空间的最大用量(协程运行的中间状态),同时用少量的栈空间来保存每个协程的必要信息。
- 适用于高并发IO场景
- 可能必须解决响应时间的问题
- 主流编程语言均以支持:C#,C++,JavaScript,Python
- 几乎没有在 bare-metal(裸机)中应用
工具链
- 代码质量控制:
cargo fmt
,cargo clippy
- 文档和单元测试:
cargo doc + cargo test + grcov
(grcov
计算测试覆盖率)- (TODO)性能测试:
cargo bench
- (TODO)性能测试:
- carte 的拆分和发布流程:
cargo publish
- 持续集成和自动测试:GitHub Actions
- 社区合作开发:GitHub issue + PR
突然想看看《设计模式》。
8月5日 RIOS实验室
没想到之前关注的两个:一生一芯、RIOS都被邀请过来作报告。。tql。感觉就是这个活动很高端。
好的,上午依然是自由活动的性质,所以没什么事。。
我的博客网址出锅了,想办法看看能不能补救。HSTS策略是真的烦。
https://raw.githubusercontent.com/wiki/rcore-os/zCore/files/wrj-thesis.pdf。wrj的毕设论文写得确实很详细。
https://raw.githubusercontent.com/wiki/rcore-os/zCore/files/pql-thesis.pdf。
先把这两个毕设看一看好了。
TBSI来咯。hhh
RIOS实验室研讨会
RIOS实验室研讨会。
张林老师有信息论的MOOC,貌似以前是TBSI的院长。 然而信息论我都还没看完,我太菜辣。
一开始基本还是一些RISC-V的背景介绍。没啥新鲜的。在经济上和政治上都有一定优势。
PicoRio:超低成本,成熟的社区。
TBSI 谭老师的口语实在是有点泛英语化。。
现在PicoRio有开源地址吗?或者在哪里可以了解到最新进展呢?
目前还没有正式地发布,文档还在慢慢更新。秋季?
从专门网站上找documentation。
PicoRio似乎不想用BSD许可证,然后再设计一个license?但是出发点是保护社区。
其它的事情不太了解也不是很感兴趣。
Sipeed矽速工程师交流会
听说K210板子是从他们那批发的。。
矽速科技官网:https://www.sipeed.com
MaixPy:使用简单的Micropython语法在AI芯片上快速实现有趣的功能的SDK。
SDK组成:
- CMake + Kconfig
- CMake:自动寻找cmake文件,导入各个模块并注册
- Kconfig:进行组件配置的选择,并生成config文件
- 组件(驱动、micropython、模块)
- 工程(project.py)
视觉、多媒体、机器流水线、人脸识别……、
Micropython语法:
- 用户代码精简,易于上手,成本低(几十块钱的开发板)
- 面向对象语法,封装性好,开发速度高
- 解释型语言,快速验证
Micropython语法是从语法上与python不同,还是只是可以调用你们写的一些库函数?
Micropython其实就是一个解释器,大部分时候与python语法上是兼容的。
AI 模型:
K210搭载了 AI 芯片吗? 它在什么方向上做了优化,和传统的芯片的不同在哪?
AI芯片就是一个可以部署和运行模型的芯片而已。
所有的算法模型都是提前训练好的? K210 本身支持训练吗?
对。一般要在电脑上训练。
KPU 是什么? 和CPU和GPU有什么不同?
针对的应用场景不同,KPU支持的是通用运算。GPU专门处理图形处理方面的运算。
KPU的K只是一个命名。KPU实现了GPU功能的一些子集。
模型压缩的方法?
浮点运算精度调低。用一些软件工具来压缩?
MaixPy常见难点:
GC(垃圾回收):GC分配的内存需要标记,内存不足的时候自动回收
对齐错误:指针、内存、地址对齐的问题
MaixPy TODO:
- LPU Flash run,PSRAM run:目前只支持6M的模型,如果可以存储到flash里面,需要的时候再读取,就很好
- MaixUI:简单轻量化,减少内存消耗
- MaixHub:分享训练好的模型的Hub网站
- IDE:。。。
- MaixPy on Linux:
JTAG(Joint Test Action Group,联合测试工作组)。
一个硬件集成式的调试工具。提供了一系列接口来调试开发板。
JTAG提供了图形界面化的IDE。
8月6日 论文研读
今天主要看rCore和zCore的本科毕业设计论文。
Rust 的零成本开销抽象意味着,抽象的运行开销为0;如果的确要在运行时使用该抽象,也可以保证运行开销最小。
文档讨论会。
可能需要从头开始搭一遍 zCore。(复现 / 拆解?)
然后老师又说把每一部分的代码进行分析。
自己先理解自己的代码部分。
主线还是需要变化。
操作系统 DEBUG 门槛/难度怎么改变?
有点难度。
华为 openEuler 研讨会。
Email:guanyanjie AT huawei.com
华为基于服务器linux发行版,开源在码云上的一个共享社区。
网址:openeuler.org。
openEuler是一个开源、免费的Linux发行版平台,将通过开放的社区形式与全球的开发者共同构建一个开放、多元和架构包容的软件生态体系。同时,openEuler也是一个创新的平台,鼓励任何人在该平台上提出新想法、开拓新思路、实践新方案。
openEuler 是为了让华为的芯片(麒麟、鲲鹏……)出厂即可以有配套的开源发行版。建立 openEuler 社区,使能ARM生态,让世界有第二选择。
全软件堆栈的技术优化,打造高性能、高可靠、高安全、易用的操作系统。
完全回到了原来的一个状态,自选一个项目:继续写tutorial,或者写代码的测试文档。
RVM晚间研讨会。
Hypervisor: Virtual Machine Monitor(VMM)
RVM: Rcore Virtual Machine。基于 RVM 实现了 rCore/zCore 的 hypervisor。
不是很感兴趣。全是实现细节。
zCore虚拟化的更多工作:
- 完善RVM,完成更多的测试(24/28)
- RVM从rCore中独立出来,但有些部分还没搞好
- 跑在其它真实的环境中,目前只支持 intel 的 x86
zCore 内核对象及系统调用。
Zircon微内核是Fuchsia的最底层。
- 实用主义微内核
- 使用 C++ 实现,支持 x86_64 和 ARM64
- 面向对象(微内核的传统习惯):将功能划分到内核对象
- 默认隔离:使用 Capability 进行权限管理
- 安全考量:强制地址随机化(zCore还没实现),使用 vDSO 隔离系统调用
所有的东西都可以称为内核对象。
- 任务:Job, …
- 内存:VMAR, …
- IPC: Channel, …
- 信号:Event, …
- 驱动:Resource, ….
Object:
- Object:内核对象
- Rights:对象访问权限
- Handle = Object + Rights:对象句柄(类似 fd)
IPC:
- Channel:进程间通信基础设施,可以传递数据和handle
- FIFO:报文数据传输
- Socket:流数据传输
Tasks:
- Job:作业,负责控制权限(类似容器)
- Process:进程,负责管理资源
- Thread:线程,负责调度执行
一个作业可能有多个进程,一个进程可能有多个线程。进程之间没有父子关系。
Memory:
- VMO(Virtual Memory Object)
- Paged:分页物理内存,支持写时复制
- Physical:连续物理内存
- VMAR(Virtual Memory Address Region)
- 代表一个进程的虚拟地址空间
- 树状结构
- Pager:用户态分页机制
Signaling and Waiting:每个 Object 有 32 个信号位,用户程序可以阻塞等待。
- Event(pair):事件源/对
- Timer:计时器
- Futex:用户态同步互斥机制(快速)
- Port:事件分发机制(类似epoll)
zCore硬件移植和驱动开发。
UEFI(Unified Extensible Firmware Interface):增强版 BIOS。类似 Open SBI。
- 省去了从古老的实模式进入现代长模式的汇编代码
- 丰富的外设驱动支持,快速输入输出
- Rust UEFI 开发环境方便易用(
uefi-rs
库)
8月8日
今天到海南转机,结果航班取消了。被迫在海南呆了半天。
居然看到了椰树椰汁的厂子。。
海南唯一的一家呷哺呷哺。。
买了晚上的经济舱,结果被升成头等舱了。。
一系列际遇之后到家。完结。