Skip to contentSkip to conversation

vmlinux/vmlinux.bin loading capability

RFC PATCH In review Maciek Nowacki 3 participants 3 messages Aug 3, 2006 – Aug 7, 2006

lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/1 vmlinux/vmlinux.bin loading capability

Hi,

Here is an attempt at a patch to load and execute a vmlinux kernel image, only tested with QEMU for x86_64. It is very preliminary, excludes a large amount of planned functionality, and so far only boots the raw vmlinux.bin file found in arch/[x86_64,i386]/boot/vmlinux.bin after compiling Linux with the 'make vmlinux' target (and 'make bzImage' as well). This means that the user must supply the entry point of the kernel on the GRUB command line. This nastiness will be easily removed once vmlinux is used in place of vmlinux.bin.

vmlinux.bin is a derivative of the vmlinux kernel executable that is produced by:

objcopy -O binary linux-2.6.xx/vmlinux vmlinux.bin

My reasons for doing this are:
- eliminating real-mode code from the kernel image (and ultimately 32-bit code, in x86-64)
- allowing GRUB to have more control over the boot process
- removing the decompression code from the kernel image - instead delegating decompression to the bootloader, as an optional feature
- simplying Linux compilation by making all targets aside from vmlinux/modules redundant (indeed, even System.map is redundant with a full vmlinux present).

If vmlinux is too large, it is always possible to strip(1). With compression, it becomes very close to the size of a bzImage:

$ gzip -9c vmlinux > vmlinux.gz
$ bzip2 -9c vmlinux > vmlinux.bz2
$ strip -o vmlinux_str vmlinux
$ gzip -9c vmlinux_str > vmlinux_str.gz
$ bzip2 -9c vmlinux_str > vmlinux_str.bz2
$ ls -ltcr vmlinux*
-rwxrwxr-x 1 maciek maciek 47308143 Jul 30 21:53 vmlinux*
-rw-rw-r-- 1 maciek maciek 19453585 Aug  3 00:47 vmlinux.gz
-rw-rw-r-- 1 maciek maciek 16795427 Aug  3 00:47 vmlinux.bz2
-rwxrwxr-x 1 maciek maciek  7140752 Aug  3 00:47 vmlinux_str*
-rw-rw-r-- 1 maciek maciek  1856381 Aug  3 00:48 vmlinux_str.gz
-rw-rw-r-- 1 maciek maciek  1757941 Aug  3 00:48 vmlinux_str.bz2
$ ls -l arch/x86_64/boot/bzImage
-rw-rw-r-- 1 maciek maciek 1832285 Jul  9 18:51 arch/x86_64/boot/bzImage
$

(bzImage and vmlinux are not representative of the same .config - but it is very close. Admittedly the vmlinux .config defines a slightly smaller kernel image.)

Of course I am aware that GRUB does not currently support bzip2 decompression. However, should it gain this feature, the kernel on-disk size would decrease compared to bzImage.

Please let me know what you think. I have included an updated version of my run-grub.sh bash script which includes an example invocation of the vmlinux loader (however, it seems that GRUB truncates the command line...? I have not yet investigated this).

Maciek

conf/i386-pc.rmk +6 -1
diff -Nur -x autom4te.cache grub2_cvspull.bak/conf/i386-pc.rmk grub2_cvspull/conf/i386-pc.rmk
@@ -112,7 +112,7 @@
 pkgdata_MODULES = _chain.mod _linux.mod linux.mod normal.mod \
 	_multiboot.mod chain.mod multiboot.mod reboot.mod halt.mod	\
 	vbe.mod vbetest.mod vbeinfo.mod video.mod gfxterm.mod \
-	videotest.mod play.mod bitmap.mod tga.mod
+	videotest.mod play.mod bitmap.mod tga.mod vmlinux.mod
 
 # For _chain.mod.
 _chain_mod_SOURCES = loader/i386/pc/chainloader.c
@@ -164,6 +164,11 @@
 _multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
 _multiboot_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For vmlinux.mod.
+vmlinux_mod_SOURCES = loader/i386/pc/vmlinux.c
+vmlinux_mod_CFLAGS = $(COMMON_CFLAGS)
+vmlinux_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For multiboot.mod.
 multiboot_mod_SOURCES = loader/i386/pc/multiboot_normal.c
 multiboot_mod_CFLAGS = $(COMMON_CFLAGS)
include/grub/i386/pc/init.h +5 -2
diff -Nur -x autom4te.cache grub2_cvspull.bak/include/grub/i386/pc/init.h grub2_cvspull/include/grub/i386/pc/init.h
@@ -48,8 +48,11 @@
 
 /* Get a memory map entry. Return next continuation value. Zero means
    the end.  */
-grub_uint32_t grub_get_mmap_entry (struct grub_machine_mmap_entry *entry,
-				   grub_uint32_t cont);
+/*grub_uint32_t grub_get_mmap_entry (struct grub_machine_mmap_entry *entry,
+				   grub_uint32_t cont);*/
+/* exporting for loader/i386/pc/vmlinux.c */
+grub_uint32_t EXPORT_FUNC (grub_get_mmap_entry)
+	(struct grub_machine_mmap_entry *entry, grub_uint32_t cont);
 
 /* Turn on/off Gate A20.  */
 void grub_gate_a20 (int on);
loader/i386/pc/vmlinux.c +416 -0

416 lines not on this page · raw message

#1 lore raw
Quoted 4 lines · Maciek Nowacki

Please let me know what you think. I have included an updated version of my run-grub.sh bash script which includes an example invocation of the vmlinux loader (however, it seems that GRUB truncates the command line...? I have not yet investigated this).

I'm not sure what you really gain from this attempt. Have you asked Linux developers?

Okuji

#2 lore raw
In reply to Maciek Nowacki
Quoted 10 lines · Maciek Nowacki

Here is an attempt at a patch to load and execute a vmlinux kernel image, only tested with QEMU for x86_64. It is very preliminary, excludes a large amount of planned functionality, and so far only boots the raw vmlinux.bin file found in arch/[x86_64,i386]/boot/vmlinux.bin after compiling Linux with the 'make vmlinux' target (and 'make bzImage' as well). This means that the user must supply the entry point of the kernel on the GRUB command line. This nastiness will be easily removed once vmlinux is used in place of vmlinux.bin.

Quoted 4 lines

vmlinux.bin is a derivative of the vmlinux kernel executable that is produced by:

objcopy -O binary linux-2.6.xx/vmlinux vmlinux.bin

I have no comments on your motivation, but I do think that a binary loader would be valuable. In that case, it might make sense to refactor this code into a "binary" loader that exports a function that your Linux binary loader calls. Then you can isolate all this "linux_kernel_header" stuff from the binary loader.

You want to combine these lines:
+ asm( "movl %0,%%esi" :: "m" (lh) );
+ asm("jmp *%0" :: "m" (begin));
into a single asm statement (and make it volatile too). Otherwise, the compiler can insert instructions between the asm statements (especially at -O0), making you a very sad debugger.

There are pretty flagrant coding style violations all over the place, so I won't comment on those. I will however say that "/* notes: grub leaks memory. */" is an extraordinarily bad way to submit a bug report.

Finally, please don't call this a "vmlinux" loader. vmlinux is an ELF file. What you're loading is not.

-Hollis