linux - 64 位引导协议中的 Linux 引导循环
问题描述
我正在尝试为 Linux 创建一个引导加载程序作为 UEFI 应用程序。问题是在跳转到 64 位内核入口点后,QEMU 将重新启动而没有任何输出。我真的不知道发生了什么事。这是执行跳转的代码:
struct gdt {
uint64_t padding: 48;
uint64_t limit: 16;
uint64_t *base;
};
__attribute__((noreturn))
static
void
start_kernel(
uint32_t kernel,
const struct boot_params *params,
const struct gdt *gdt)
{
// setup segment registers
asm ("mov %0, %%rsi" : : "m" (params));
asm ("mov %0, %%rbx" : : "m" (kernel));
asm ("mov %0, %%rax" : : "m" (gdt));
asm ("lgdt 6(%rax)");
asm ("mov $0x18, %rax");
asm ("mov %ax, %ds");
asm ("mov %ax, %es");
asm ("mov %ax, %fs");
asm ("mov %ax, %gs");
asm ("mov %ax, %ss");
// jmp into the kernel
asm ("add $0x200, %rbx");
asm ("pushq $0x10");
asm ("pushq %rbx");
asm ("lretq");
__builtin_unreachable();
}
如何params
设置:
CopyMem(¶ms->hdr, kernel + 0x01F1, (0x0202 + kernel[0x0201]) - 0x01F1);
params->hdr.vid_mode = 0xFFFF; // normal
params->hdr.type_of_loader = 0xFF;
params->hdr.loadflags = QUIET_FLAG;
params->hdr.ramdisk_image = (intptr_t)initrd;
params->hdr.ramdisk_size = rdsize;
if (params->hdr.version >= 0x0202) {
// FIXME: ensure command_line is not above 4gb
// FIXME: use "auto" in case of no command line in the configuration
params->hdr.cmd_line_ptr = (intptr_t)conf->command_line;
}
如何start_kernel
被调用:
// setup gdt
gdt = AllocateZeroPool(sizeof(*gdt));
if (!gdt) {
Print(L"Failed to allocated %u bytes for GDT\n", sizeof(*gdt));
goto fail_with_params;
}
gdt->limit = 8 * 4;
gdt->base = AllocateZeroPool(gdt->limit);
if (!gdt->base) {
Print(L"Failed to allocated %u bytes for GDT entries\n", gdt->limit);
goto fail_with_gdt;
}
gdt->base[2] = 0x00AF9A000000FFFF; // cs
gdt->base[3] = 0x00CF92000000FFFF; // ds
gdt->limit--;
// terminate boot service
map = LibMemoryMap(&count, &key, &size, &ver);
if (!map) {
Print(L"Failed to get system memory map\n");
goto fail_with_gdt;
}
es = BS->ExitBootServices(tcg, key);
if (EFI_ERROR(es)) {
Print(L"Failed to terminate boot services: %r\n", es);
goto fail_with_map;
}
// jump to the kernel
start_kernel((intptr_t)kernel, params, gdt);
解决方案
推荐阅读
- python - 是否可以将 fastapi 与 gremlin-python 一起使用?
- python - DRF 添加非模型字段只是为了更新或创建模型实例
- javascript - 我是否必须做任何事情才能使我的 Electron 应用程序“与 Citrix 兼容”?
- reactjs - React SSR React Router Dom Switch, Route, Link "Invariant Failed"
- java - 我没有看到 Gradle / Maven 的意义
- javascript - 带有地图 JavaScript 的条件过滤数组
- javascript - 如何使用 jquery 在占位符中的文本后放置红色星号标记?
- r - Group_by 和过滤或嵌套在 tidyverse 中。如何取消过滤()然后再次过滤()?
- python - 使用 CMake 在可移植 C++ 应用程序中嵌入 python 和 numpy
- php - 使用 rest api 将优惠券应用于 WooCommerce 订单