Мне нужна помощь в разборе распакованного Linux изображения в parse_elf()
в arch/x86/boot/compressed/misc.c
. В частности, я не понимаю, из каких областей памяти сегменты ELF копируются в и из. Ниже приведен аннотированный код, показывающий мое (неправильное) понимание.
for (i = 0; i < ehdr.e_phnum; i++) { // For each segment...
phdr = &phdrs[i];
switch (phdr->p_type) { // Ignore all segments that
case PT_LOAD: // aren't labeled as loadable
#ifdef CONFIG_RELOCATABLE
dest = output; // Set `dest` to be equal to the base of the kernel
// after decompression and KASLR considerations
// Next, add to `dest` the difference between the physical address
// of the segment and where the kernel was told to be loaded by the
// kernel configuration file. It seems to me that this difference
// is equal to `phdr->p_offset`.
dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
#else
// If we aren't considering relocations then just use the physical
// address of the segment as the destination.
dest = (void *)(phdr->p_paddr);
#endif
// Copy, to the destination determined above, from the beginning
// of the decompressed kernel plus the offset to the segment until
// the end of the segment is reached.
memcpy(dest,
output + phdr->p_offset,
phdr->p_filesz);
break;
default: /* Ignore other PT_* */ break;
}
}
Что сбивает с толку, так это то, что в случае перемещения первый и второй аргументы memcpy
кажутся одинаковыми и нет смысла звонить parse_elf
. Возможно, я неправильно понимаю, что такое LOAD_PHYSICAL_ADDR
или phdr->p_paddr
, или шаги, предпринятые после распаковки ядра на месте.
Случай отсутствия перемещения имеет больше смысла, поскольку нам просто нужно скопировать из распакованного ядра по «жестко запрограммированному» адресу.