On Jan 22, 2008 9:57 PM, Robert Millan <[EMAIL PROTECTED]> wrote: > On Tue, Jan 22, 2008 at 12:25:49PM +0800, Bean wrote: > > > but, what is the advantage in that? Is there any use case in which the > > > first > > > option is not good but the second is? > > > > Some advantages of using external initrd: > > > > 1, Resolve size limit for core.img > > core.img can't be too large, otherwise it doesn't fit inside > > conventional memory. external initrd doesn't have this problem. > > Ok. > > > 2. Easy to modify > > users may not know how to create core.img, but modifying files in a, > > say, tar or cpio archive is very easy. They can do simple tasks like > > replacing splash image without too much knowledge of grub2. > > > > 3. Multiple configuration > > We can use the same core.img, but different initrd to start grub2 with > > different configuration. > > I don't think these two make a big difference, but well. > > No objection from me, then.
this is the patch, please try it. * boot/i386/pc/lnxboot.S (data_start) : Simplify code. (real_code_2) : Set grub_memdisk_image_addr using initrd address. * include/grub/i386/pc/boot.h : New constant GRUB_BOOT_MACHINE_LNX_LENG_OFFSET. * include/grub/i386/pc/kernel.h : New constant GRUB_KENRL_MACHINE_MEMDISK_IMAGE_ADDR. New variable grub_memdisk_image_addr. * kern/i386/pc/init.c (grub_arch_memdisk_addr) : Use grub_memdisk_image_addr if it isn't zero. * kern/i386/pc/startup.S : New variable grub_memdisk_image_addr. * util/i386/pc/grub-mkimage.c (generate_image) : Add is_linux parameter. If it's set, use lnxboot.img as header instead of diskboot.img. (options): Add "linux"|'x' option (main): Parse --linux|-x option, and pass its value to generate_image. diff --git a/boot/i386/pc/lnxboot.S b/boot/i386/pc/lnxboot.S index f1a4ded..6503e26 100644 --- a/boot/i386/pc/lnxboot.S +++ b/boot/i386/pc/lnxboot.S @@ -36,22 +36,7 @@ .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) - + xorl %ebp, %ebp jmp linux_next . = data_start + 0x1F1 @@ -76,7 +61,7 @@ boot_flag: start: _start: - jmp linux_code + jmp linux_init .ascii "HdrS" // Header signature .word 0x0203 // Header version number @@ -134,9 +119,10 @@ reg_edx: data_leng: .long 0 -linux_code: +linux_init: movw %cs:(reg_edx - start), %dx + movl %cs:(code32_start - start), %ebp linux_next: @@ -164,9 +150,6 @@ real_code: movw %si, %ss movw $(CODE_ADDR), %sp - pushl %esi - pushl %edi - // Move itself to 0:CODE_ADDR cld @@ -183,17 +166,26 @@ real_code: real_code_2: + xchgl %ebp, %esi + orl %esi, %esi + jnz 1f + movw %ds, %si + shll $4, %esi + addl %ebp, %esi +1: + pushw %es popw %ds - movl (ramdisk_image - start), %esi - or %esi, %esi + movl (data_leng - start), %ecx + or %ecx, %ecx jnz 1f - movl (code32_start - start), %esi + movl (ramdisk_image - start), %esi + movl (ramdisk_size - start), %ecx + addl $0x200, %esi + subl $0x200, %ecx 1: - movl $0x200, %ecx - addl %ecx, %esi movl $DATA_ADDR, %edi call move_memory @@ -204,13 +196,17 @@ real_code_2: 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 + movl (data_leng - start), %eax + or %eax, %eax + jz 1f + movl (ramdisk_size - start), %eax + or %eax, %eax + jz 1f - call move_memory - - popl %edi - popl %esi + movl %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE) + movl (ramdisk_image - start), %eax + movl %eax, %ss:(DATA_ADDR + GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_ADDR) +1: ljmp $(DATA_ADDR >> 4), $0 @@ -261,8 +257,8 @@ move_memory: 2: - leal (%esi, %eax), %esi - leal (%edi, %eax), %edi + addl %eax, %esi + addl %eax, %edi subl %eax, %ecx jnz 1b diff --git a/include/grub/i386/pc/boot.h b/include/grub/i386/pc/boot.h index fcc961b..4cc9a04 100644 --- a/include/grub/i386/pc/boot.h +++ b/include/grub/i386/pc/boot.h @@ -75,4 +75,7 @@ /* The size of a block list used in the kernel startup code. */ #define GRUB_BOOT_MACHINE_LIST_SIZE 12 +/* The offset of variable data_leng in lnxboot.S. */ +#define GRUB_BOOT_MACHINE_LNX_LENG_OFFSET 0x264 + #endif /* ! BOOT_MACHINE_HEADER */ diff --git a/include/grub/i386/pc/kernel.h b/include/grub/i386/pc/kernel.h index ca16df7..f5d8438 100644 --- a/include/grub/i386/pc/kernel.h +++ b/include/grub/i386/pc/kernel.h @@ -37,8 +37,11 @@ /* The offset of GRUB_MEMDISK_IMAGE_SIZE. */ #define GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_SIZE 0x1c +/* The offset of GRUB_MEMDISK_IMAGE_ADDR. */ +#define GRUB_KERNEL_MACHINE_MEMDISK_IMAGE_ADDR 0x20 + /* The offset of GRUB_PREFIX. */ -#define GRUB_KERNEL_MACHINE_PREFIX 0x20 +#define GRUB_KERNEL_MACHINE_PREFIX 0x24 /* End of the data section. */ #define GRUB_KERNEL_MACHINE_DATA_END 0x50 @@ -66,6 +69,9 @@ extern grub_int32_t grub_install_bsd_part; /* The size of memory disk image, if present. */ extern grub_int32_t grub_memdisk_image_size; +/* The address of memory disk image, if present. */ +extern grub_int32_t grub_memdisk_image_addr; + /* The prefix which points to the directory where GRUB modules and its configuration file are located. */ extern char grub_prefix[]; diff --git a/kern/i386/pc/init.c b/kern/i386/pc/init.c index 0cf81d7..af6deda 100644 --- a/kern/i386/pc/init.c +++ b/kern/i386/pc/init.c @@ -253,9 +253,10 @@ grub_arch_modules_addr (void) grub_addr_t grub_arch_memdisk_addr (void) { - return GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + return (grub_memdisk_image_addr) ? grub_memdisk_image_addr : + (GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (grub_kernel_image_size - GRUB_KERNEL_MACHINE_RAW_SIZE) - + grub_total_module_size; + + grub_total_module_size); } /* Return the size of the memdisk image. */ diff --git a/kern/i386/pc/startup.S b/kern/i386/pc/startup.S index e4101a6..5dd2e67 100644 --- a/kern/i386/pc/startup.S +++ b/kern/i386/pc/startup.S @@ -97,6 +97,8 @@ VARIABLE(grub_install_bsd_part) .long 0xFFFFFFFF VARIABLE(grub_memdisk_image_size) .long 0 +VARIABLE(grub_memdisk_image_addr) + .long 0 VARIABLE(grub_prefix) /* to be filled by grub-mkimage */ diff --git a/util/i386/pc/grub-mkimage.c b/util/i386/pc/grub-mkimage.c index 48d6dfc..eee6b34 100644 --- a/util/i386/pc/grub-mkimage.c +++ b/util/i386/pc/grub-mkimage.c @@ -77,7 +77,7 @@ compress_kernel (char *kernel_img, size_t kernel_size, } static void -generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path) +generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *memdisk_path, int is_linux) { grub_addr_t module_addr = 0; char *kernel_img, *boot_img, *core_img; @@ -151,17 +151,25 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[], char *me if (num > 0xffff) grub_util_error ("the core image is too big"); - boot_path = grub_util_get_path (dir, "diskboot.img"); + boot_path = grub_util_get_path (dir, (is_linux) ? "lnxboot.img" : "diskboot.img"); boot_size = grub_util_get_image_size (boot_path); - if (boot_size != GRUB_DISK_SECTOR_SIZE) + if ((! is_linux) && (boot_size != GRUB_DISK_SECTOR_SIZE)) grub_util_error ("diskboot.img is not one sector size"); boot_img = grub_util_read_image (boot_path); - /* i386 is a little endian architecture. */ - *((grub_uint16_t *) (boot_img + GRUB_DISK_SECTOR_SIZE + if (is_linux) + { + *((grub_uint32_t *) (boot_img + GRUB_BOOT_MACHINE_LNX_LENG_OFFSET)) + = grub_cpu_to_le32 (core_size); + } + else + { + /* i386 is a little endian architecture. */ + *((grub_uint16_t *) (boot_img + GRUB_DISK_SECTOR_SIZE - GRUB_BOOT_MACHINE_LIST_SIZE + 8)) - = grub_cpu_to_le16 (num); + = grub_cpu_to_le16 (num); + } grub_util_write_image (boot_img, boot_size, out); free (boot_img); @@ -208,6 +216,7 @@ static struct option options[] = {"prefix", required_argument, 0, 'p'}, {"memdisk", required_argument, 0, 'm'}, {"output", required_argument, 0, 'o'}, + {"linux", no_argument, 0, 'x'}, {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 'V'}, {"verbose", no_argument, 0, 'v'}, @@ -229,6 +238,7 @@ Make a bootable image of GRUB.\n\ -p, --prefix=DIR set grub_prefix directory [default=%s]\n\ -m, --memdisk=FILE embed FILE as a memdisk image\n\ -o, --output=FILE output a generated image to FILE [default=stdout]\n\ + -x, --linux add linux kernel header to output file\n\ -h, --help display this message and exit\n\ -V, --version print version information and exit\n\ -v, --verbose print verbose messages\n\ @@ -247,12 +257,13 @@ main (int argc, char *argv[]) char *prefix = NULL; char *memdisk = NULL; FILE *fp = stdout; + int is_linux = 0; progname = "grub-mkimage"; while (1) { - int c = getopt_long (argc, argv, "d:p:m:o:hVv", options, 0); + int c = getopt_long (argc, argv, "d:p:m:o:xhVv", options, 0); if (c == -1) break; @@ -280,6 +291,10 @@ main (int argc, char *argv[]) memdisk = xstrdup (optarg); break; + case 'x': + is_linux = 1; + break; + case 'h': usage (0); break; @@ -312,7 +327,7 @@ main (int argc, char *argv[]) grub_util_error ("cannot open %s", output); } - generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk); + generate_image (dir ? : GRUB_LIBDIR, prefix ? : DEFAULT_DIRECTORY, fp, argv + optind, memdisk, is_linux); fclose (fp); -- Bean _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org http://lists.gnu.org/mailman/listinfo/grub-devel