Discussion:
Convert grub2 kernel core.img to linux kernel format
Bean
2007-12-01 14:16:38 UTC
Permalink
Hi,

I've just written a header file that can be used to convert core.img
to linux kernel format:

cat lnxhdr.bin core.img > grub2.bin

You can then load grub2.bin from syslinux/isolinux/pxelinux/lilo or
any other boot loader that supports linux kernel.

qemu support linux kernel as well. Now you can start grub2 like this:

qemu -kernel grub2.bin -hda aa.dsk

To compile lnxhdr.bin, use the following commands:

gcc -nostdlib -Wl,-N -o lnxhdr lnxhdr.S
objcopy -O binary lnxhdr lnxhdr.bin
--
Bean
Robert Millan
2007-12-06 11:56:46 UTC
Permalink
Post by Bean
Hi,
I've just written a header file that can be used to convert core.img
cat lnxhdr.bin core.img > grub2.bin
You can then load grub2.bin from syslinux/isolinux/pxelinux/lilo or
any other boot loader that supports linux kernel.
qemu -kernel grub2.bin -hda aa.dsk
gcc -nostdlib -Wl,-N -o lnxhdr lnxhdr.S
objcopy -O binary lnxhdr lnxhdr.bin
Very nice! Can you resend as a patch that puts it in the tree ? (+ ChangeLog)
--
Robert Millan

<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call, if you are unable to speak?
(as seen on /.)
Bean
2007-12-06 16:13:03 UTC
Permalink
Hi,

Added a new file boot/i386/pc/lnxboot.S, which will compile into
lnxboot.img. You can use it in a few ways:

1, Use it as standalone kernel, core.img as initrd

kernel lnxboot.img
initrd core.img

For example, you can start grub2 in qemu like this:

qemu -kernel lnxboot.img -initrd core.img ...

2, Create a combined kernel:

cat lnxboot.img core.img > grub2.img

You can then load grub2.img as kernel

kernel grub2.img

The image grub2.img can also be loaded using the grldr boot loader.
--
Bean
Robert Millan
2007-12-12 15:34:19 UTC
Permalink
Post by Bean
Hi,
Added a new file boot/i386/pc/lnxboot.S, which will compile into
Could you make this boot/i386/lnxboot.S ? In principle, this should work on
other firmware (except maybe EFI). It'd also be good to include it in the
makefile for at least i386-linuxbios.
--
Robert Millan

<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call, if you are unable to speak?
(as seen on /.)
Bean
2007-12-12 16:20:36 UTC
Permalink
Ok.

2007-12-12 Bean <***@gmail.com>

* conf/i386-pc.rmk (pkgdata_IMAGES): Add lnxboot.img.
(lnxboot_img_SOURCES): New variable.
(lnxboot_img_ASFLAGS): Likewise.
(lnxboot_img_LDFLAGS): Likewise.

* conf/i386-linuxbios.rmk (pkgdata_PROGRAMS): Add lnxboot.img
(lnxboot_img_SOURCES): New variable.
(lnxboot_img_ASFLAGS): Likewise.
(lnxboot_img_LDFLAGS): Likewise.

* boot/i386/lnxboot.S: New file.


Index: conf/i386-pc.rmk
===================================================================
RCS file: /sources/grub/grub2/conf/i386-pc.rmk,v
retrieving revision 1.94
diff -u -p -r1.94 i386-pc.rmk
--- conf/i386-pc.rmk 18 Nov 2007 06:41:45 -0000 1.94
+++ conf/i386-pc.rmk 6 Dec 2007 15:56:02 -0000
@@ -5,7 +5,7 @@ COMMON_CFLAGS = -fno-builtin -mrtd -mreg
COMMON_LDFLAGS = -m32 -nostdlib

# Images.
-pkgdata_IMAGES = boot.img diskboot.img kernel.img pxeboot.img
+pkgdata_IMAGES = boot.img diskboot.img kernel.img pxeboot.img lnxboot.img

# For boot.img.
boot_img_SOURCES = boot/i386/pc/boot.S
@@ -22,6 +22,11 @@ diskboot_img_SOURCES = boot/i386/pc/disk
diskboot_img_ASFLAGS = $(COMMON_ASFLAGS)
diskboot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,8000

+# For lnxboot.img.
+lnxboot_img_SOURCES = boot/i386/lnxboot.S
+lnxboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+lnxboot_img_LDFLAGS = $(COMMON_LDFLAGS) -Wl,-N,-Ttext,6000
+
# For kernel.img.
kernel_img_SOURCES = kern/i386/pc/startup.S kern/main.c kern/device.c \
kern/disk.c kern/dl.c kern/file.c kern/fs.c kern/err.c \
Index: conf/i386-linuxbios.rmk
===================================================================
RCS file: /sources/grub/grub2/conf/i386-linuxbios.rmk,v
retrieving revision 1.3
diff -u -p -r1.3 i386-linuxbios.rmk
--- conf/i386-linuxbios.rmk 18 Nov 2007 06:41:45 -0000 1.3
+++ conf/i386-linuxbios.rmk 12 Dec 2007 16:15:45 -0000
@@ -5,7 +5,12 @@ COMMON_CFLAGS = -ffreestanding -mrtd -mr
COMMON_LDFLAGS = -nostdlib -static -lgcc

# Images.
-pkgdata_PROGRAMS = kernel.elf
+pkgdata_PROGRAMS = kernel.elf lnxboot.img
+
+# For lnxboot.img.
+lnxboot_img_SOURCES = boot/i386/lnxboot.S
+lnxboot_img_ASFLAGS = $(COMMON_ASFLAGS)
+lnxboot_img_LDFLAGS = -m32 -nostdlib -Wl,-N,-Ttext,6000

# For kernel.elf.
kernel_elf_SOURCES = kern/i386/linuxbios/startup.S kern/i386/linuxbios/init.c \
Index: boot/i386/lnxboot.S
===================================================================
RCS file: /sources/grub/grub2/boot/i386/lnxboot.S,v
diff -Nu boot/i386/lnxboot.S
--- /dev/null 2007-12-07 07:38:42.252044265 +0800
+++ boot/i386/lnxboot.S 2007-12-06 23:49:09.359375000 +0800
@@ -0,0 +1,292 @@
+/* -*-Asm-*- */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 1999,2000,2001,2002,2005,2006,2007 Free Software
Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/boot.h>
+#include <grub/machine/boot.h>
+#include <grub/machine/kernel.h>
+
+ .file "lnxboot.S"
+
+#define CODE_ADDR 0x6000
+#define CODE_LENG (code_end - start)
+#define DATA_ADDR ((GRUB_BOOT_MACHINE_KERNEL_ADDR) + 0x200)
+
+#define BLCK_LENG 0x4000
+
+ .text
+
+ .code16
+
+ .globl start, _start
+
+data_start:
+ pushw %cs
+ popw %ds
+ xorl %eax, %eax
+ xorl %ebx, %ebx
+ call data_next
+
+data_next:
+ popw %bx
+ movw %cs, %ax
+ shll $4, %eax
+ leal 0x200 + data_start - data_next(%ebx,%eax), %eax
+ movzbl setup_sects - data_next(%bx), %ecx
+ shll $9, %ecx
+ addl %ecx, %eax
+ movl %eax, code32_start - data_next(%bx)
+
+ jmp linux_next
+
+ . = data_start + 0x1F1
+
+setup_sects:
+ .byte (CODE_LENG >> 9)
+root_flags:
+ .word 0
+syssize:
+ .word 0
+swap_dev:
+ .word 0
+ram_size:
+ .word 0
+vid_mode:
+ .word 0
+root_dev:
+ .word 0
+boot_flag:
+ .word 0xAA55
+
+start:
+_start:
+
+ jmp linux_code
+
+ .ascii "HdrS" // Header signature
+ .word 0x0203 // Header version number
+
+realmode_swtch:
+ .word 0, 0 // default_switch, SETUPSEG
+start_sys_seg:
+ .word 0x1000 // obsolete
+version_ptr:
+ .word 0 // version string ptr
+type_of_loader:
+ .byte 0 // Filled in by boot loader
+loadflags:
+ .byte 1 // Please load high
+setup_move_size:
+ .word 0 // Unused
+code32_start:
+ .long 0x100000 // 32-bit start address
+ramdisk_image:
+ .long 0 // Loaded ramdisk image address
+ramdisk_size:
+ .long 0 // Size of loaded ramdisk
+bootsect_kludge:
+ .word 0, 0
+heap_end_ptr:
+ .word 0
+pad1:
+ .word 0
+cmd_line_ptr:
+ .long 0 // Command line
+ramdisk_max:
+ .long 0xffffffff // Highest allowed ramdisk address
+
+gdt:
+ .long 0, 0, 0, 0 // Must be zero
+ .word 0xffff // 64 K segment size
+gdt_src1:
+ .byte 0, 0 ,0 // Low 24 bits of source addy
+ .byte 0x93 // Access rights
+ .byte 0 // Extended access rights
+gdt_src2:
+ .byte 0 // High 8 bits of source addy
+ .word 0xffff // 64 K segment size
+gdt_dst1:
+ .byte 0, 0, 0 // Low 24 bits of target addy
+ .byte 0x93 // Access rights
+ .byte 0 // Extended access rights
+gdt_dst2:
+ .byte 0 // High 8 bits of source addy
+ .long 0, 0, 0, 0 // More space for the BIOS
+
+reg_edx:
+ .byte 0x80,0,0xFF,0xFF
+
+data_leng:
+ .long 0
+
+linux_code:
+
+ movw %cs:(reg_edx - start), %dx
+
+linux_next:
+
+ call normalize
+
+normalize:
+ popw %bx
+ subw $(normalize - start), %bx
+ shrw $4, %bx
+ movw %cs, %ax
+ addw %bx, %ax
+ pushw %ax
+ pushw $(real_code - start)
+ lret // jump to real_code
+
+real_code:
+ subw $0x20, %ax
+ movw %ax, %ds
+ movw (setup_sects - data_start), %cx
+ shlw $7, %cx
+
+ // Setup stack
+
+ xorw %si, %si
+ movw %si, %ss
+ movw $(CODE_ADDR), %sp
+
+ pushl %esi
+ pushl %edi
+
+ // Move itself to 0:CODE_ADDR
+
+ cld
+ movw %cs, %ax
+ movw %ax, %ds
+ movw $(CODE_ADDR >> 4), %ax
+ movw %ax, %es
+ movw %si, %di
+
+ rep
+ movsl
+
+ ljmp $(CODE_ADDR >> 4), $(real_code_2 - start)
+
+real_code_2:
+
+ pushw %es
+ popw %ds
+
+ movl (ramdisk_image - start), %esi
+ or %esi, %esi
+ jnz 1f
+ movl (code32_start - start), %esi
+1:
+
+ movl $0x200, %ecx
+ addl %ecx, %esi
+ movl $DATA_ADDR, %edi
+
+ call move_memory
+
+ movsbl %dh, %eax
+ movl %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_DOS_PART)
+
+ movsbl (reg_edx + 2 - start), %eax
+ movl %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_INSTALL_BSD_PART)
+
+ movl %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_COMPRESSED_SIZE), %ecx
+ addl $(GRUB_KERNEL_MACHINE_RAW_SIZE - 0x200), %ecx
+
+ call move_memory
+
+ popl %edi
+ popl %esi
+
+ ljmp $(DATA_ADDR >> 4), $0
+
+// Parameters:
+// esi: source address
+// edi: target address
+// ecx: number of bytes
+move_memory:
+ incl %ecx
+ andb $0xFE, %cl
+ pushw %dx
+1:
+ pushl %esi
+ pushl %edi
+ pushl %ecx
+ cmpl $BLCK_LENG, %ecx
+ jbe 2f
+ movl $BLCK_LENG, %ecx
+2:
+ pushl %ecx
+
+ movl %esi, %eax
+ movw %si, (gdt_src1 - start)
+ shrl $16, %eax
+ movb %al, (gdt_src1 + 2 - start)
+ movb %ah, (gdt_src2 - start)
+
+ movl %edi, %eax
+ movw %di, (gdt_dst1 - start)
+ shrl $16, %eax
+ movb %al, (gdt_dst1 + 2 - start)
+ movb %ah, (gdt_dst2 - start)
+
+ movw $(gdt - start), %si
+ movb $0x87, %ah
+ shrw $1, %cx
+
+ int $0x15
+
+ popl %eax
+ popl %ecx
+ popl %edi
+ popl %esi
+
+ jnc 2f
+ movw $(err_int15_msg - start), %si
+ jmp fail
+
+2:
+
+ leal (%esi, %eax), %esi
+ leal (%edi, %eax), %edi
+ subl %eax, %ecx
+ jnz 1b
+
+
+ popw %dx
+ ret
+
+// Parameters:
+// si: message
+fail:
+ movb $0x0e, %ah
+ xorw %bx, %bx
+1:
+ lodsb (%si), %al
+ int $0x10
+ cmpb $0, %al
+ jne 1b
+1: jmp 1b
+
+err_int15_msg:
+ .ascii "move memory fails\0"
+
+ . = (. & (~0x1FF)) + 0x1FF
+
+ .byte 0
+
+code_end:
Bean
2007-12-13 02:06:31 UTC
Permalink
On second thoughts,the original patch is better, because lnxboot.img
works with core.img, which depends on boot.img, kernel.img and
grub-mkimage that exist only in i386-pc.
--
Bean
Robert Millan
2007-12-15 10:43:08 UTC
Permalink
Post by Bean
On second thoughts,the original patch is better, because lnxboot.img
works with core.img, which depends on boot.img, kernel.img and
grub-mkimage that exist only in i386-pc.
Ok, just checked that in.
--
Robert Millan

<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call, if you are unable to speak?
(as seen on /.)
Loading...