Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
[Solved] Linking existing kernel with new initramfs
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Portage & Programming
View previous topic :: View next topic  
Author Message
blochl
n00b
n00b


Joined: 28 Aug 2018
Posts: 16

PostPosted: Thu Oct 18, 2018 11:24 am    Post subject: [Solved] Linking existing kernel with new initramfs Reply with quote

Hello,

I'm quite puzzled with the following problem: I have an xz-compressed bzImage, which contains an internal initramfs, and I want to make changes to the initramfs without re-compiling the kernel (because the changes might be done in a totally different environment from where the kernel was compiled).
Using an external initramfs which will be merged with the internal one at boot time is not an option, because I want a single bootable file (that can be signed) in the end.

I have read this and this tutorials about how a new initramfs might be inserted into an existing kernel, but the first one looks like it is written for someone who already knows what they are doing, and I can't figure out how to apply it to my case. The second one (section: "Combine the kernel, initramfs, and boot options") while really detailed, addresses a different scenario from what I have, and again, I can't figure out how to apply it to my case.

Can someone please explain (or point me to another tutorial) how given a bzImage with internal initramfs and a new initramfs I can get a bzImage linked only with the new initramfs?

I think that the solution should be similar to the tutorials above, I just can't get the exact procedure so far...


Last edited by blochl on Wed Oct 24, 2018 12:55 pm; edited 1 time in total
Back to top
View user's profile Send private message
khayyam
Watchman
Watchman


Joined: 07 Jun 2012
Posts: 6227
Location: Room 101

PostPosted: Thu Oct 18, 2018 1:39 pm    Post subject: Re: Linking existing kernel with new initramfs Reply with quote

blochl wrote:
I have read this and this tutorials about how a new initramfs might be inserted into an existing kernel, but the first one looks like it is written for someone who already knows what they are doing, and I can't figure out how to apply it to my case.

blochl ... the instructions from coreboot look pretty staightforward to me:

Code:
# file initramfs
initramfs: ASCII cpio archive (SVR4 with no CRC)
# objcopy -I binary -O elf32-i386 -B i386 --redefine-sym _binary_initramfs_start=.init.ramfs -N _binary_initramfs_end -N _binary_initramfs_size initramfs initramfs.elf
# file initramfs.elf
initramfs.elf: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
# cp /usr/src/linux/vmlinux .
# file vmlinux
vmlinux: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, BuildID[sha1]=364adc71e0470c199d5cd55e6bcaeb9163943ce4, not stripped
# objcopy -I elf32-i386 -O elf32-i386 -R .init.ramfs --add-section .init.ramfs=initramfs.elf vmlinux vmlinux.withnewinitramfs
# ls -lh vmlinux*
-rwxr-xr-x 1 root root 10M 2018-04-28 19:46 vmlinux*
-rwxr-xr-x 1 root root 16M 2018-10-18 15:31 vmlinux.withnewinitramfs*

The initramfs involved is much bigger than the one currently in use, and so the output seems about right, though I haven't attempted to boot it.

Any questions, just ask ... best ... khay
Back to top
View user's profile Send private message
blochl
n00b
n00b


Joined: 28 Aug 2018
Posts: 16

PostPosted: Thu Oct 18, 2018 5:41 pm    Post subject: Reply with quote

Sorry, guess I wasn't specific enough. And thanks for the `file` clarifications, khayyam - that already made things a bit more clear. Though you use an uncompressed initramfs, and they use gzipped.

Currently my main showstopper is compression: as I said, I have an xz-compressed bzImage, while the instructions from coreboot require uncompressed vmlinux. Sure, I can get vmlinux with the in-tree script "scripts/extract-vmlinux", but then how can I compress it back?

On the other hand, in the second tutorial a compressed kernel is OK, but it requires the initramfs to be uncompressed. Sure, I can uncompress it before linking, but then the kernel will take much more space (as the initramfs will not be compressed after linking) and also they are not clear about what is "linuxx64.efi.stub" they refer to, if the kernel in their example is "vmlinuz-linux".

There are some more technical questions (like why the VMA addresses are set to these values (0x40000, 0x3000000)?) but the showstopper for me now is what to do with the compression.
Back to top
View user's profile Send private message
blochl
n00b
n00b


Joined: 28 Aug 2018
Posts: 16

PostPosted: Sat Oct 20, 2018 9:56 am    Post subject: Reply with quote

Another problem: I don't even see the relevant section (".init.ramfs") in vmlinux (although it definitely has the initramfs linked-in). All I see is:

Code:

vmlinux:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00602000  ffffffff81000000  0000000001000000  00200000  2**12
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .notes        00000024  ffffffff81602000  0000000001602000  00802000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 __ex_table    0000255c  ffffffff81602030  0000000001602030  00802030  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .rodata       0010ee78  ffffffff81800000  0000000001800000  00a00000  2**12
                  CONTENTS, ALLOC, LOAD, DATA
  4 .pci_fixup    00003300  ffffffff8190ee78  000000000190ee78  00b0ee78  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 __param       00002120  ffffffff81912178  0000000001912178  00b12178  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 __modver      00000d68  ffffffff81914298  0000000001914298  00b14298  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .data         00086a80  ffffffff81a00000  0000000001a00000  00c00000  2**13
                  CONTENTS, ALLOC, LOAD, DATA
  8 __bug_table   00009f60  ffffffff81a86a80  0000000001a86a80  00c86a80  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  9 .orc_unwind_ip 0006e860  ffffffff81a909e0  0000000001a909e0  00c909e0  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 10 .orc_unwind   000a5c90  ffffffff81aff242  0000000001aff242  00cff242  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 11 .orc_lookup   00018084  ffffffff81ba4ed4  0000000001ba4ed4  00da4ed2  2**0
                  ALLOC
 12 .vvar         00001000  ffffffff81bbd000  0000000001bbd000  00dbd000  2**4
                  CONTENTS, ALLOC, LOAD, DATA
 13 .init.text    0002b7bd  ffffffff81bbe000  0000000001bbe000  00dbe000  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 14 .altinstr_aux 000007de  ffffffff81be97bd  0000000001be97bd  00de97bd  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 15 .init.data    00506678  ffffffff81bea000  0000000001bea000  00dea000  2**13
                  CONTENTS, ALLOC, LOAD, DATA
 16 .x86_cpu_dev.init 00000018  ffffffff820f0678  00000000020f0678  012f0678  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 17 .altinstructions 00002db4  ffffffff820f0690  00000000020f0690  012f0690  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 18 .altinstr_replacement 00000abd  ffffffff820f3444  00000000020f3444  012f3444  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 19 .iommu_table  00000050  ffffffff820f3f08  00000000020f3f08  012f3f08  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 20 .apicdrivers  00000010  ffffffff820f3f58  00000000020f3f58  012f3f58  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 21 .exit.text    00001282  ffffffff820f3f68  00000000020f3f68  012f3f68  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 22 .data..percpu 00000000  ffffffff820f6000  00000000020f51ea  012f51ea  2**0
                  CONTENTS, ALLOC, LOAD, DATA
 23 .smp_locks    00000000  ffffffff820f6000  ffffffff820f6000  012f51ea  2**0
                  CONTENTS
 24 .data_nosave  00000000  ffffffff820f6000  ffffffff820f6000  012f51ea  2**0
                  CONTENTS
 25 .bss          00031000  ffffffff820f6000  00000000020f6000  012f51ea  2**12
                  ALLOC
 26 .brk          0002c000  ffffffff82127000  0000000002127000  012f51ea  2**0
                  ALLOC
Back to top
View user's profile Send private message
khayyam
Watchman
Watchman


Joined: 07 Jun 2012
Posts: 6227
Location: Room 101

PostPosted: Sat Oct 20, 2018 10:46 am    Post subject: Reply with quote

blochl ...

I'm currently in the process of packing for a move next week, and so don't have time to see what might be done re compression. I know there is a script for this in the kernel sources, but it's not something I've done (and so would have to search and see what I came up with). Subsequent to the move I'll be offline until I'm able to afford service ... so, at this time I'm not in the best situation to help, sorry. Hopefully someone else will jump in.

good luck & best ... khay
Back to top
View user's profile Send private message
blochl
n00b
n00b


Joined: 28 Aug 2018
Posts: 16

PostPosted: Sat Oct 20, 2018 6:01 pm    Post subject: Reply with quote

khay, I really appreciate that! Thanks! And good luck with your moving!

I couldn't find a script for that in the kernel sources, and as I saw the compression process is quite complicated: there are different headers that need to be prepended, etc...
I'll keep looking. Thanks for any additional help...
Back to top
View user's profile Send private message
blochl
n00b
n00b


Joined: 28 Aug 2018
Posts: 16

PostPosted: Sun Oct 21, 2018 7:05 pm    Post subject: Reply with quote

OK, after more research into this, my goals have changed just a bit:
Instead of changing the embedded initramfs (which has some delicate parts in it) it would be much better to use the mechanism that exists in the kernel for merging an external initramfs with the internal one. But, in order to be signed, the external initrd (it loads as initrd, despite being an initramfs) should still be a part of the kernel. So I'm looking at the following now:

This, where the initrd is linked to the ready-made compressed kernel, with the following command (I modified it here for my case):
Code:

objcopy --add-section .initrd="external.initramfs" \
    --change-section-vma .initrd=0x3000000 \
    original-bzImage new-bzImage


But this doesn't work. The system doesn't boot with such a kernel.

The output of
Code:
objdump -h new-bzImage
is:
Code:

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .setup        00003be0  0000000000000200  0000000000000200  00000250  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .reloc        00000020  0000000000003de0  0000000000003de0  00003e30  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .text         0071d230  0000000000003e00  0000000000003e00  00003e50  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  3 .bss          00c5afd0  0000000000721030  0000000000721030  00000000  2**4
                  ALLOC
  4 .initrd       00000200  0000000003000000  0000000003000000  00721090  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA


I also get this warning from the "objcopy" part:
Code:

Warning: Ignoring section flag IMAGE_SCN_MEM_NOT_PAGED in section .bss


The second place I'm looking at is here. There they manage to load the initrd not from a file, but from a specific location in the memory. So I see that something like this is possible, although their case is very different from mine.

Does anyone have a clue how could I load an "external" initrd from the same file that already contains an internal initramfs? Really banging my head against the wall here... :)
Back to top
View user's profile Send private message
blochl
n00b
n00b


Joined: 28 Aug 2018
Posts: 16

PostPosted: Wed Oct 24, 2018 12:54 pm    Post subject: Reply with quote

Alright, marking this as solved, because I've realized that this problem is unsolvable:

* The externally linked section is good only for systemd-boot, and I can't use this, because I want my kernel to be bootable in legacy mode as well as in UEFI, but systemd-boot "EFI Unified Kernel Images" are working only with UEFI boot.
* Re-linking the initramfs inside the kernel is impossible to do in a reliable way: first of all, a lot of work needs to be done to re-link the binary, and even when done and automated, there is no guarantee that it will work on another version of the kernel, or even on the same version that was compiled with a different config.

Therefore I'm going for the really messy solution of recompiling the kernel each time I want to change the initramfs. It's very messy and not elegant, but it's the only way to get what I want in a reliable manner.

I'm amazed of the asymmetry - how easy it is to extract the built-in initramfs, and how difficult it is to insert a new one in its place!
Back to top
View user's profile Send private message
khayyam
Watchman
Watchman


Joined: 07 Jun 2012
Posts: 6227
Location: Room 101

PostPosted: Wed Oct 24, 2018 8:46 pm    Post subject: Reply with quote

blochl wrote:
Therefore I'm going for the really messy solution of recompiling the kernel each time I want to change the initramfs. It's very messy and not elegant, but it's the only way to get what I want in a reliable manner.

blochl ... why not build an initramfs that doesn't require updating? ... there's no reason to really (it's just that some think it a good idea to include kernel modules in the initramfs). Here's an example, or the prebuilt version. Note, these will be built against uClibc (and with the 'devel' branch, musl), and so the size is considerably smaller.

Back to packing!!! & best ... khay
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Portage & Programming All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum