diff options
-rw-r--r-- | mdk-stage1/Makefile | 11 | ||||
-rw-r--r-- | mdk-stage1/mkinitrd_helper/Makefile | 46 | ||||
-rw-r--r-- | mdk-stage1/mkinitrd_helper/mkinitrd_helper.c | 246 |
3 files changed, 303 insertions, 0 deletions
diff --git a/mdk-stage1/Makefile b/mdk-stage1/Makefile index d6135bc8b..95be78f45 100644 --- a/mdk-stage1/Makefile +++ b/mdk-stage1/Makefile @@ -187,6 +187,17 @@ clean: done rm -f *.o .depend *.rdz *.img $(BINS) + +tar-mkinitrd_helper: clean + $(MAKE) -C mkinitrd_helper clean + rm -rf mkinitrd_helper-subdir + mkdir mkinitrd_helper-subdir + cd mkinitrd_helper-subdir ; cp -a ../dietlibc ../insmod-busybox ../mkinitrd_helper ../Makefile.common ../insmod.h ../log.h . ; \ + cp ../Makefile.mkinitrd_helper Makefile + tar cfj mkinitrd_helper.tar.bz2 mkinitrd_helper-subdir --exclude CVS + rm -rf mkinitrd_helper-subdir + + .depend: $(CPP) $(CFLAGS) -DHAVE_CONFIG_H -M $(ALLSRC) > .depend diff --git a/mdk-stage1/mkinitrd_helper/Makefile b/mdk-stage1/mkinitrd_helper/Makefile new file mode 100644 index 000000000..e1397ef60 --- /dev/null +++ b/mdk-stage1/mkinitrd_helper/Makefile @@ -0,0 +1,46 @@ + #****************************************************************************** + # + # Guillaume Cottenceau (gc@mandrakesoft.com) + # + # Copyright 2000 MandrakeSoft + # + # This software may be freely redistributed under the terms of the GNU + # public license. + # + # You should have received a copy of the GNU General Public License + # along with this program; if not, write to the Free Software + # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + # + #***************************************************************************** + +top_dir = .. + +include $(top_dir)/Makefile.common + + +VERSION = 1.0 + +DEFS = -DVERSION=\"$(VERSION)\" + + +MKINITRD_HELPER_SRC = mkinitrd_helper.c +MKINITRD_HELPER_LIBS = ../insmod-busybox/libinsmod-DIET.a + +MKINITRD_HELPER_OBJS = $(subst .c,.o,$(MKINITRD_HELPER_SRC)) + +BIN = mkinitrd_helper + +all: $(BIN) + +clean: + rm -f *.o $(BIN) + +FLAGS = -Wall -Werror -Os -fomit-frame-pointer -c + + +$(MKINITRD_HELPER_OBJS): %.o: %.c + $(CC) $(DEFS) $(DIETLIBC_INCLUDES) -I.. -c $< -o $@ + +mkinitrd_helper: $(MKINITRD_HELPER_OBJS) $(MKINITRD_HELPER_LIBS) $(DIETLIBC_LIBC) + $(CC) $(DIETLIBC_LDFLAGS_STAGE1) -o $@ $^ + $(STRIPCMD) $@ diff --git a/mdk-stage1/mkinitrd_helper/mkinitrd_helper.c b/mdk-stage1/mkinitrd_helper/mkinitrd_helper.c new file mode 100644 index 000000000..5a0ce4a28 --- /dev/null +++ b/mdk-stage1/mkinitrd_helper/mkinitrd_helper.c @@ -0,0 +1,246 @@ +/* + * Guillaume Cottenceau (gc@mandrakesoft.com) + * + * Copyright 2001 MandrakeSoft + * + * This software is covered by the GPL license. + * + * This software may be freely redistributed under the terms of the GNU + * public license. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * This little program replaces usual sash and insmod.static based script + * from mkinitrd (that insmod modules, plus possibly mount a partition and + * losetup a loopback-based / on the partition). + * + * + * On my machine: + * gzipped sash + insmod.static 502491 bytes + * gzipped <this-program> 14243 bytes + * + * There will be room for linux-2.4 and many modules, now. Cool. + * + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <sys/mount.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <signal.h> + +#include "insmod.h" + + +void vlog_message(const char * s, va_list args) +{ + vprintf(s, args); + printf("\n"); +} + +void log_perror(char *msg) +{ + perror(msg); +} + + +static void fatal_error(char *msg) +{ + printf("[] fatal: %s\n[] giving hand to kernel.\n", msg); + exit(-1); +} + +static void parse_parms(const char * parm, char ** parm1, char ** parm2, char ** parm3) +{ + char * ptr; + + ptr = strchr(parm, '\n'); + if (!ptr) + fatal_error("bad config file: no newline after parms"); + + *parm1 = malloc(ptr-parm+1); /* yup, never freed :-) */ + memcpy(*parm1, parm, ptr-parm); + (*parm1)[ptr-parm] = '\0'; + + *parm2 = strchr(*parm1, ' '); + if (!*parm2) + return; + **parm2 = '\0'; + (*parm2)++; + + if (!parm3) + return; + + *parm3 = strchr(*parm2, ' '); + if (!*parm3) + return; + **parm3 = '\0'; + (*parm3)++; +} + + +static void insmod_(const char * parm) +{ + char * mod_name, * options; + + parse_parms(parm, &mod_name, &options, NULL); + +#ifdef DEBUG + printf("insmod %s options %s\n", mod_name, options); +#endif + printf("[] Loading module %s\n", mod_name); + + if (insmod_call(mod_name, options)) + perror("insmod failed"); +} + + +static void mount_(const char * parm) +{ + char * dev, * location, * fs; + unsigned long flags; + char * opts = NULL; + + parse_parms(parm, &dev, &location, &fs); + +#ifdef DEBUG + printf("mounting %s on %s as type %s\n", dev, location, fs); +#endif + printf("[] Mounting device containing loopback root filesystem\n"); + + flags = MS_MGC_VAL; + + if (!strcmp(fs, "vfat")) + opts = "check=relaxed"; + + if (mount(dev, location, fs, flags, opts)) + perror("mount failed"); +} + + +#define LO_NAME_SIZE 64 +#define LO_KEY_SIZE 32 + +struct loop_info +{ + int lo_number; /* ioctl r/o */ + dev_t lo_device; /* ioctl r/o */ + unsigned long lo_inode; /* ioctl r/o */ + dev_t lo_rdevice; /* ioctl r/o */ + int lo_offset; + int lo_encrypt_type; + int lo_encrypt_key_size; /* ioctl w/o */ + int lo_flags; /* ioctl r/o */ + char lo_name[LO_NAME_SIZE]; + unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */ + unsigned long lo_init[2]; + char reserved[4]; +}; + +#define LOOP_SET_FD 0x4C00 +#define LOOP_CLR_FD 0x4C01 +#define LOOP_SET_STATUS 0x4C02 + +static void set_loop_(const char * parm) +{ + struct loop_info loopinfo; + int fd, ffd; + char * device, * file; + + parse_parms(parm, &device, &file, NULL); + +#ifdef DEBUG + printf("set_looping %s with %s\n", device, file); +#endif + printf("[] Setting up loopback file %s\n", file); + + if ((ffd = open(file, O_RDWR)) < 0) { + perror("set_loop, opening file in rw"); + exit(-1); + } + + if ((fd = open(device, O_RDWR)) < 0) { + perror("set_loop, opening loop device in rw"); + close(ffd); + exit(-1); + } + + memset(&loopinfo, 0, sizeof (loopinfo)); + strncpy(loopinfo.lo_name, file, LO_NAME_SIZE); + loopinfo.lo_name[LO_NAME_SIZE - 1] = 0; + loopinfo.lo_offset = 0; + + if (ioctl(fd, LOOP_SET_FD, ffd) < 0) { + close(fd); + close(ffd); + perror("LOOP_SET_FD"); + exit(-1); + } + + if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) { + (void) ioctl (fd, LOOP_CLR_FD, 0); + close(fd); + close(ffd); + perror("LOOP_SET_STATUS"); + exit(-1); + } + + close(fd); + close(ffd); +} + + +static int handle_command(char ** ptr, char * cmd_name, void (*cmd_func)(const char * parm)) +{ + if (!strncmp(*ptr, cmd_name, strlen(cmd_name))) { + *ptr = strchr(*ptr, '\n'); + if (!*ptr) + fatal_error("Bad config file: no newline after command"); + (*ptr)++; + cmd_func(*ptr); + *ptr = strchr(*ptr, '\n'); + if (!*ptr) + exit(0); + (*ptr)++; + return 1; + } + return 0; +} + + +int main(int argc, char **argv) +{ + int fd_conf, i; + char buf[5000]; + char * ptr; + + printf("[] initrd_helper v" VERSION "\n"); + + if ((fd_conf = open("/mkinitrd_helper.conf", O_RDONLY)) < 0) + fatal_error("could not open mkinitrd_helper config file"); + + i = read(fd_conf, buf, sizeof(buf)); + if (i == -1) + fatal_error("could not read mkinitrd_helper config file"); + buf[i] = '\0'; + close(fd_conf); + + ptr = buf; + + while (*ptr) + if (!(handle_command(&ptr, "insmod", insmod_) + + handle_command(&ptr, "mount", mount_) + + handle_command(&ptr, "set_loop", set_loop_))) + fatal_error("unkown command"); + + return 0; +} |