Skip to content

Commit

Permalink
supported initrdfs.
Browse files Browse the repository at this point in the history
1. 支持读写initrdfs(cpio new format)内部文件.

   例子,访问initrd.gz文件里面的文件内容(可以查看修改哦)
   也可以利用这个来动态修改initrd的启动脚本实现一些特殊功能,当然了目前还是不能改变文件大小.
   map /inirtd.gz (rd)
   ls (rd)/

2. initrd 多个文件时可以生成cpio new格式.
   initrd @name=FILE @name1=FILE1

   如下例子可以通过[WIMBOOT](http://ipxe.org/wimboot)启动WIM文件

   kernel /wimboot
   initrd @bcd=/boot/bcd @boot.sdi=/boot/boot.sdi @BOOTMGR=/boot/bootmgr @boot.wim=/boot/boot.wim
  • Loading branch information
chenall committed Nov 10, 2014
1 parent 5fd6a92 commit 3d23237
Show file tree
Hide file tree
Showing 13 changed files with 395 additions and 57 deletions.
4 changes: 2 additions & 2 deletions ChangeLog_GRUB4DOS.txt
@@ -1,5 +1,5 @@
2014-11-03 (tinybit) mask off non-booting floppy drives in order to gain more
stability.
2014-11-10 supported initrdfs.
2014-11-03 (tinybit) mask off non-booting floppy drives in order to gain more stability.
2014-11-02 (tinybit) fix offset nestification problem for virtual drives built on another in-situ virtual drive.
2014-10-25 disabled warning and errinfo message redirect.
2014-10-17 PXE Boot supported proxyDHCP and gateway.
Expand Down
11 changes: 11 additions & 0 deletions configure
Expand Up @@ -764,6 +764,7 @@ enable_jfs
enable_xfs
enable_iso9660
enable_pxe
enable_initrdfs
enable_fb
enable_gunzip
enable_md5_password
Expand Down Expand Up @@ -6476,6 +6477,16 @@ if test x"$enable_pxe" != xno; then
FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_PXE=1"
fi

# Check whether --enable-initrdfs was given.
if test "${enable_initrdfs+set}" = set; then :
enableval=$enable_initrdfs;
fi


if test x"$enable_initrdfs" != xno; then
FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_INITRD=1"
fi

# Check whether --enable-fb was given.
if test "${enable_fb+set}" = set; then :
enableval=$enable_fb;
Expand Down
7 changes: 7 additions & 0 deletions configure.ac
Expand Up @@ -343,6 +343,13 @@ if test x"$enable_pxe" != xno; then
FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_PXE=1"
fi

AC_ARG_ENABLE(initrdfs,
[ --disable-initrdfs disable initrdfs support in Stage 2])

if test x"$enable_initrdfs" != xno; then
FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_INITRD=1"
fi

AC_ARG_ENABLE(fb,
[ --disable-fb disable FB support in Stage 2])

Expand Down
4 changes: 2 additions & 2 deletions stage2/Makefile.am
Expand Up @@ -7,7 +7,7 @@ noinst_SCRIPTS = $(TESTS)
noinst_HEADERS = fat.h filesys.h freebsd.h hercules.h \
iso9660.h jfs.h mb_header.h mb_info.h md5.h \
pc_slice.h serial.h shared.h term.h \
terminfo.h tparm.h ufs2.h vstafs.h xfs.h pxe.h graphics.h
terminfo.h tparm.h ufs2.h vstafs.h xfs.h pxe.h graphics.h fsys_initrd.h cpio.h
EXTRA_DIST = $(noinst_SCRIPTS)

# Stage 2 and Stage 1.5's.
Expand Down Expand Up @@ -57,7 +57,7 @@ STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
pre_stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c char_io.c \
cmdline.c common.c console.c dec_lzma.c disk_io.c fsys_ext2fs.c \
fsys_fat.c fsys_ntfs.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c fsys_pxe.c fsys_fb.c gunzip.c \
fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c fsys_pxe.c fsys_initrd.c fsys_fb.c gunzip.c \
hercules.c md5.c serial.c stage2.c terminfo.c tparm.c graphics.c
pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
Expand Down
21 changes: 19 additions & 2 deletions stage2/Makefile.in
Expand Up @@ -132,6 +132,7 @@ am_pre_stage2_exec_OBJECTS = pre_stage2_exec-asm.$(OBJEXT) \
pre_stage2_exec-fsys_vstafs.$(OBJEXT) \
pre_stage2_exec-fsys_xfs.$(OBJEXT) \
pre_stage2_exec-fsys_pxe.$(OBJEXT) \
pre_stage2_exec-fsys_initrd.$(OBJEXT) \
pre_stage2_exec-fsys_fb.$(OBJEXT) \
pre_stage2_exec-gunzip.$(OBJEXT) \
pre_stage2_exec-hercules.$(OBJEXT) \
Expand Down Expand Up @@ -326,7 +327,7 @@ noinst_SCRIPTS = $(TESTS)
noinst_HEADERS = fat.h filesys.h freebsd.h hercules.h \
iso9660.h jfs.h mb_header.h mb_info.h md5.h \
pc_slice.h serial.h shared.h term.h \
terminfo.h tparm.h ufs2.h vstafs.h xfs.h pxe.h graphics.h
terminfo.h tparm.h ufs2.h vstafs.h xfs.h pxe.h fsys_initrd.h graphics.h

EXTRA_DIST = $(noinst_SCRIPTS)

Expand Down Expand Up @@ -354,7 +355,7 @@ STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
pre_stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c char_io.c \
cmdline.c common.c console.c dec_lzma.c disk_io.c fsys_ext2fs.c \
fsys_fat.c fsys_ntfs.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c fsys_pxe.c fsys_fb.c gunzip.c \
fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c fsys_pxe.c fsys_initrd.c fsys_fb.c gunzip.c \
hercules.c md5.c serial.c stage2.c terminfo.c tparm.c graphics.c

pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
Expand Down Expand Up @@ -483,6 +484,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_minix.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_ntfs.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_pxe.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_initrd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_reiserfs.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_ufs2.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_vstafs.Po@am__quote@
Expand Down Expand Up @@ -917,6 +919,21 @@ pre_stage2_exec-fsys_pxe.obj: fsys_pxe.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_pxe.obj `if test -f 'fsys_pxe.c'; then $(CYGPATH_W) 'fsys_pxe.c'; else $(CYGPATH_W) '$(srcdir)/fsys_pxe.c'; fi`

pre_stage2_exec-fsys_initrd.o: fsys_initrd.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_initrd.o -MD -MP -MF $(DEPDIR)/pre_stage2_exec-fsys_initrd.Tpo -c -o pre_stage2_exec-fsys_initrd.o `test -f 'fsys_initrd.c' || echo '$(srcdir)/'`fsys_initrd.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pre_stage2_exec-fsys_initrd.Tpo $(DEPDIR)/pre_stage2_exec-fsys_initrd.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fsys_initrd.c' object='pre_stage2_exec-fsys_initrd.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_initrd.o `test -f 'fsys_initrd.c' || echo '$(srcdir)/'`fsys_initrd.c

pre_stage2_exec-fsys_initrd.obj: fsys_initrd.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_initrd.obj -MD -MP -MF $(DEPDIR)/pre_stage2_exec-fsys_initrd.Tpo -c -o pre_stage2_exec-fsys_initrd.obj `if test -f 'fsys_initrd.c'; then $(CYGPATH_W) 'fsys_initrd.c'; else $(CYGPATH_W) '$(srcdir)/fsys_initrd.c'; fi`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pre_stage2_exec-fsys_initrd.Tpo $(DEPDIR)/pre_stage2_exec-fsys_initrd.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fsys_initrd.c' object='pre_stage2_exec-fsys_initrd.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_initrd.obj `if test -f 'fsys_initrd.c'; then $(CYGPATH_W) 'fsys_initrd.c'; else $(CYGPATH_W) '$(srcdir)/fsys_initrd.c'; fi`


pre_stage2_exec-fsys_fb.o: fsys_fb.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_fb.o -MD -MP -MF $(DEPDIR)/pre_stage2_exec-fsys_fb.Tpo -c -o pre_stage2_exec-fsys_fb.o `test -f 'fsys_fb.c' || echo '$(srcdir)/'`fsys_fb.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pre_stage2_exec-fsys_fb.Tpo $(DEPDIR)/pre_stage2_exec-fsys_fb.Po
Expand Down
81 changes: 54 additions & 27 deletions stage2/boot.c
Expand Up @@ -21,7 +21,7 @@

#include "shared.h"
#include <term.h>

#include "cpio.h"
#include "freebsd.h"

struct exec
Expand Down Expand Up @@ -952,6 +952,14 @@ load_module (char *module, char *arg)
}

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

void cpio_set_field(char *field,unsigned long value)
{
char buf[9];
sprintf(buf,"%08x",value);
memcpy(field,buf,8);
}

int
load_initrd (char *initrd)
Expand All @@ -961,12 +969,8 @@ load_initrd (char *initrd)
unsigned long long tmp;
unsigned long long top_addr;
char *arg = initrd;
#ifndef NO_DECOMPRESSION
int no_decompression_bak = no_decompression;
#endif

linux_header = (struct linux_kernel_header *) (cur_addr - LINUX_SETUP_MOVE_SIZE);

tmp = ((linux_header->header == LINUX_MAGIC_SIGNATURE && linux_header->version >= 0x0203)
? linux_header->initrd_addr_max : LINUX_INITRD_MAX_ADDRESS);

Expand All @@ -990,14 +994,14 @@ load_initrd (char *initrd)

moveto &= 0xfffff000;

len = 0;

next_file:

#ifndef NO_DECOMPRESSION
no_decompression = 1;
#endif

if (*initrd == '@')
{
moveto -= 0x200;
initrd = skip_to (1, initrd);
}

if (! grub_open (initrd))
goto fail;

Expand All @@ -1020,18 +1024,15 @@ load_initrd (char *initrd)

tmp = filemax;
grub_close ();

initrd = skip_to (0, initrd);

if (*initrd)
{
len += ((tmp + 0xFFF) & 0xfffff000);
goto next_file;
}
len += tmp;

{
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 */
Expand Down Expand Up @@ -1062,15 +1063,38 @@ load_initrd (char *initrd)
top_addr = moveto = initrd_start_sector << 9;
memset ((char *)(unsigned long)top_addr, 0, tmp << 9);
initrd = arg;
len = 0;

next_file1:
#ifndef NO_DECOMPRESSION
no_decompression = 1;
#endif

grub_open (initrd);
tmp = grub_read (RAW_ADDR (moveto), -1ULL, 0xedde0d90);
if (*initrd == '@')
{
char *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);
grub_open (initrd);
memset(cpio,'0',sizeof(struct cpio_header));
memcpy(cpio->c_magic,CPIO_MAGIC,sizeof(cpio->c_magic));
cpio_set_field (cpio->c_mode, 0100644 );
cpio_set_field (cpio->c_nlink,1);
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;
}
else
{
cpio_hdr_sz = 0;
grub_open (initrd);
}

arg = skip_to (0, initrd);
if (debug) printf("Loading:%.*s\n",arg-initrd,initrd);

tmp = grub_read (RAW_ADDR (moveto + cpio_hdr_sz), -1ULL, GRUB_READ);
grub_close ();

if (tmp != filemax)
{
//sprintf (map_tmp, "(0x22) (0x22)"); // INITRD_DRIVE
Expand All @@ -1080,11 +1104,18 @@ load_initrd (char *initrd)
errnum = ERR_READ;
goto fail;
}
moveto += ((tmp + 0xFFF) & 0xfffff000);
initrd = skip_to (0, initrd);

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

if (*initrd)
{
len += cpio_img_sz;
goto next_file1;
}

len += tmp + cpio_hdr_sz;

unset_int13_handler (0); /* unhook it */
set_int13_handler (bios_drive_map); /* hook it */
Expand All @@ -1100,10 +1131,6 @@ load_initrd (char *initrd)

fail:

#ifndef NO_DECOMPRESSION
no_decompression = no_decompression_bak;
#endif

return ! errnum;
}

Expand Down
23 changes: 4 additions & 19 deletions stage2/builtins.c
Expand Up @@ -7292,8 +7292,8 @@ static struct builtin builtin_initrd =
{
"initrd",
initrd_func,
BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_SCRIPT | BUILTIN_HELP_LIST,
"initrd FILE [FILE ...]",
BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_SCRIPT | BUILTIN_HELP_LIST | BUILTIN_NO_DECOMPRESSION,
"initrd [@name=]FILE [@name=][FILE ...]",
"Load an initial ramdisk FILE for a Linux format boot image and set the"
" appropriate parameters in the Linux setup area in memory. For Linux"
" 2.6+ kernels, multiple cpio files can be loaded."
Expand Down Expand Up @@ -10771,29 +10771,14 @@ static struct builtin builtin_module =
static int
modulenounzip_func (char *arg, int flags)
{
int ret;
#ifndef NO_DECOMPRESSION
int no_decompression_bak = no_decompression;
#endif

#ifndef NO_DECOMPRESSION
no_decompression = 1;
#endif

ret = module_func (arg, flags);

#ifndef NO_DECOMPRESSION
no_decompression = no_decompression_bak;
#endif

return ret;
return module_func (arg, flags);
}

static struct builtin builtin_modulenounzip =
{
"modulenounzip",
modulenounzip_func,
BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_SCRIPT | BUILTIN_HELP_LIST,
BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_SCRIPT | BUILTIN_HELP_LIST | BUILTIN_NO_DECOMPRESSION,
"modulenounzip FILE [ARG ...]",
"The same as `module', except that automatic decompression is"
" disabled."
Expand Down
7 changes: 3 additions & 4 deletions stage2/char_io.c
Expand Up @@ -252,7 +252,6 @@ grub_putstr (const char *str)
//}
#endif

unsigned char *putchar_hook_back;
int
grub_sprintf (char *buffer, const char *format, ...)
{
Expand All @@ -272,16 +271,16 @@ grub_sprintf (char *buffer, const char *format, ...)
unsigned int length;
int align;
unsigned int accuracy;
unsigned char *putchar_hook_back=NULL;
int stdout = 1;
if (buffer == (char*)1 || buffer == (char*)2)
{
if (debug < 2 && buffer == (char*)1)// show nothing when debug < 2 for warning message
return 1;

stdout = 0;
putchar_hook_back = set_putchar_hook(NULL);
bp=NULL;//reset buffer and bp to NULL
buffer=NULL;
putchar_hook_back = set_putchar_hook((grub_u8_t*)0);
bp=buffer=NULL;//reset buffer and bp to NULL
}
//dataptr++;
//dataptr++;
Expand Down
35 changes: 35 additions & 0 deletions stage2/cpio.h
@@ -0,0 +1,35 @@
#ifndef _CPIO_H
#define _CPIO_H

/** A CPIO archive header
*
* All field are hexadecimal ASCII numbers padded with '0' on the
* left to the full width of the field.
*/
struct cpio_header {
char c_magic[6]; /** The string "070701" or "070702" */
char c_ino[8]; /** File inode number */
char c_mode[8]; /** File mode and permissions */
char c_uid[8]; /** File uid */
char c_gid[8]; /** File gid */
char c_nlink[8]; /** Number of links */
char c_mtime[8]; /** Modification time */
char c_filesize[8]; /** Size of data field */
char c_maj[8]; /** Major part of file device number */
char c_min[8]; /** Minor part of file device number */
char c_rmaj[8]; /** Major part of device node reference */
char c_rmin[8]; /** Minor part of device node reference */
char c_namesize[8]; /** Length of filename, including final NUL */
char c_chksum[8]; /** Checksum of data field if c_magic is 070702, othersize zero */
} __attribute__ (( packed ));

/** CPIO magic */
#define CPIO_MAGIC "070701"
#define CPIO_MODE_DIR 0040000
#define CPIO_ALIGN 4
static inline grub_u32_t cpio_image_align( grub_u32_t len )
{
return (len + (CPIO_ALIGN - 1)) & ~(CPIO_ALIGN - 1);
}

#endif /* _CPIO_H */
3 changes: 3 additions & 0 deletions stage2/disk_io.c
Expand Up @@ -168,6 +168,9 @@ struct fsys_entry fsys_table[NUM_FSYS + 1] =
on floppies from track 1 to 2, while others only use 1. */
# ifdef FSYS_FFS
{"ffs", ffs_mount, ffs_read, ffs_dir, 0, ffs_embed},
# endif
# ifdef FSYS_INITRD
{"initrdfs", initrdfs_mount, initrdfs_read, initrdfs_dir, 0, 0},
# endif
{0, 0, 0, 0, 0, 0}
};
Expand Down

0 comments on commit 3d23237

Please sign in to comment.