|OS开发爱好者福利:树莓派上编译C语言,顺便掌握一波硬件知识( 二 )


或者:
-M raspi3:让 qemu 仿真树莓派 3 硬件 。
-kernel kernel8.img:告知要使用的内核文件名 。
-drive file=$(yourimagefile),if=sd,format=raw:在第二种情况下 , 该参数为 SD 卡镜像 , 它也可以是标准的 rasbian 镜像 。
-serial stdio
-serial null -serial stdio:将模拟的 UART0 重定向到运行 qemu 的终端的标准输入 / 输出 , 以便显示发送到串行线路的所有内容 , 并且 vm 会接收终端中键入的每个键 。 该操作仅适用于教程 05 及更高版本 , 因为默认情况下不会重定向 UART1 。 为此 , 必须添加一些类似于 - chardev socket , host=localhost , port=1111 , id=aux -serial chardev:aux 的参数 , 或者简单地使用两个 -serial 参数 。
硬件资源
下面简单介绍一下所需硬件资源 , BCM2837 SoC 芯片 。 包括:
VideoCore GPU;
ARM-Cortex-A53 CPU (ARMv8);
MMIO 映射外部设备 。
有趣的是 , CPU 不是主板上的主处理器 。 当它通电后 , 第一个 GPU 运行 。 当初始化完成时 , 通过执行 bootcode.bin , 它将加载并执行 start.elf 。 这不是一个 ARM 可执行文件 , 而是专门为 GPU 编译的 。 比较有意思的是 , start.elf 寻找不同的 ARM 可执行文件 , 都以 kernel 开头 , 以. img 结尾 。 由于要在 AArch64 模式下对 CPU 进行编程 , 因此只需要 kernel8.img , 这也是最后一个要查找的 。 加载后 , GPU 触发 ARM 处理器上的复位线 , 开始在地址 0x80000(或更准确地说是 0)处执行代码 。
RAM(1G Raspberry Pi3)在 CPU 和 GPU 之间共享 , 这意味着一个可以读取另一个写入内存的内容 。 为了避免混淆 , 需要定义好 mailbox 接口 。 CPU 将消息写入 mailbox , 并通知 GPU 读取它 。 GPU(知道消息完全在内存中)解释它 , 并将响应消息放在同一个地址 。 CPU 必须循环访问内存以知道 GPU 何时完成 , 然后它才能读取响应 。
相似的 , 所有外部设备都在内存中与 CPU 通信 。 每个设备都有从 0x3F000000 开始的专用内存地址 , 但是它不在真实的 RAM 中(称为内存映射 IO) 。 现在没有用于外围设备的 mailbox , 而是每个设备都有其自己的协议 。 这些设备的共同点是:必须以 32 位为单位在 4 个字节对齐的地址(所谓的字)上读取和写入其内存 , 并且每个设备都有控制 / 状态和数据字(data words) 。 不幸的是 , Broadcom(SoC 芯片的制造商)在记录产品方面很差 。 现在所拥有的最好的是 BCM2835 文档 , 这个文档就足够了 。
CPU 中还有一个内存管理单元 , 允许创建虚拟地址空间 。 这可以通过特定的 CPU 寄存器进行编程 , 并且在将这些 MMIO 地址映射到虚拟地址空间时必须小心 。
一些更有趣的 MMIO 地址是:
【|OS开发爱好者福利:树莓派上编译C语言,顺便掌握一波硬件知识】更多信息 , 请参见:https://github.com/raspberrypi


推荐阅读