解析器把一个字符放回在输入流的时候,Python 也需要使用 ungetc() 。而不是在添加一个字符缓冲区的时候使用,即添加"快速 hack"来寻找后一个字符。添加开放式编码的 qsort() 时也一样一样要使用 ungetc();GRUB 不任何支持排序。
GRUB还没有支持的另一个方面是浮点运算。项目组发现了一个许可的浮点运算库FDLIBM。它没有使用任何浮点硬件加速,这在GRUB环境是非常有用的。这意味啊即使在固件没完全初始化浮点运算硬件时也能使用浮点运算。
在使用Python时,我们大量使用printf()和sprintf()。大部分情况,GRUB版本工作很好,但对“%%”(输出一个”%“)这种特殊格式还不支持。事实证明,Python频繁使用格式化的字符串输出。
在被发现和修复之前,怪异的BUG仍然存在。
这个工程还有一些性能问题需要解决。首先,启动时间出乎意料的长。对硬件来说,这是十分痛苦的事情,但是在 CPU 的模拟电路上也很糟糕(“我们不想花三天时间做引导”)。部分问题来自于 Python 的解释器,每次它读取一个数据的时候都要调用 usesungetc()。GRUB 没有太多高速缓存的磁盘,所以所有 I/O 端口直接访问磁盘。
通过加入对 .pyc (Python 字节代码)文件格式的支持,这个工程能够提前减少许多语法分析工作。主机的版本和 GRUB 的版本在同一时刻编译,用于 Python 文件在启动时的编译工作。
这做出了实质性的提升,但是由于stat()的原因,启动时间仍然有些慢。他说在Linux系统上,stat()仅花费几微秒的时间,但是BITS版本会花费几毫秒。增加对zipimport的支持能让工程把所有的.py文件打包放入一个单一的ZIP文件中来避免对stat()的调用。
这个工程希望做有历史和tab自动补全的REPL(读取﹣求值﹣输出循环),但是一般获得支持的方式是使用GUN的Readline library。这个库由有终端设备的POSIX(可移植操作系统接口)提供环境支持。开发者不想写一个“C代码文件”来支持它,所以他们用Python写了一个读取线支持来替代。CPython的PyOS_ReadlineFunctionPointer被称为一个使用C语言API的新Python函数的C函数集合。
为了能够使用其他的操作和多种的测试套件,仍迫切需要构建 GRUB 的动态菜单。GRUB 已经为设备提供了磁盘和文件系统像磁盘分区和 CD 驱动器(例如:“(hd0)”,"(cd)")因此 BITS 增加了一个的“(python)”设备和一个工作起来像在 Linux 用户空间的文件系统(译者注:打不开请加梯子)。因此 Python 代码能访问任意的内存文件,例如在 (python)/menu.cfg 下的菜单配置文件,“即使我们没有写更多的C代码”,Triplett 说道。
访问硬件既然目标是提供一个友好的测试硬件环境,Python 需要能够访问它。一个叫做“bits”的模块被添加进来提供访问各种硬件的功能,例如:CPUID,特殊模块寄存器 (MSRs),I/O 端口,和内存映射 I/O。他用几行代码展示了这些能力。
1
>>> import bits
2
>>> from ctypes import *
3
>>> c = bits.cpuid(0, 0)
4
>>> c
5
cpuid_result(eax=0x..., ebx=..., ecx=..., edx=...)
他引入ctypes模块,以便在下一部分演示中“操作原始内存片”。对于那些想要深挖一些的人来说,几乎所有演示都可以在这个YouTube视频的演讲中看到。cpuid()调用返回了CPU0的CPUID,他之后将其打印出来。他问:“这是不是很有趣?我们正从Python中得到处理器的寄存器信息。” 接着,他使用Python来解释这个结果:
1
>>> buf = (c_uint32*3)(c.ebx, c.edx, c.ecx)
2
>>> (c_char*12).from_buffer(buf).value
3
'GenuineIntel'