问题描述
我想要一个简单的PVH内核,它将由qemu加载并启动入口点。到目前为止,我有我的链接描述文件:
ENTRY(pvh_start_addr)
SECTIONS
{
. = 1M;
.text : { *(.boot.text)
*(.text) }
. = ALIGN(4K);
.data : { *(.data) }
.bss : { *(.bss) }
.notes : { *(.notes) }
}
和代码:
.section .notes,"a"
.balign 4096
.align 4
.long 4
.long 4
.long 18 /* XEN..PHYS32 */
.asciz "Xen"
.align 4
.long pvh_start_addr
.long 0x101000
.align 4
.balign 16
.code64
.section ".boot.text","ax"
.global pvh_start_addr
pvh_start_addr:
jmp pvh_start_addr
Qemu通过错误获取起始地址将小精灵作为PVH二进制文件加载。无论如何,它的SEG错误在这里:
qemu-5.1.0/hw/i386/x86.c:417
417 pvh_start_addr = *elf_note_data_addr;
这项工作还是需要其他精灵注释才能完成?
解决方法
您用于创建ELF注释的代码似乎对注释描述符字段的大小具有错误的值:n_namesz和n_descsz字段都具有“ .long 4”,但是尽管name字段的确是4字节长(“ XEN \ 0”)描述符在64位系统上为8个字节长(因为它是“ .long pvh_start_addr”)。
您可以考虑在ELFNOTE宏上使用Xen itself uses的某些变体:
#define ELFNOTE(name,type,desc) \
.pushsection .note.name ; \
.align 4 ; \
.long 2f - 1f /* namesz */ ; \
.long 4f - 3f /* descsz */ ; \
.long type /* type */ ; \
1:.asciz #name /* name */ ; \
2:.align 4 ; \
3:desc /* desc */ ; \
4:.align 4 ; \
.popsection
然后,您可以(假设您已为常量18定义了常量XEN_ELFNOTE_PHYS32_ENTRY)进行写
ELFNOTE(Xen,XEN_ELFNOTE_PHYS32_ENTRY,.long,my_entry_label)
,然后让宏为您计算名称和描述符大小。
,在qemu中,当加载ELF文件时会有一个but。对于64位ELF文件,对齐方式仍然是32位值。
uint64_t phdr_align = *(uint64_t *)arg2;
应该更改为
uint64_t phdr_align = *(uint32_t *)arg2;