Skip to content

Commit e520f1d

Browse files
authored
Merge pull request #51 from Solicey/dev-x86_64
add arch x86_64 docs
2 parents fcde500 + 9b4beae commit e520f1d

12 files changed

Lines changed: 630 additions & 7 deletions

File tree

src/SUMMARY.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040

4141
- [FPGA 香山昆明湖快速上手]()
4242

43+
- [Qemu X86_64 快速上手](./chap02/QemuX86_64.md)
44+
45+
- [NUC14MNK X86_64 快速上手](./chap02/NUC14MNK.md)
46+
4347

4448
# hvisor 使用手册
4549

@@ -70,6 +74,8 @@
7074
- [RISC-V 处理器虚拟化](./chap04/subchap01/RISCVirtualization.md)
7175

7276
- [LoongArch 处理器虚拟化](./chap04/subchap01/LoongArchVirtualization.md)
77+
78+
- [X86_64 处理器虚拟化](./chap04/subchap01/X86_64Virtualization.md)
7379
- [内存虚拟化](./chap04/MemVirtualization.md)
7480
- [中断虚拟化](./chap04/subchap02/InterruptVirtualization.md)
7581

@@ -80,13 +86,17 @@
8086
- [RISC-V 中断控制 AIA](./chap04/subchap02/RISC-AIA.md)
8187

8288
- [LoongArch 中断控制](./chap04/subchap02/LoongArch-Controller.md)
89+
90+
- [X86_64 中断控制 APIC](./chap04/subchap02/X86_64-APIC.md)
8391
- [I/O 虚拟化](./chap04/subchap03/IO-Virtualization.md)
8492

8593
- [IOMMU](./chap04/subchap03/IOMMU/IOMMU-Define.md)
8694

8795
- [ARM SMMU 的实现](./chap04/subchap03/IOMMU/ARM-SMMU.md)
8896

8997
- [RISC-V IOMMU 标准的实现](./chap04/subchap03/IOMMU/RISC-IOMMU.md)
98+
99+
- [X86_64 IOMMU 实现](./chap04/subchap03/IOMMU/X86_64-VTD.md)
90100
- [VirtIO](./chap04/subchap03/VirtIO/VirtIO-Define.md)
91101

92102
- [Block](./chap04/subchap03/VirtIO/BlockDevice.md)

src/chap01/Board.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@
1919
- [x] FPGA 香山(昆明湖)on S2C Prodigy S7-19PS-2
2020
- [x] FPGA RocketChip on Xilinx Ultrascale+ MPSoC ZCU102
2121

22-
## x86
23-
- [x] QEMU virt x86_64
24-
- [x] 华硕 NUC 14 Elite 主机
25-
2622
## loongarch64
2723

2824
- [x] Loongson 3A5000+7A2000
29-
- [ ] Loongson 3A6000
25+
- [ ] Loongson 3A6000
26+
27+
## x86_64
28+
29+
- [x] QEMU q35
30+
- [x] ASUS NUC 14 Essential

src/chap01/PlatformDev.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ wheatfox (wheatfox17@icloud.com) 2025.3.17
2323
- `bootloader/` - (可选) 用于 QEMU 本地运行和 unittest/systemtest 测试
2424
- `dts/` - (可选) zone 0, 1, 2, … 的设备树源文件
2525
- `its/` - (可选) 用于 U-Boot FIT image 生成(hvisor aarch64 zcu102)
26-
- `acpi/` - (可选) x86 平台的 ACPI 设备树源码(hvisor x86_64)
26+
- `iso/` - (可选) 用于 GRUB image 生成(hvisor x86_64)
2727
- `kernel/` - (可选) 适用于目标平台的 kernel Image
2828
- `virtdisk/` - (可选) 虚拟磁盘文件,如 rootfs 等
29+
- `font/` - (可选) 在显示器上打印调试日志信息使用的字体
2930

3031
## 代码实现细节
3132

@@ -55,7 +56,8 @@ wheatfox (wheatfox17@icloud.com) 2025.3.17
5556
| `loongarch64/ls3a6000` | `loongson_chip_7a2000` `loongson_uart` `loongson_cpu_3a6000` |
5657
| `aarch64/rk3588` | `gicv3` `uart_16550` `uart_addr_rk3588` `pt_layout_rk` |
5758
| `aarch64/rk3568` | `gicv3` `uart_16550` `uart_addr_rk3568` `pt_layout_rk` |
58-
| `x86_64/qemu ` | |
59+
| `x86_64/qemu ` | `pci` `uart16550a` |
60+
| `x86_64/nuc14mnk ` | `pci` `uart16550a` |
5961

6062
## 开发与编译指南
6163

src/chap02/NUC14MNK.md

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# 在 NUC 14 Essential x86_64 上运行 Hvisor
2+
3+
刘天弘(lzoi_lth@163.com
4+
5+
## 一、BIOS 设置
6+
7+
NUC14 初始自带一个 BIOS,需要进行相应设置。
8+
9+
完成必要的连线工作后(电源、显示器、路由器),开机,按 F8(可能有所不同)进入 BIOS,打开 Boot 页面,关闭 Secure Boot。此后即可加载自制的镜像。
10+
11+
<div align="center">
12+
<img src="./img/nuc14bios.jpg" style="zoom: 40%;" />
13+
</div>
14+
15+
16+
## 二、编译 Linux 内核
17+
18+
在 Qemu X86_64 编译内核的基础上,增加下述配置项,然后重新编译:
19+
20+
```bash
21+
# nvme 磁盘驱动
22+
./scripts/config --enable CONFIG_NVME_CORE
23+
./scripts/config --enable CONFIG_BLK_DEV_NVME
24+
# vesafb 图形显示器驱动
25+
./scripts/config --enable CONFIG_FB
26+
./scripts/config --enable CONFIG_FB_CMDLINE
27+
./scripts/config --enable CONFIG_FB_VESA
28+
```
29+
30+
31+
## 三、制作启动盘
32+
33+
为了测试方便,本文选择一块 U 盘作为 Hvisor 的启动盘,并且在上面安装 GRUB 作为 bootloader。
34+
35+
首先需要对 U 盘进行分区,推荐使用带有图形界面的 Linux 操作系统以及分区工具 GParted。U 盘插入后,会对应到一个设备节点,例如 `/dev/sda`**在正式开始分区前,确保 U 盘内无重要数据或者已经备份**
36+
37+
打开 GParted,选择 U 盘作为当前盘,然后点击 `Device → Create Partition Table...` 建立一个 GPT 分区表。如果提示无法建立分区表,需要使用 `umount` 卸载所有活动分区,然后重新启动 GParted。
38+
39+
建完 GPT 分区表后,新建一个 EFI 分区,该分区必须为 **FAT32** 格式。然后再新建一个文件系统分区作为 zone0 的根文件系统,分区格式为 **EXT4**。建立好分区后,点击绿色的 √,正式完成划分。在下图的示例中,FAT32 分区被命名为 `/dev/sda1`,EXT4 分区被命名为 `/dev/sda2`。不同环境下的命名可能有所不同,需要留意。
40+
41+
<div align="center">
42+
<img src="./img/nuc14gparted.jpg" style="zoom: 30%;" />
43+
</div>
44+
45+
接下来进行 GRUB 的编译。
46+
47+
```bash
48+
# 下载 GRUB
49+
wget https://ftp.gnu.org/gnu/grub/grub-2.06.tar.xz
50+
51+
# 解压并打开
52+
tar -xf grub-2.06.tar.xz
53+
cd grub-2.06/
54+
55+
# 配置并编译
56+
mkdir EFI64
57+
cd EFI64
58+
../configure CFLAGS="-Wno-error" --target=x86_64 --with-platform=efi && make -j$(nproc)
59+
```
60+
61+
然后将 GRUB 安装到 U 盘的 EFI 分区中。
62+
63+
```bash
64+
# 将 EFI 分区 mount 到 mnt 文件夹
65+
sudo mount /dev/sda1 /mnt
66+
67+
# 安装到 /mnt
68+
cd ../EFI64/grub-core
69+
sudo ../grub-install -d $PWD --force --removable --no-floppy --target=x86_64-efi --boot-directory=/mnt/boot --efi-directory=/mnt
70+
```
71+
72+
## 四、编译 Hvisor
73+
74+
进入 Hvisor 所在路径,打开 `platform/x86_64/nuc14mnk/board.rs`,将 `ROOT_ZONE_CMDLINE``root=/dev/sda2` 参数修改为 EXT4 分区的名字。
75+
76+
由于 NUC14 未提供串口接口,若要打印调试日志,需要在 `platform/x86_64/nuc14mnk/cargo/features` 添加 `graphics` 这一特性,使得日志可以直接绘制在显示器上,这一特性仅供早期调试。
77+
78+
参考 QEMU 的步骤,将构建好的内核文件和根文件系统移动到指定位置。执行编译指令 `make ARCH=x86_64 BOARD=nuc14mnk`
79+
80+
可以看到 `/platform/x86_64/nuc14mnk/image/iso/boot` 路径下有文件生成,将 `boot` 文件夹整个复制到第三步的 `/mnt` 中。此时 EFI 分区的大致布局如下:
81+
82+
```bash
83+
.
84+
├── boot
85+
│   ├── grub
86+
│   │   ├── fonts
87+
│   │   ├── grub.cfg # 用于配置 GRUB 菜单的各个选项
88+
│   │   ├── grubenv
89+
│   │   ├── locale
90+
│   │   └── x86_64-efi
91+
│   │   ├── acpi.mod
92+
│   │   ├── ...
93+
│   │   └── zstd.mod
94+
│   ├── hvisor
95+
│   └── kernel
96+
│      ├── boot.bin
97+
│      ├── setup.bin
98+
│      └── vmlinux.bin
99+
└── EFI
100+
   └── BOOT
101+
   └── BOOTX64.EFI
102+
```
103+
104+
`grub.cfg` 可以配置 Hvisor 加载时的相关操作,其 menuentry 具体如下。`multiboot2` 会将 Hvisor 以 Multiboot2 协议加载入内存,`module2` 会将 Linux 内核镜像加载到内存中,Hvisor 再将其移动到末尾的十六进制数字所指定的内存位置。
105+
106+
```
107+
menuentry "Hvisor" {
108+
multiboot2 /boot/hvisor # use multiboot spec to boot
109+
module2 /boot/kernel/boot.bin 0
110+
module2 /boot/kernel/boot.bin 5008000
111+
module2 /boot/kernel/setup.bin 500a000
112+
module2 /boot/kernel/vmlinux.bin 5100000
113+
boot
114+
}
115+
```
116+
117+
最后,将 zone0 的根文件系统通过 `sudo dd if=rootfs1.img的路径 of=/dev/sda2 bs=4M status=progress` 指令写入 EXT4 分区。
118+
119+
NUC14 开机后,按 F10 进入 U 盘启动模式,选择 U 盘的 EFI 分区。(或者修改 BIOS 将 U 盘作为第一启动项)进入 GRUB 后,选择 `Hvisor` 即可。
120+
121+
## 五、有线网卡驱动问题
122+
123+
首先在 Linux 源码文件夹下执行 `make modules` 以生成 `Module.symvers` 文件。
124+
125+
Linux 镜像自带的 r8169 驱动可能无法在 NUC14 上运行,导致无法正常联网。因此需要下载 Realtek 官方提供的 r8125 驱动:[Realtek PCIe FE / GbE / 2.5GbE / 5G / 10G Family Controller Software](https://www.realtek.com/Download/List?cate_id=584),下载 2.5G Ethernet LINUX driver r8125 for kernel up to x.xx 这一项。
126+
127+
下载完成后,进入 `src` 文件夹,执行 `make -C linux所在路径 M=src所在路径 modules`,将生成的 `r8125.ko` 内核模块放入 zone0 的根文件系统的特定位置,例如 `/mnt/lib/modules/$(uname -r)/kernel/drivers/net/ethernet/realtek/`,然后执行 `depmod -a -b /mnt $(uname -r)` 更新模块依赖索引。这样在进入 Hvisor 时,就可以执行 `sudo modprobe r8125` 加载网卡驱动了。
128+
129+
## 六、无线网卡驱动问题
130+
131+
如果要让 zone0 或 zone1 使用无线网卡,需要给内核添加如下配置项,重新编译:
132+
133+
```bash
134+
# iwlwifi 无线网卡驱动
135+
./scripts/config --module CONFIG_IWLWIFI
136+
```
137+
138+
然后把内核模块安装到 `/lib/modules/$(uname -r)`
139+
140+
```bash
141+
make -j$(nproc)
142+
make modules
143+
make modules_install INSTALL_MOD_PATH=/path/to/rootfs
144+
```
145+
146+
这里编译成内核模块,是因为无线网卡驱动在加载时可能需要从 Linux 文件系统中读取固件(firmware)文件。因此要等到文件系统准备完毕,才能进行驱动的初始化。编译成内核模块可以更好地控制驱动初始化的时机。
147+
148+
如果未在 Linux 文件系统中放置合适的固件文件,执行 `sudo modprobe iwlwifi` 后,可能会显示如下类型的报错。
149+
150+
```
151+
Direct firmware load for iwlwifi-so-a0-gf-a0-73.ucode failed with error -2
152+
Direct firmware load for iwlwifi-so-a0-gf-a0-72.ucode failed with error -2
153+
Direct firmware load for iwlwifi-so-a0-gf-a0-71.ucode failed with error -2
154+
...
155+
```
156+
157+
从网上下载 iwlwifi 所需的固件文件,将其移动到 Linux 文件系统的 `/lib/firmware` 路径下。本示例所需的固件包括 [`iwlwifi-so-a0-gf-a0.pnvm`](https://github.com/crojewsk-intel/linux-firmware/blob/main/iwlwifi-so-a0-gf-a0.pnvm) 以及 [`iwlwifi-so-a0-gf-a0-72.ucode`](https://github.com/crojewsk-intel/linux-firmware/blob/main/iwlwifi-so-a0-gf-a0-72.ucode)
158+
159+
为 Linux 安装依赖:
160+
161+
```bash
162+
sudo apt install wpasupplicant udhcpc
163+
```
164+
165+
修改 `init`,添加如下内容:
166+
167+
```bash
168+
modprobe iwlwifi
169+
# wlan0 是无线网卡对应的接口
170+
ip link set wlan0 up
171+
# 连接 Wifi
172+
wpa_passphrase "你的 Wifi 名称" "你的 Wifi 密码" > /etc/wpa_supplicant.conf
173+
wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf
174+
# 获取 IP 地址
175+
udhcpc -i wlan0
176+
# 添加 DNS 解析服务器
177+
echo "nameserver 114.114.114.114" > /etc/resolv.conf
178+
echo "nameserver 8.8.8.8" >> /etc/resolv.conf
179+
```

0 commit comments

Comments
 (0)