Skip to content

Commit

Permalink
Supported Multi-line initrd
Browse files Browse the repository at this point in the history
  • Loading branch information
chenall committed Dec 23, 2019
1 parent a009d1a commit dc5f13b
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 11 deletions.
1 change: 1 addition & 0 deletions ChangeLog_GRUB4DOS.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
2019-12-23 (chenall) Supported Multi-line initrd.
2015-01-10 New Batch script debugging features.
2014-12-15 (tinybit) get rid of endless loop due to wrong usage of pxe detect.
2014-12-01 add new filesystem `ipxe`,support for access file with iPXE;
Expand Down
3 changes: 3 additions & 0 deletions ChangeLog_chenall.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
更新说明:
2019-12-23(chenall)
1. 支持多行initrd.

2019-12-20(yaya)
1. 改进 setmenu 字符串功能,增加索引和菜单区域内居中。字符串可以使用背景色。
setmenu --string[=iINDEX]=[X|s|m]=[-]Y=COLOR="STRING"
Expand Down
45 changes: 34 additions & 11 deletions stage2/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,7 @@ load_module (char *module, char *arg)
}

struct linux_kernel_header *linux_header;
unsigned long initrd_drver_block;
void cpio_set_field(char *field,unsigned long value);

void cpio_set_field(char *field,unsigned long value)
Expand All @@ -976,6 +977,7 @@ load_initrd (char *initrd)
unsigned long long tmp;
unsigned long long top_addr;
char *arg = initrd;
char *name = initrd;

linux_header = (struct linux_kernel_header *) (cur_addr - LINUX_SETUP_MOVE_SIZE);
tmp = ((linux_header->header == LINUX_MAGIC_SIGNATURE && linux_header->version >= 0x0203)
Expand All @@ -988,6 +990,7 @@ load_initrd (char *initrd)

if (moveto > 0x100000000ULL)
moveto = 0x100000000ULL;

top_addr = moveto;

/* XXX: Linux 2.3.xx has a bug in the memory range check, so avoid
Expand All @@ -1001,12 +1004,17 @@ load_initrd (char *initrd)

moveto &= 0xfffff000;

if (debug > 2)
printf("linux_header->ramdisk_image: 0x%x,0x%x\ninitrd_start_sector: %lx,top_addr: %lx\n",linux_header->ramdisk_image,linux_header->ramdisk_size,initrd_start_sector,top_addr);

next_file:

if (*initrd == '@')
{
moveto -= 0x200;
initrd = skip_to (1, initrd);
name = skip_to(1,initrd);
moveto -= name - initrd - 1 + sizeof(struct cpio_header);
moveto &= ~(CPIO_ALIGN - 1);
initrd = name;
}

if (! grub_open (initrd))
Expand Down Expand Up @@ -1040,11 +1048,23 @@ load_initrd (char *initrd)
char map_tmp[64];
grub_u32_t cpio_hdr_sz;
grub_u32_t cpio_img_sz;

tmp = top_addr - moveto;
tmp += 0x1FF;

tmp >>= 9; /* sectors needed */
sprintf (map_tmp, "--mem=-%d (md)0x800+8 (0x22)", (unsigned long)tmp); // INITRD_DRIVE
if (linux_header->ramdisk_size)
{
linux_header->ramdisk_size += 0xFFF;
linux_header->ramdisk_size &= 0xFFFFF000;
tmp += initrd_drver_block;
sprintf (map_tmp, "--mem=-%d (md)0x%x+0x%x (0x22)", (unsigned long)tmp,linux_header->ramdisk_image>>9,linux_header->ramdisk_size>>9); // INITRD_DRIVE
map_func ("(0x22) (0x22)", 0/*flags*/);
} else {
sprintf (map_tmp, "--mem=-%d (md)0x800+8 (0x22)", (unsigned long)tmp); // INITRD_DRIVE
}

initrd_drver_block = tmp;
if (debug > 1)
{
printf ("Create INITRD_DRIVE:\tmap %s\n", map_tmp);
Expand All @@ -1068,15 +1088,16 @@ load_initrd (char *initrd)
goto fail;
}
top_addr = moveto = initrd_start_sector << 9;
memset ((char *)(unsigned long)top_addr, 0, tmp << 9);
moveto += linux_header->ramdisk_size;
memset ((char *)(unsigned long)moveto, 0, (tmp << 9)-linux_header->ramdisk_size);
initrd = arg;
len = 0;
len = linux_header->ramdisk_size;

next_file1:

if (*initrd == '@')
{
char *name = initrd + 1;
name = initrd + 1;
initrd = skip_to (SKIP_WITH_TERMINATE |1, initrd);
struct cpio_header *cpio = (struct cpio_header *)(grub_u32_t)moveto;
grub_u32_t name_len = grub_strlen(name) + 1;
Expand All @@ -1088,7 +1109,7 @@ load_initrd (char *initrd)
cpio_set_field (cpio->c_filesize, filemax);
cpio_set_field (cpio->c_namesize, name_len);
memcpy((void*)(cpio+1),name,name_len);
cpio_hdr_sz = (sizeof(struct cpio_header) + 3 + name_len) & ~3;
cpio_hdr_sz = cpio_image_align (sizeof(struct cpio_header) + name_len);
}
else
{
Expand All @@ -1112,17 +1133,19 @@ load_initrd (char *initrd)
goto fail;
}

cpio_img_sz = (tmp + cpio_hdr_sz + 0xFFF) & ~0xFFF;
moveto += cpio_img_sz;
cpio_img_sz = tmp + cpio_hdr_sz;
initrd = arg;

if (*initrd)
{
cpio_img_sz += 0xFFF;
cpio_img_sz &= 0xFFFFF000;
moveto += cpio_img_sz;
len += cpio_img_sz;
goto next_file1;
}

len += tmp + cpio_hdr_sz;
len += cpio_img_sz;

unset_int13_handler (0); /* unhook it */
set_int13_handler (bios_drive_map); /* hook it */
Expand All @@ -1135,7 +1158,7 @@ load_initrd (char *initrd)
/* FIXME: Should check if the kernel supports INITRD. */
linux_header->ramdisk_image = RAW_ADDR (top_addr);
linux_header->ramdisk_size = len;

fail:

return ! errnum;
Expand Down

1 comment on commit dc5f13b

@steve6375
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setmenu --string ... "date&time=hh:mm" not working.

Please sign in to comment.