这是seL4运行机制的第2篇。
截图中的代码和log不额外说明,都是指截图的最后一行
1 教程
依然还是从代码开始,等我完全过一遍教程,再根据自己的理解来总结那些基本的理论。
./init --tut untype
ninja
./simulate
生成untype的教程代码,并编译运行。
提供给root task的Bootinfo描述了所有untype capability。
这里可以延伸一下,看到set up by the default crt0.S ,有时间可以看下这个启动脚本具体是怎么来做这件事的。
接下来,打印了untype的信息:
获取到untype的start和end,然后轮循从untypeList拿到对应的Untype的指针。 打印出其地址、大小,是否是设备:
Untype capability的这个Boolean属性(isDevice)是用来标识这一块内存是否可以被kernel写入的。Device untype capability被重定义为frame对象,即物理内存帧,映射成虚拟内存。
我们直接执行例程,得到的是以下结果:
这里错误的原因是我们尝试创建一个大小为0的untyped。 (untyped_size_bits的值为0)
接下来我们要做的就是计算子untyped需要的空间大小,用来建立下面的对象。
我们所有要创建的对象的大小在这个数组里:
大小分别是11,4,5,由于这个大小指的都是幂,所以我们只要分配11+1就够了,即两个seL4_TCBObject的大小。
这样我们就找到了一个合适大小的parent_untyped。
再次运行,得到的错误如下:
出现这个错误的原因是下面使用的child_tcb是一个空的CSlot(来自于empty.start):
retype这个child_tcp,将其变成TCB对象:
编译运行,会看到如下错误:
这是由无效的endpoint引起的,所以我们需要创建一个放置在child_ep:
编译运行,结果如下:
我们为其创建一个notification对象:
编译运行结果如下:
最后一部分试图创建一个endpoint对象,结果失败了:
原因是我们本来申请的大小就是只够创建这三个对象:
现在多创建一个,肯定是放不下的,所以可以使用revoke函数撤销之前的创建:
再次编译执行,运行成功:
2 思考总结
首先我们好好看一下seL4_Untyped_Retype这个函数:
第1个参数: 需要被retype的对象,在这里我们是通过在可用的untype里面找了一块符合的大小。 第2个参数: 要retype的新类型,这些类型定义在libsel4里面
第3个参数: 要retype的大小。
第4,5,6个参数:
用来定义要放置capabilities的CNode,其中node_depth为0,指的是要用调用的方式引用,默认指向当前线程的CSpace的根。node_index是设计给多层CSpace的,所以在这里就忽略了。
第7个参数: 要开始放置capabilities的CSlot,在这个例程里面,child_untyped是取的第一个空的CSlot。
第8个参数: 要创建的数量。