我的链接器脚本:
SECTIONS{
. = 0xC0008000;
__text_start = .;
.text :
{
boot/start.o
*(.text)
}
__text_end = .;
.rodata ALIGN(4) : {*(.rodata*)}
.data ALIGN(4) : { *(.data) }
__bss_start = .;
.bss ALIGN(4) : { *(.bss) *(COMMON) }
__bss_end = .;
}
0xC 0008000是引导加载程序的地址,我想在QEMU中指定它。
这是我尝试过的。\
qemu-system-arm \
-machine virt \
-cpu cortex-a15 \
-nographic \
-S -s \
-m 4096M \
-kernel Image \
# -device loader,file=Image,addr=0xC0008000
它会将PC设置为0x 40000000,在几个指令后,PC将跳转到0x 40010000的引导加载程序。根据QEMU提供的文件,这是可以接受的,但不是我期望做的。
RAM从0x4000_0000 https://qemu.readthedocs.io/en/latest/system/arm/virt.html开始
但当我将命令更改为
qemu-system-arm \
-machine virt \
-cpu cortex-a15 \
-nographic \
-S -s \
-m 4096M \
-kernel Image \
-device loader,file=Image,addr=0xC0008000
镜像加载正确,似乎是0xC 0008000中指令的0x 40010000中的重复指令,但它不能跳转到0xC 0008000,这使得调试困难。我想知道为什么PC不能跳到我期望的地方。谢谢!
2条答案
按热度按时间b91juud31#
你没有说你的图像文件是什么格式。它是一个ELF文件,还是一个原始的二进制文件?从描述的行为来看,我猜这是一个原始的二进制文件。
如果您向QEMU传递
-kernel
选项,那么您就是在说“这个文件应该以Linux内核期望的方式启动”。这意味着,除其他事项外,你不关心它在内存Map中的位置,它应该首先设置几个寄存器,然后跳转到图像的开始。(有一个例外:ELF文件是根据ELF文件指示它们应该放置的位置来加载的,并通过跳转到ELF入口点来启动。但是现在ELF文件更好地使用通用加载器加载。)(The“像Linux内核一样 Boot 我”的具体含义在this bit of the kernel documentation中列出。virt板将始终传递设备树blob,而不是ATAG。)
如果您的映像文件不希望像Linux内核那样引导,则不应使用
-kernel
选项。相反,您可以使用通用加载器(
-device loader
)。您的第二个命令行几乎可以做到这一点,但它在两个方面是错误的:1.你没有删除
-kernel
选项,所以你的镜像文件将被QEMU加载两次,在两个不同的地方。这只是令人困惑,所以删除-kernel
选项。1.要让通用加载程序为CPU设置启动PC,您需要显式地请求它。由于您想要的启动PC与映像加载地址相同,因此可以使用
-device loader,file=Image,addr=0xc0008000,cpu-num=0
来执行此操作。cpu-num部分说明要为PC设置哪个CPU。(如果需要,可以使用更复杂的语法将PC设置为图像加载地址以外的其他地址。)注1:以上是原始图像文件。如果你有一个ELF文件,那么通用加载器将把文件加载到ELF文件指定的地址,你不需要指定
addr=
。如果您使用cpu-num=
,它将使用初始PC的ELF入口点。注2:对于32位CPU来说,4GB的RAM相当多。Cortex-A15具有LPAE,所以并不是说不可能访问超过4GB物理地址标记的RAM部分,但这似乎很奇怪。3GB(即从0x4000_0000到0xFFFF_FFFF的RAM)可能同样有用,并且可以保存VM使用的主机资源。
f4t66c6m2#
当您使用
-kernel
选项时,qemu将执行以下操作:1.在地址(
0x40010000
)加载内核映像1.将PC设置为启动DRAM基座(
0x40000000
)0x40010000
)现在,如果你想传输你的内核映像并开始执行而不执行上面的操作,那么将使用下面的命令:
要在特定位置传输内核,请执行以下操作:
-device guest-loader,addr=<addr, where you want to copy img>,kernel=<kernel_img_path>
要在内核启动时加载PC,请执行以下操作:
-device loader,addr=<addr, where you copied your img>,cpu-num=0