Haiku 在 OSX(Intel) 上的编译和运行
准备工作
在开始前,由于 osx 默认的 apfs 文件系统不区分大小小写,所以首先得新建一块大小写敏感的 volume。
-
打开磁盘工具,进行分区 -
点击 + 号添加分区 在弹出的选择中点击 添加分区 设置分区名称、格式、大小。注意这里需要选择区分大小写的格式,这里使用了区分大小写的 APFS,分区大小至少为 15GB。 设置完成后点击 应用 开始分区。 -
等待分区完成 分区完成后,可以在 /Volumes/haiku/ 访问此分区,接下来所有的工作都在这里进行。
获取源码
配置 git 与 review.haiku
基本上你可以参考 https://www.haiku-os.org/guides/building/get-source-git 获取源代码,这里我简要描述一下步骤。
-
首先你的电脑上应该已经安装了 git,并确保这两个值已经正确设置 user.name 与 user.email ,如果没有,可以这样设置 git config --global user.name "yourname"
git config --global user.email "youremail"
此外还需要设置 core.precomposeunicode 为 true git config core.precomposeunicode true
-
haiku 没有直接使用 github 进行托管,你需要使用你的 github 在 https://review.haiku-os.org/ 登陆,记住你的用户名,在后面的步骤中要用到它。
获取代码
代码分为两部分:buildtools 和 haiku,前者是 haiku 定制化的编译工具,包括 gcc 与构建工具 jam;后者则是 haiku 的源代码,
git clone "ssh://<login>@git.haiku-os.org/buildtools" && scp -p <login>@git.haiku-os.org:hooks/commit-msg "buildtools/.git/hooks/"
git clone "ssh://<login>@git.haiku-os.org/haiku"
scp -p <login>@git.haiku-os.org:hooks/commit-msg "haiku/.git/hooks/"
将其中的 <login> 替换为你的用户名,举个例子,我的用户名是 MRNIU ,那么命令应该这样写
git clone "ssh://MRNIU@git.haiku-os.org/buildtools" && scp -p MRNIU@git.haiku-os.org:hooks/commit-msg "buildtools/.git/hooks/"
git clone "ssh://MRNIU@git.haiku-os.org/haiku"
scp -p MRNIU@git.haiku-os.org:hooks/commit-msg "haiku/.git/hooks/"
在编译之前,还需要做一些小小的改动
PS:在撰写本文时使用的是 hrev56168,如果使用最新代码,一些问题可能已经被修复。
-
gcc/gcc/config/host-darwin.c 最后一行添加宏 #if defined(__aarch64__)
const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
#endif
-
src/system/kernel/device_manager/device_manager.cpp 添加 #L1732 _AddPath(*stack, “busses/virtio”); 将 virtio 总线添加到搜索路径中
做好以上准备,就可以开始进行编译了。
编译
安装依赖
brew install autoconf zstd xorriso gawk wget nasm less mpfr gmp libmpc bison libffi
安装构建工具 jam
cd /Volumes/haiku/buildtools/jam
make
sudo ./jam0 install
首先需要编译工具链
cd haiku
mkdir generated.arm
cd generated.arm
../configure -j8 --cross-tools-source ../../buildtools --build-cross-tools arm
编译完成后执行 jam -v 可以看到如下输出
> jam -v
Jam 2.5-haiku-20211029. OS=MACOSX. Copyright 1993-2002 Christopher Seiwald.
接下来编译可以在 qemu 上运行的 haiku 镜像
jam -j8 -q @minimum-mmc
运行
编译完成后就可以准备运行了,我们使用 uboot 进行引导,在这里可以找到 u-boot.bin,将其复制到 generated.arm 目录下即可。
我们使用 qemu 进行模拟,但要注意我们要用的是 version 6.0.0。
使用 brew 安装 6.0.0 版本 qemu:
curl https://raw.githubusercontent.com/Homebrew/homebrew-core/b1268a3ecd418df8f7360c46ce3ee62a0599a1be/Formula/qemu.rb > /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/qemu.rb
brew install qemu
万事俱备,运行!
> qemu-system-arm -bios u-boot.bin -M virt -cpu cortex-a15 -m 2048 \
-device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 \
-drive file="haiku-mmc.image",if=none,format=raw,id=x0 \
-device ramfb -usb -device qemu-xhci,id=xhci -device usb-mouse -device usb-kbd -serial stdio
遇到的问题和解决方式
buildtools
在初次编译 buildtools for arm 时遇到
> ../configure -j8 --cross-tools-source ../../buildtools --build-cross-tools arm
...
/Volumes/haiku/buildtools/gcc/gcc/config/host-darwin.c:83:25: error: variable has incomplete type 'const struct host_hooks'
const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
^
/Volumes/haiku/buildtools/gcc/gcc/config/host-darwin.c:83:14: note: forward declaration of 'host_hooks'
const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
^
/Volumes/haiku/buildtools/gcc/gcc/config/host-darwin.c:83:38: error: use of undeclared identifier 'HOST_HOOKS_INITIALIZER'
const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
^
1 warning and 2 errors generated.
make[2]: *** [host-darwin.o] Error 1
make[2]: *** Waiting for unfinished jobs....
1 warning generated.
140 warnings generated.
25 warnings generated.
25 warnings generated.
110 warnings generated.
25 warnings generated.
434 warnings generated.
rm gcc.pod
make[1]: *** [all-gcc] Error 2
make: *** [all] Error 2
ERROR: Building gcc failed.
解决方式:https://review.haiku-os.org/c/buildtools/+/5302
KDiskDeviceManager::InitialDeviceScan() returned error
> qemu-system-arm -bios u-boot.bin -M virt -cpu cortex-a15 -m 2048 \
-device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 \
-drive file="haiku-mmc.image",if=none,format=raw,id=x0 \
-device ramfb -usb -device qemu-xhci,id=xhci -device usb-mouse -device usb-kbd -serial stdio
...
get_boot_partitions(): boot volume message:
KMessage: buffer: 0x8240ad40 (size/capacity: 255/255), flags: 0xa
field: "partition offset" (LLNG): 54520832 (0x33fec00)
field: "packaged" (BOOL): true
field: "boot method" (LONG): 0 (0x0)
field: "disk identifier" (RAWT): data at 0x8240adf0, 79 bytes
get_boot_partitions(): boot method type: 0
intel: ep_std_ops(0x1)
intel: ep_std_ops(0x2)
intel: pm_std_ops(0x1)
intel: pm_std_ops(0x2)
dos_std_ops()
dos_std_ops()
module: Search for bus_managers/pci/x86/v1 failed.
ahci: failed to get pci x86 module
module: Search for bus_managers/pci/x86/v1 failed.
ahci: failed to get pci x86 module
module: Search for bus_managers/pci/x86/v1 failed.
ahci: failed to get pci x86 module
name: Generic
KDiskDeviceManager::InitialDeviceScan() returned error: No such file or directory
PANIC: did not find any boot partitions!
Welcome to Kernel Debugging Land...
Thread 14 "main2" running on CPU 0
frame caller <image>:function + offset
0 801bd9d0 (+2145658416) 801ba870 <kernel_arm> (nearest) + 0x00
initial commands: syslog | tail 15
get_boot_partitions(): boot method type: 0
intel: ep_std_ops(0x1)
intel: ep_std_ops(0x2)
intel: pm_std_ops(0x1)
intel: pm_std_ops(0x2)
dos_std_ops()
dos_std_ops()
module: Search for bus_managers/pci/x86/v1 failed.
ahci: failed to get pci x86 module
module: Search for bus_managers/pci/x86/v1 failed.
ahci: failed to get pci x86 module
module: Search for bus_managers/pci/x86/v1 failed.
ahci: failed to get pci x86 module
name: Generic
KDiskDeviceManager::InitialDeviceScan() returned error: No such file or directory
kdebug>
解决方式:
diff --git a/src/system/kernel/device_manager/device_manager.cpp b/src/system/kernel/device_manager/device_manager.cpp
index ffc539a23b..882590ae39 100644
--- a/src/system/kernel/device_manager/device_manager.cpp
+++ b/src/system/kernel/device_manager/device_manager.cpp
@@ -1731,6 +1731,7 @@ device_node::_GetNextDriverPath(void*& cookie, KPath& _path)
_AddPath(*stack, "drivers", sGenericContextPath);
_AddPath(*stack, "busses/i2c");
_AddPath(*stack, "busses/scsi");
+ _AddPath(*stack, "busses/virtio");
_AddPath(*stack, "busses/random");
_AddPath(*stack, "bus_managers/pci");
}
Data Abort
如果你使用了较高版本的 qemu,可能会出现 Data Abort:
> qemu-system-arm -bios u-boot.bin -M virt -cpu cortex-a15 -m 2048 \
-device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 \
-drive file="haiku-mmc.image",if=none,format=raw,id=x0 \
-device ramfb -usb -device qemu-xhci,id=xhci -device usb-mouse -device usb-kbd -serial stdio
...
Identified boot partition by partition offset.
bfs: mounted "Haiku" (root node at 131072, device = /dev/disk/virtual/virtio_block/0/1)
Mounted boot partition: /dev/disk/virtual/virtio_block/0/1
unknown [0: 14] Adding packages from "/boot/system/packages"
unknown [0: 14] Failed to open packages activation file: No such file or directory
unknown [0: 14] Loading packages from activation file failed. Loading all packages in packages directory.
Exception: Data Abort
R00=00010015 R01=00000000 R02=0000ffff R03=00000032
R04=80df4049 R05=00000f85 R06=00000003 R07=00000f9d
R08=80b961c0 R09=80006003 R10=80007029 R11=8244680e
R12=801bde94 SP=824467e8 LR=8224bba4 PC=82265304 CPSR=a0000053
FAR: 80df4051, isWrite: 1, thread: main2
解决方式:使用 qemu 6.0.0 即可。
出现 Exception: Data Abort 时 DFSR:0x600001d3(b0110…1 1101 0011),这表示在 read 时出现了 Access flag fault 错误。See: armv7-dfsr
|