Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将Linux映像加载到内存中的适当位置_Linux_Linux Kernel_Bootloader_Bootstrapping - Fatal编程技术网

如何将Linux映像加载到内存中的适当位置

如何将Linux映像加载到内存中的适当位置,linux,linux-kernel,bootloader,bootstrapping,Linux,Linux Kernel,Bootloader,Bootstrapping,我们正在尝试将linux映像加载到特定位置的DRAM中,DRAM结束地址为 0x8000000,这是我们从引导日志中得知的,引导日志上写着“mem设备结束地址为0x8000000”。我们在地址“0x5000000”处加载映像,在映像中的variuos部分之前,从引导日志中再次为eaxmple加载大于“0x8000000”的某个地址 loading section to address 0xc5000000 from file position 0x1000, size is 0x5ac13e

我们正在尝试将linux映像加载到特定位置的DRAM中,DRAM结束地址为 0x8000000,这是我们从引导日志中得知的,引导日志上写着“mem设备结束地址为0x8000000”。我们在地址“0x5000000”处加载映像,在映像中的variuos部分之前,从引导日志中再次为eaxmple加载大于“0x8000000”的某个地址

 loading section to address 0xc5000000 from file position 0x1000, size is 0x5ac13e
上面一行中“来自文件位置0x1000”的含义是什么

加载的第一个部分是.text部分,下面是我们的vmlinux映像转储的部分头

[Nr]      Name           Type            Addr     Off    Size   ES Flg Lk Inf Al

[ 0]                     NULL            00000000 000000 000000 00      0   0  0

 [ 1]   .text            PROGBITS        c5000000 001000 5ac13e 00  AX  0   0 4096

 [ 2]      .notes           NOTE            c55ac140 5ad140 000168 00  AX  0   0  4

 [ 3]    __ex_table        PROGBITS        c55ac2b0 5ad2b0 000fe0 00   A  0   0  4

 [ 4]   .rodata           PROGBITS        c55ae000 5af000 20a930 00   A  0   0 64

 [ 5]   __bug_table       PROGBITS        c57b8930 7b9930 0075fc 00   A  0   0  1

 [ 6]   .pci_fixup        PROGBITS        c57bff2c 7c0f2c 001a90 00   A  0   0  4

 [ 7]    .builtin_fw       PROGBITS        c57c19bc 7c29bc 0000cc 00   A  0   0  4
这是一个相当大的列表,所以没有发布完整的内容。但有一点我们可以在这里看到。文本部分大于DRAM结束地址,所以图像不应该正确放置,尽管在加载第一部分后我们没有收到任何错误,但它会继续加载其他部分,但在此消息之后它会挂起

    program load complete, entry point: 0x5000000, size: 0x92e7fc
我的问题是如何将这些不同的部分地址与我们的DRAM地址对齐, Is objcopy实用程序可用于更改这些不同部分的地址

有没有办法在编译之前设置这些分区地址??
第二件事是什么原因导致程序加载完成后挂起

来自文件位置0x1000
表示它所说的内容。你把它放在垃圾堆里了:

[Nr]      Name           Type            Addr     Off    Size   ES Flg Lk Inf Al
...
[ 1]   .text            PROGBITS        c5000000 001000 5ac13e 00  AX  0   0 4096
它是文件中
.text
部分的起始位置,偏移量
0x1000

但有一件事我们可以在这里看到,文本部分大于DRAM结束地址

不,它不是更大(至少不是在更大的意义上),它被编译是为了期望它将被加载到内存中的地址
0xc500000

所以图像不应该被正确地分块,虽然我们在加载第一部分后并没有得到任何错误,但它会继续加载其他部分

图像可以在任何地方加载,它只是用于加载的数据

OTOH,如果
加载节到地址0xc500000
的意思是它所说的,那么文件将不会加载到任何地方,因为您的RAM在
0x7fffffff
处结束

但在这条消息之后,它就挂起了

    program load complete, entry point: 0x5000000, size: 0x92e7fc
这是意料之中的。机器代码很少是位置独立的,所以如果你在不同的位置加载它,它就不会工作。或者如果它甚至没有被加载,那么你将执行什么?垃圾

有没有办法在编译之前设置这些分区地址

根据系统的不同,您可能有以下两个选项中的一个或两个:

  • 设置页面转换,使整个程序的虚拟地址从
    0xc5000000
    和up映射到物理地址从
    0x5000000
    和up
  • 找到编译器正在使用的链接器脚本,并将初始节地址从
    0xc500000
    更改为
    0x5000000
    ,用谷歌搜索,请参阅编译器/链接器文档

另外,入口点位于
0x5000000
有点奇怪。这并不一定是错的,只是情况很少如此。我要确保
开始
标签(或
\u开始
或其他任何标签)确实接收到与
.text
部分开头相同的地址。如果出于某种原因,情况并非如此,则链接器脚本或编译器/链接器命令行选项或加载程序出现问题。

您使用的加载程序是什么?“形象”的形式是什么?U-boot映像,原始映像,vmlinux ELF文件?我猜最后一个是根据ELF文件中是否存在节等来判断的。您不应该加载节,而应该加载所谓的程序头。例如,这是OpenRISC linux内核程序头列表(使用
readelf-l
获得):

查看
VirtAddr
physadr
之间的区别(由于通常的Linux内核映射而被删除
c
)。当然,应该使用物理地址进行加载

内核对符号、节等使用虚拟地址的原因是,在引导过程中,您可以快速进入MMU初始化的时刻,虚拟地址是唯一有效的地址


最后,关于更改这些地址。事实上,正如Alexey所指出的,链接器脚本是关键。您可以在
arch/(您的arch)/kernel/vmlinux.lds.S
中找到这些。但问题是这不是你的问题,问题可能在于加载程序或其选项。

检查你的arch/arm/mach xxx/Makefile.boot(你使用的是arm板吗?)

这是来自Ti omap3芯片


我想你也需要同样的

谢谢@Alexey的友好回复。我想与你分享我在问题中遗漏的几件事,我们通过更改内核的.config文件更改了入口点0x5000000,因为无法将映像加载到默认地址0x1000000。第二件事是我们之前已将基于QNX的内核映像加载并执行到同一DRAM,现在我们可以为QNX映像在Linux内核映像中使用的部分和入口点地址使用相同的地址吗?您提出的另一点是入口点是.text部分的一部分。这是
吗?现在我们可以为QNX映像在Linux内核中使用的部分和入口点地址使用相同的地址吗图像
一个问题?我不太明白你的意思。嗨,Alexey,正如你所建议的,在更改页偏移量值后,获得了2GB范围内的节地址,并且在程序加载完成后,消息我们的映像没有挂起,但我们遇到了其他问题,很快它说程序加载完成,CPU被重置,而不是控制Linux内核映像,我想听听你那边关于这件事的一两句话,我不知道。但我建议你首先让一个小程序工作,然后再回到整个操作系统,也许,做增量的“检查点”(例如,在屏幕上打印一些东西或打印到一个串行文件)
  zreladdr-y        += 0x80008000
params_phys-y       := 0x80000100
initrd_phys-y       := 0x80800000