diff --git a/package/base/sysfiles/etc_fstab.txt b/package/base/sysfiles/etc_fstab.txt index 4282e12e0..9576cf0ad 100644 --- a/package/base/sysfiles/etc_fstab.txt +++ b/package/base/sysfiles/etc_fstab.txt @@ -1,6 +1,6 @@ /dev/root / auto defaults 0 1 none /proc proc defaults 0 0 -none /dev devfs defaults 0 0 +#none /dev devfs defaults 0 0 none /dev/pts devpts defaults 0 0 none /dev/shm ramfs defaults 0 0 none /sys sysfs defaults 0 0 diff --git a/package/base/sysfiles/etc_initscript.txt b/package/base/sysfiles/etc_initscript.txt index 4eaf48226..7c50de91e 100644 --- a/package/base/sysfiles/etc_initscript.txt +++ b/package/base/sysfiles/etc_initscript.txt @@ -30,7 +30,7 @@ export PATH # Do the dev filesystem magic # if [ -z "$devtype" ]; then - devtype=devfs + devtype=udev if [ -f /etc/conf/devtype ]; then . /etc/conf/devtype fi diff --git a/package/base/sysfiles/stone_mod_hardware.sh b/package/base/sysfiles/stone_mod_hardware.sh index 6ff6666b6..def497884 100644 --- a/package/base/sysfiles/stone_mod_hardware.sh +++ b/package/base/sysfiles/stone_mod_hardware.sh @@ -102,7 +102,7 @@ set_rtc() { main() { while - devtype=devfs + devtype=udev if [ -f /etc/conf/devtype ]; then . /etc/conf/devtype fi diff --git a/package/base/sysfiles/stone_mod_install.sh b/package/base/sysfiles/stone_mod_install.sh index a81634d6d..3210a69ae 100644 --- a/package/base/sysfiles/stone_mod_install.sh +++ b/package/base/sysfiles/stone_mod_install.sh @@ -189,9 +189,9 @@ This dialog allows you to modify your discs parition layout and to create filesy # protect for the case no discs are present ... if [ -e /dev/discs ] ; then for x in $( cd /dev/discs - ls -l * | grep ' -> ' | cut -f2- -d/ ; ) + ls -l */disc | grep ' -> ' | cut -f4- -d/ ; ) do - disk_add $x + disk_add ${x%/disc} done for x in $( cat /etc/lvmtab 2> /dev/null ) do @@ -210,9 +210,10 @@ This dialog allows you to modify your discs parition layout and to create filesy $STONE packages cat > /mnt/target/tmp/stone_postinst.sh << EOT #!/bin/sh -mount -v -t devfs none /dev +mount -v -t ramfs none /dev mount -v -t proc none /proc mount -v -t sysfs none /sys +/sbin/udevstart . /etc/profile stone setup umount -v /sys diff --git a/target/bootdisk/build_stage1.sh b/target/bootdisk/build_stage1.sh index b33d234ca..21dfe06ae 100644 --- a/target/bootdisk/build_stage1.sh +++ b/target/bootdisk/build_stage1.sh @@ -1,36 +1,43 @@ echo_header "Creating initrd data:" rm -rf $disksdir/initrd -mkdir -p $disksdir/initrd/{dev,proc,sys,tmp,scsi,net,bin} +mkdir -p $disksdir/initrd/{dev,proc,sys,tmp,scsi,net,bin,etc} cd $disksdir/initrd; ln -s bin sbin; ln -s . usr -# -if [ -x ../../../usr/bin/diet ] ; then - export DIETHOME="../../../usr/dietlibc" - LXRCCC="../../../usr/bin/diet $CC"; -elif [ -x /usr/bin/diet ] ; then - echo_status "using host's diet - did the target's dietlibc build fail?" - LXRCCC="/usr/bin/diet $CC"; -else - echo_status "diet not found - using glibc -static - initrd may be too big..." - LXRCCC="$CC -static" -fi -echo_status "Create linuxrc binary." -$LXRCCC -c $base/misc/isomd5sum/md5.c -Wall -o md5.o -$LXRCCC -c $base/misc/isomd5sum/libcheckisomd5.c -Wall -o libcheckisomd5.o -$LXRCCC -c $base/target/$target/linuxrc.c -Wall -I $base/misc/isomd5sum/ \ - -DSTAGE_2_BIG_IMAGE="\"${ROCKCFG_SHORTID}/2nd_stage.tar.gz\"" \ - -DSTAGE_2_SMALL_IMAGE="\"${ROCKCFG_SHORTID}/2nd_stage_small.tar.gz\"" \ - -o linuxrc.o -$LXRCCC linuxrc.o md5.o libcheckisomd5.o -o linuxrc -rm -f linuxrc.o md5.o libcheckisomd5.o -# + +echo_status "Creating some device nodes" +mknod dev/ram0 b 1 0 +mknod dev/null c 1 3 +mknod dev/zero c 1 5 +mknod dev/tty c 5 0 +mknod dev/console c 5 1 + +echo_status "Create checkisomd5 binary" +cd ${base}/misc/isomd5sum +make CC="${CC}" LDFLAGS="-L ${base}/build/${ROCKCFG_ID}/usr/lib -lpopt" +cd - +cp ${base}/misc/isomd5sum/checkisomd5 bin/ +cd - +make clean +cd - + +echo_status "Copying and adjusting linuxrc scipt" +cp ${base}/target/${target}/linuxrc.sh linuxrc +chmod +x linuxrc +sed -i -e "s,^STAGE_2_BIG_IMAGE=\"2nd_stage.tar.gz\"$,STAGE_2_BIG_IMAGE=\"${ROCKCFG_SHORTID}/2nd_stage.tar.gz\"," \ + -e "s,^STAGE_2_SMALL_IMAGE=\"2nd_stage_small.tar.gz\"$,STAGE_2_SMALL_IMAGE=\"${ROCKCFG_SHORTID}/2nd_stage_small.tar.gz\"," \ + linuxrc + echo_status "Copy various helper applications." -cp ../2nd_stage/bin/{tar,gzip} bin/ -cp ../2nd_stage/sbin/{ip,hwscan} bin/ -cp ../2nd_stage/usr/bin/{wget,gawk} bin/ -for x in modprobe.static modprobe.static.old \ - insmod.static insmod.static.old -do +for file in ../2nd_stage/bin/{tar,gzip,bash2,bash,sh,mount,umount,ls,cat,uname,rm,ln,mkdir,rmdir,gawk} \ + ../2nd_stage/sbin/{ip,hwscan,pivot_root,swapon,swapoff,udevstart} \ + ../2nd_stage/usr/bin/{wget,find,expand} \ + ../2nd_stage/usr/sbin/lspci ; do + programs="${programs} ${file#../2nd_stage}" + cp ${file} bin/ +done +cp -r $build_root/etc/udev etc/ + +for x in modprobe.static modprobe.static.old insmod.static insmod.static.old ; do if [ -f ../2nd_stage/sbin/${x/.static/} ]; then rm -f bin/${x/.static/} cp -a ../2nd_stage/sbin/${x/.static/} bin/ @@ -41,7 +48,7 @@ do ln -sf $x bin/${x/.static/} fi done -# + echo_status "Copy scsi and network kernel modules." for x in ../2nd_stage/lib/modules/*/kernel/drivers/{scsi,net}/*.{ko,o} ; do # this test is needed in case there are only .o or only .ko files @@ -51,57 +58,82 @@ for x in ../2nd_stage/lib/modules/*/kernel/drivers/{scsi,net}/*.{ko,o} ; do $STRIP --strip-debug $xx # stripping more breaks the object fi done -# + for x in ../2nd_stage/lib/modules/*/modules.{dep,pcimap,isapnpmap} ; do cp $x ${x#../2nd_stage/} || echo "not found: $x" ; done -# + for x in lib/modules/*/kernel/drivers/{scsi,net}; do ln -s ${x#lib/modules/} lib/modules/ done rm -f lib/modules/[0-9]*/kernel/drivers/scsi/{st,scsi_debug}.{o,ko} rm -f lib/modules/[0-9]*/kernel/drivers/net/{dummy,ppp*}.{o,ko} -# -if [ "$ROCKCFG_BOOTDISK_USEKISS" = 1 ]; then - echo_status "Adding kiss shell for expert use of the initrd image." - cp $build_root/bin/kiss bin/ - #mv linuxrc bin/; ln -s bin/kiss linuxrc - #rm -f lib/modules/[0-9]*/kernel/drivers/net/{dgrx,acenic}.o - #rm -f lib/modules/[0-9]*/kernel/drivers/scsi/{advansys,qla1280}.o -fi + +echo_status "Copying necessary libraries" + +libs="/lib/ld-linux.so.2 /usr/lib/libpopt.so.0" +# libpopt from checkisomd5 which is not in build/* +for x in ${programs} ; do + [ -e ./$x ] || continue + file $x | grep -q ELF || continue + libs="$libs `chroot ${base}/build/${ROCKCFG_ID} ldd $x 2>/dev/null | grep -v 'not a dynamic executable' | sed -e 's,^[\t ]*,,g' | cut -f 3 -d' '`" +done + +while [ -n "$libs" ] ; do + oldlibs=$libs + libs="" + for x in $oldlibs ; do + mkdir -p ./${x%/*} + if [ ! -e ./$x ] ; then + cp ${base}/build/${ROCKCFG_ID}/$x ./$x + echo_status "- ${x##*/}" + fi + file $x | grep -q ELF || continue + for y in `chroot ${base}/build/${ROCKCFG_ID} ldd $x 2>/dev/null | grep -v 'not a dynamic executable' | sed -e 's,^[\t ]*,,g' | cut -f 3 -d' '` ; do + [ ! -e "./$y" ] && libs="$libs $y" + done + done +done + +echo_status "Creating links for identical files." +while read ck fn +do + if [ "$oldck" = "$ck" ] ; then + echo_status "\`- Found $fn -> $oldfn." + rm $fn ; ln -s ${oldfn#.} $fn + else + oldck=$ck ; oldfn=$fn + fi +done < <( find -type f | xargs md5sum | sort ) + cd .. echo_header "Creating initrd filesystem image: " ramdisk_size=8192 -#[ $arch = x86 ] && ramdisk_size=4096 echo_status "Creating temporary files." tmpdir=initrd_$$.dir; mkdir -p $disksdir/$tmpdir; cd $disksdir dd if=/dev/zero of=initrd.img bs=1024 count=$ramdisk_size &> /dev/null -tmpdev="" -for x in /dev/loop/* /dev/loop[0-9] ; do - if losetup $x initrd.img 2> /dev/null ; then - tmpdev=$x ; break - fi -done +tmpdev="`losetup -f`" if [ -z "$tmpdev" ] ; then echo_error "No free loopback device found!" rm -f $tmpfile ; rmdir $tmpdir; exit 1 fi echo_status "Using loopback device $tmpdev." -# +losetup "$tmpdev" initrd.img + echo_status "Writing initrd image file." -mke2fs -m 0 -N 180 -q $tmpdev &> /dev/null +mke2fs -m 0 -N 360 -q $tmpdev &> /dev/null mount -t ext2 $tmpdev $tmpdir rmdir $tmpdir/lost+found/ cp -a initrd/* $tmpdir umount $tmpdir -# + echo_status "Compressing initrd image file." gzip -9 initrd.img mv initrd{.img,}.gz -# + echo_status "Removing temporary files." losetup -d $tmpdev rm -rf $tmpdir diff --git a/target/bootdisk/config.in b/target/bootdisk/config.in index 5c0bdbd82..00ddf3cac 100644 --- a/target/bootdisk/config.in +++ b/target/bootdisk/config.in @@ -20,8 +20,6 @@ # # --- ROCK-COPYRIGHT-NOTE-END --- -bool 'Include the kiss shell into the initrd' ROCKCFG_BOOTDISK_USEKISS 1 - pkgfilter sed ' # Select some packages explicitely (base) @@ -43,7 +41,7 @@ pkgfilter sed ' / mdadm / { p; d; }; / ntfsprogs / { P; d; }; / linux / { p; d; }; / ddrescue / { p; d; }; / iproute2 / { p; d; }; / wget / { p; d; }; -/ kiss / { p; d; }; +/ kiss / { p; d; }; / udev / { p; d; }; # Select some packages explicitely (architectures) @@ -83,9 +81,9 @@ ROCKCFGSET_DIETLIBC_bzip2=1 ROCKCFGSET_DIETLIBC_wget=1 ROCKCFGSET_DIETLIBC_gawk=1 ROCKCFGSET_DIETLIBC_iproute2=1 +ROCKCFGSET_DIETLIBC_udev=1 ROCKCFGSET_DIETWANT_SYSENTER=0 -ROCKCFGSET_PKG_TERMCAP_USEIT=1 ROCKCFGSET_PKG_GCC2_NO_CHILL=1 ROCKCFGSET_PKG_GCC32_NO_JAVA=1 ROCKCFGSET_PKG_GCC33_NO_JAVA=1 diff --git a/target/bootdisk/linuxrc.c b/target/bootdisk/linuxrc.c deleted file mode 100644 index 7996faaf7..000000000 --- a/target/bootdisk/linuxrc.c +++ /dev/null @@ -1,710 +0,0 @@ - -/* - * --- ROCK-COPYRIGHT-NOTE-BEGIN --- - * - * This copyright note is auto-generated by ./scripts/Create-CopyPatch. - * Please add additional copyright information _after_ the line containing - * the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by - * the ./scripts/Create-CopyPatch script. Do not edit this copyright text! - * - * ROCK Linux: rock-src/target/bootdisk/linuxrc.c - * ROCK Linux is Copyright (C) 1998 - 2005 Clifford Wolf - * - * This program 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 2 of the License, or - * (at your option) any later version. A copy of the GNU General Public - * License can be found at Documentation/COPYING. - * - * Many people helped and are helping developing ROCK Linux. Please - * have a look at http://www.rocklinux.org/ and the Documentation/TEAM - * file for details. - * - * --- ROCK-COPYRIGHT-NOTE-END --- - * - * linuxrc.c is Copyright (C) 2003, 2004 Cliford Wolf and Rene Rebe - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "libcheckisomd5.h" - -#ifndef MS_MOVE -# define MS_MOVE 8192 -#endif - -#ifndef STAGE_2_BIG_IMAGE -# define STAGE_2_BIG_IMAGE "2nd_stage.tar.gz" -#endif - -#ifndef STAGE_2_SMALL_IMAGE -# define STAGE_2_SMALL_IMAGE "2nd_stage_small.tar.gz" -#endif - -#ifndef STAGE_2_COMPRESS_ARG -# define STAGE_2_COMPRESS_ARG "--use-compress-program=gzip" -#endif - -/* 640kB, err, 64 MB should be enought for the tmpfs ;-) */ -#define TMPFS_OPTIONS "size=67108864" - -/* It seams like we need this prototype here ... */ -int pivot_root(const char *new_root, const char *put_old); - -int exit_linuxrc=0; - -char mod_loader[50]; -char mod_dir[255]; -char mod_suffix[3]; -int mod_suffix_len=0; - -void mod_load_info(char *mod_loader, char *mod_dir, char *mod_suffix) { - struct utsname uts_name; - - if(uname(&uts_name) < 0) { - perror("unable to perform uname syscall correctly"); - return; - } else if(strcmp(uts_name.sysname, "Linux") != 0) { - printf("Your operating system is not supported ?!\n"); - return; - } - - strcpy(mod_loader, "/sbin/insmod"); - strcpy(mod_dir, "/lib/modules/"); - strcat(mod_dir, uts_name.release); - - /* kernel module suffix for <= 2.4 is .o, .ko if above */ - if(uts_name.release[2] > '4') { - strcpy(mod_suffix, ".ko"); - } else { - strcpy(mod_suffix, ".o"); - } - - return; -} - -void doboot() -{ - if ( mkdir("/mnt_root/old_root", 700) ) - { perror("Can't create /mnt_root/old_root"); exit_linuxrc=0; } - - if ( access("/mnt_root/linuxrc", R_OK) ) - { printf("Can't find /mnt_root/linuxrc!\n"); exit_linuxrc=0; } - - if ( exit_linuxrc ) { - if ( pivot_root("/mnt_root", "/mnt_root/old_root") ) - { perror("Can't call pivot_root"); exit_linuxrc=0; } - chdir("/"); - - if ( mount("/old_root/dev", "/dev", "", MS_MOVE, NULL) ) - perror("Can't remount /old_root/dev as /dev"); - - if ( mount("/old_root/proc", "/proc", "", MS_MOVE, NULL) ) - perror("Can't remount /old_root/proc as /proc"); - } else { - if ( rmdir("/mnt_root/old_root") ) - perror("Can't remove /mnt_root/old_root"); - - if ( umount("/mnt_root") ) perror("Can't umount /mnt_root"); - if ( rmdir ("/mnt_root") ) perror("Can't remove /mnt_root"); - } -} - -int trymount (const char* source, const char* target) -{ - return mount(source, target, "iso9660", MS_RDONLY, NULL) && - mount(source, target, "ext3", MS_RDONLY, NULL) && - mount(source, target, "ext2", MS_RDONLY, NULL) && - mount(source, target, "minix", MS_RDONLY, NULL) && - mount(source, target, "vfat", MS_RDONLY, NULL); -} - -void trygets(char *s, int len) -{ - s[0]=0; - if (fgets(s, len, stdin) == NULL) { - if (ferror(stdin)) perror("fgets"); - else printf("EOF\n"); - - sleep(1); - execl("/linuxrc", "/linuxrc", NULL); - printf("\nCan't start /linuxrc!! Life sucks.\n\n"); - exit(0); - } - /* guarantee a 0 termination and remove the trailing newline */ - s[len-1]=0; - if (strlen(s) > 0) s[strlen(s)-1]=0; -} - -void trywait(pid) -{ - if (pid < 0) perror("fork"); - else waitpid(pid, NULL, 0); -} - -#define tryexeclp(file, arg, ...) ( { \ - int pid; \ -\ - if ( (pid = fork()) == 0 ) { \ - execlp(file, arg, __VA_ARGS__); \ - perror(file); \ - exit(1); \ - } \ -\ - trywait(pid); \ -} ) - -void httpload() -{ - int fd[2]; - char baseurl[200]; - char filename[100]; - char url[500]; - int pid_wget, pid_tar; - - printf("Enter base URL (e.g. http://1.2.3.4/rock): "); - fflush(stdout); - - trygets(baseurl, 200); - if (baseurl[0] == 0) return; - - printf("Select a stage 2 image file:\n\n" - " 1. %s\n 2. %s\n\n" - "Enter number or image file name (default=1): ", - STAGE_2_BIG_IMAGE, STAGE_2_SMALL_IMAGE); - - trygets(filename, 100); - if (filename[0] == 0) strcpy(filename, STAGE_2_BIG_IMAGE); - else if (!strcmp(filename, "1")) strcpy(filename, STAGE_2_BIG_IMAGE); - else if (!strcmp(filename, "2")) strcpy(filename, STAGE_2_SMALL_IMAGE); - - exit_linuxrc=1; - snprintf(url, 500, "%s/%s", baseurl, filename); - - printf("[ %s ]\n", url); - setenv("ROCK_INSTALL_SOURCE_URL", baseurl, 1); - - exit_linuxrc=1; - if ( mkdir("/mnt_root", 700) ) - { perror("Can't create /mnt_root"); exit_linuxrc=0; } - - if ( mount("none", "/mnt_root", "tmpfs", 0, TMPFS_OPTIONS) ) - { perror("Can't mount /mnt_root"); exit_linuxrc=0; } - - if ( pipe(fd) < 0 ) - { perror("Can't create pipe"); exit_linuxrc=0; } - - if ( (pid_wget = fork()) == 0 ) { - dup2(fd[1],1); close(fd[0]); close(fd[1]); - execlp("wget", "wget", "-O", "-", url, NULL); - perror("wget"); - _exit(1); - } - - if ( (pid_tar = fork()) == 0 ) { - dup2(fd[0],0); close(fd[0]); close(fd[1]); - execlp("tar", "tar", STAGE_2_COMPRESS_ARG, - "-C", "/mnt_root", "-xf", "-", NULL); - perror("tar"); - _exit(1); - } - - close(fd[0]); close(fd[1]); - trywait(pid_wget); trywait(pid_tar); - printf("finished ... now booting 2nd stage\n"); - doboot(); -} - -/* check wether a file is a directory */ -int is_dir(const struct dirent *entry) { - struct stat tmpstat; - stat(entry->d_name, &tmpstat); - return S_ISDIR(tmpstat.st_mode); -} - -/* this is used in the module loading shell for sorting dirs before files */ -int dirs_first_sort(const struct dirent **a, const struct dirent **b) { - if(is_dir(*a)) { - if(is_dir(*b)) return 0; - else return 1; - } else if(is_dir(*b)) { - return -1; - } else return 0; -} - -/* this is used in the modules loading shell to filter out kernel objects */ -int module_filter(const struct dirent *entry) { - if(is_dir(entry)) { - if(!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) return 0; - else return 1; - } else if (!strcmp(entry->d_name+(strlen(entry->d_name) - mod_suffix_len), mod_suffix)) return 1; - return 0; -} - -/* this starts the module loading shell */ -void load_modules(char* directory){ - struct dirent **namelist; - int cnt, n, len, needmodhdr = 1, needdirhdr = 1; - int loader_res=0; - char filename[256], input[256]; - char *execargs[100]; - - printf("module loading shell\n\n"); - printf("you can navigate through the filestem with 'cd'. for loading a module\n"); - printf("simply enter the shown name, to exit press enter on a blank line.\n\n"); - - while(1) { - if(chdir(directory)) { - perror("chdir"); - } - - n = scandir(".", &namelist, module_filter, dirs_first_sort); - if (n < 0) { - perror("scandir"); - } - getcwd(directory, 255); - - while(n--) { - strcpy(filename, namelist[n]->d_name); - len = strlen(filename); - - if(is_dir(namelist[n])) { - /* first visit to this function, show header */ - if(needdirhdr == 1) { - printf("directories:\n "); - needdirhdr = 0; cnt = 1; - } - printf("[%-15s]",filename); - if(cnt % 4 == 0) printf("\n "); - cnt++; - } else { - /* finished directories, show module header */ - if(needmodhdr == 1) { - if(needdirhdr == 0) printf("\n"); - printf("kernel modules:\n "); - needmodhdr = 0; cnt = 1; - } - filename[len-mod_suffix_len] = 0; - printf("%-15s",filename); - if(cnt % 4 == 0) printf("\n "); - cnt++; - } - - free(namelist[n]); - } - free(namelist); - needmodhdr = 1; needdirhdr = 1; - - printf("\n[%s]> ", directory); - fflush(stdout); - - input[0]=0; fgets(input, 256, stdin); input[255]=0; - if (strlen(input) > 0) input[strlen(input)-1]=0; - if (input[0] == 0) return; - - if(!strncmp(input, "cd ", 3)) { - /* absolute or relative pathname? */ - if(input[3] == '/') { - strcpy(filename, input+3); - } else { - strcpy(filename, directory); - strcat(filename, "/"); - strcat(filename, input+3); - } - free(directory); - directory = (char*)malloc(strlen(filename)+1); - strcpy(directory, filename); - } else { - snprintf(filename, 256, "%s%s", strtok(input, " "), mod_suffix); - execargs[0] = mod_loader; execargs[1] = filename; - for (n=2; (execargs[n] = strtok(NULL, " ")) != NULL; n++) ; - - if ( ! access(filename, R_OK) ) { - if ( fork() == 0 ) { - execvp(execargs[0], execargs); - printf("Can't start %s!\n", execargs[0]); - exit(1); - } - wait(&loader_res); - if(WEXITSTATUS(loader_res) != 0) - printf("error: module loader finished unsuccesfully!\n"); - else - printf("module loader finished succesfully.\n"); - } else { - printf("%s: no such module found! try again... (enter=exit)\n", filename); - } - } - - fflush(stdout); - } - return; -} - -int getdevice(char* devstr, int devlen, int cdroms, int floppies, int autoboot) -{ - char *devicelists[2] = { "/dev/cdroms/cdrom%d", "/dev/floppy/%d" }; - char *devicenames[2] = - { "CD-ROM #%d (IDE/ATAPI or SCSI)", "FDD (Floppy Disk Drive) #%d" }; - char *devn[10], *desc[10]; - char text[100], devicefile[100]; - int nr=0; - int i, tmp_nr; - - if (!cdroms && !floppies) - return -1; - - for (i = 0; i < 2; i++) { - if ( (0 == i) && (!cdroms) ) continue; - if ( (1 == i) && (!floppies) ) continue; - - for (tmp_nr = 0; tmp_nr < 10; ++tmp_nr) { - sprintf(devicefile, devicelists[i], tmp_nr); - sprintf(text, devicenames[i], tmp_nr+1); - - if ( access (devicefile, R_OK) ) break; - - desc[nr] = strdup (text); - devn[nr++] = strdup (devicefile); - } - } - - if (!nr) return -1; - - desc[nr] = devn[nr] = NULL; - - for (nr=0; desc[nr]; nr++) { - printf(" %d. %s\n", nr, desc[nr]); - } - - printf("\nEnter number or device file name (default=0): "); - fflush(stdout); - - if ( !autoboot ) { - trygets(text, 100); - } else { - printf("0\n"); - strcpy(text, "0"); - } - - if (text[0] == 0) - strcpy(text, "0"); - - while (1) { - if ( ! access(text, R_OK) ) { - strncpy(devstr, text, devlen); - break; - } - - if (atoi(text) >= 0 && atoi(text) < nr) { - strncpy(devstr, devn[atoi(text)], devlen); - break; - } - - printf("No such device found. Try again (enter=back): "); - fflush(stdout); - trygets(text, 100); - if (text[0] == 0) return -1; - } - - return 1; -} - -void load_ramdisk_file(int autoboot) -{ - char text[100], devicefile[100]; - char filename[100]; - int pid; - - printf("Select a device for loading the 2nd stage system from: \n\n"); - - if (getdevice(devicefile, 100, 1, 1, autoboot) <= 0) - return; - - printf("Select a stage 2 image file:\n\n" - " 1. %s\n 2. %s\n\n" - "Enter number or image file name (default=1): ", - STAGE_2_BIG_IMAGE, STAGE_2_SMALL_IMAGE); - - if ( !autoboot ) { - trygets(text, 100); - } else { - printf("1\n"); - strcpy(text, "1"); - } - - if (text[0] == 0) strcpy(filename, STAGE_2_BIG_IMAGE); - else if (! strcmp(text, "1")) strcpy(filename, STAGE_2_BIG_IMAGE); - else if (! strcmp(text, "2")) strcpy(filename, STAGE_2_SMALL_IMAGE); - else strcpy(filename, text); - - exit_linuxrc=1; - printf("Using %s:%s.\n", devicefile, filename); - - if ( mkdir("/mnt_source", 700) ) - { perror("Can't create /mnt_source"); exit_linuxrc=0; } - - if ( trymount (devicefile, "/mnt_source") ) - { perror("Can't mount /mnt_source"); exit_linuxrc=0; } - - if ( mkdir("/mnt_root", 700) ) - { perror("Can't create /mnt_root"); exit_linuxrc=0; } - - if ( mount("none", "/mnt_root", "tmpfs", 0, TMPFS_OPTIONS) ) - { perror("Can't mount /mnt_root"); exit_linuxrc=0; } - - if ( (pid = fork()) == 0 ) { - printf("Extracting 2nd stage filesystem to ram ...\n"); - snprintf(text, 100, "/mnt_source/%s", filename); - execlp( "tar", "tar", STAGE_2_COMPRESS_ARG, - "-C", "/mnt_root", "-xf", text, NULL); - printf("Can't run tar on %s!\n", filename); - exit(1); - } - trywait(pid); - - if ( umount("/mnt_source") ) - { perror("Can't umount /mnt_source"); exit_linuxrc=0; } - - if ( rmdir("/mnt_source") ) - { perror("Can't remove /mnt_source"); exit_linuxrc=0; } - - setenv("ROCK_INSTALL_SOURCE_DEV", devicefile, 1); - setenv("ROCK_INSTALL_SOURCE_FILE", filename, 1); - doboot(); -} - -void activate_swap() -{ - char text[100]; - - printf("\nEnter file name of swap device: "); - fflush(stdout); - - trygets(text, 100); - if ( text[0] ) { - if ( swapon(text, 0) < 0 ) - perror("Can't activate swap device"); - } -} - -void config_net() -{ - char dv[100]=""; - char ip[100]=""; - char gw[100]=""; - - tryexeclp("ip", "ip", "addr", NULL); - printf("\n"); - - tryexeclp("ip", "ip", "route", NULL); - printf("\n"); - - printf("Enter interface name (eth0): "); - fflush(stdout); - trygets(dv, 100); - if (dv[0] == 0) strcpy(dv, "eth0"); - - printf("Enter ip (192.168.0.254/24): "); - fflush(stdout); - trygets(ip, 100); - if (ip[0] == 0) strcpy(ip, "192.168.0.254/24"); - - tryexeclp("ip", "ip", "addr", "add", ip, "dev", dv, NULL); - tryexeclp("ip", "ip", "link", "set", dv, "up", NULL); - - printf("Enter default gateway (none): "); - fflush(stdout); - trygets(gw, 100); - if (gw[0] != 0) - tryexeclp("ip", "ip", "route", "add", - "default", "via", gw, NULL); - printf("\n"); - - tryexeclp("ip", "ip", "addr", NULL); - printf("\n"); - - tryexeclp("ip", "ip", "route", NULL); -} - -void autoload_modules() -{ - char line[200], cmd[200], module[200]; - int fd[2], rc; - FILE *f; - int pid; - - if (pipe(fd) <0) - { perror("Can't create pipe"); return; } - - if ( (pid = fork()) == 0 ) { - dup2(fd[1],1); close(fd[0]); close(fd[1]); - execlp("gawk", "gawk", "-f", "/bin/hwscan", NULL); - printf("Can't start >>hwscan<< program with gawk!\n"); - exit(1); - } - - close(fd[1]); - f = fdopen(fd[0], "r"); - while ( fgets(line, 200, f) != NULL ) { - if ( sscanf(line, "%s %s", cmd, module) < 2 ) continue; - if ( !strcmp(cmd, "modprobe") || !strcmp(cmd, "insmod") ) { - printf("%s %s\n", cmd, module); - if ( (rc = fork()) == 0 ) { - execlp(cmd, cmd, module, NULL); - perror("Cant run modprobe/insmod"); - exit(1); - } - trywait(rc); - } - } - fclose(f); - trywait(pid); -} - -void exec_sh() -{ - int rc; - - printf ("Quit the shell to return to the stage 1 loader!\n"); - if ( (rc = fork()) == 0 ) { - execl("/bin/kiss", "kiss", "-E", NULL); - perror("kiss"); - _exit(1); - } - trywait(rc); -} - -void checkisomd5() -{ - char devicefile[100]; - - printf("Select a device for checking: \n\n"); - - if (getdevice(devicefile, 100, 1, 0, 0) <= 0) - return; - - mediaCheckFile(devicefile, 0); - - printf("\nPress Return key to continue."); (void)getchar(); -} - -int main() -{ - char text[100]; - int input=1; - - if ( mount("none", "/dev", "devfs", 0, NULL) && errno != EBUSY ) - perror("Can't mount /dev"); - - if ( mount("none", "/proc", "proc", 0, NULL) && errno != EBUSY ) - perror("Can't mount /proc"); - - /* Only print important stuff to console */ - klogctl(8, NULL, 3); - - mod_load_info(mod_loader, mod_dir, mod_suffix); - mod_suffix_len = strlen(mod_suffix); - - autoload_modules(); - if ( getenv("autoboot") ) { - load_ramdisk_file(1); - } - - printf("\n\ - ============================================\n\ - === ROCK Linux 1st stage boot system ===\n\ - ============================================\n\ -\n\ -The ROCK Linux install / rescue system boots up in two stages. You\n\ -are now in the first of this two stages and if everything goes right\n\ -you will not spend much time here. Just load your SCSI and networking\n\ -drivers (if needed) and configure the installation source so the\n\ -2nd stage boot system can be loaded and you can start the installation.\n"); - - while (exit_linuxrc == 0) - { - printf("\n\ - 0. Load 2nd stage system from local device\n\ - 1. Load 2nd stage system from network\n\ - 2. Configure network interfaces (IPv4 only)\n\ - 3. Load kernel modules from this disk\n\ - 4. Load kernel modules from another disk\n\ - 5. Activate already formatted swap device\n\ - 6. Execute a (kiss) shell if present (for experts!)\n\ - 7. Validate a CD/DVD against its embedded checksum\n\ -\n\ -What do you want to do [0-8] (default=0)? "); - fflush(stdout); - - trygets(text, 100); - input=atoi(text); - - switch (input) { - case 0: - load_ramdisk_file(0); - break; - - case 1: - httpload(); - break; - - case 2: - config_net(); - break; - - case 3: - load_modules(mod_dir); - break; - - case 4: - if ( mkdir("/mnt_floppy", 700) ) - perror("Can't create /mnt_floppy"); - - if ( trymount("/dev/floppy/0", "/mnt_floppy") ) - load_modules("/mnt_floppy"); - - if ( umount("/mnt_floppy") ) - perror("Can't umount /mnt_floppy"); - - if ( rmdir("/mnt_floppy") ) - perror("Can't remove /mnt_floppy"); - break; - - case 5: - activate_swap(); - break; - - case 6: - exec_sh(); - break; - - case 7: - checkisomd5(); - break; - - default: - perror ("No such option present!"); - } - } - - sleep(1); - execl("/linuxrc", "/linuxrc", NULL); - printf("\nCan't start /linuxrc!! Life sucks.\n\n"); - return 0; -} - diff --git a/target/bootdisk/linuxrc.sh b/target/bootdisk/linuxrc.sh new file mode 100644 index 000000000..5d1753b9f --- /dev/null +++ b/target/bootdisk/linuxrc.sh @@ -0,0 +1,465 @@ +#!/bin/bash + +STAGE_2_BIG_IMAGE="2nd_stage.tar.gz" +STAGE_2_SMALL_IMAGE="2nd_stage_small.tar.gz" +STAGE_2_COMPRESS_ARG="--use-compress-program=gzip" + +#640kB, err, 64 MB should be enought for the tmpfs ;-) +TMPFS_OPTIONS="size=67108864" + +mod_load_info () { # {{{ + read os host version rest < <( uname -a ) + if [ -z "${os}" ] ; then + echo "Can't run \`uname -a\`" + return + elif [ "${os}" != "Linux" ] ; then + echo "Your operating system is not supported ?!" + return + fi + + mod_loader="/sbin/insmod" + mod_dir="/lib/modules/" + + # kernel module suffix for <= 2.4 is .o, .ko if above + if [ ${version:2:1} -gt 4 ] ; then + mod_suffix=".ko" + mod_suffix_len=3 + else + mod_suffix=".o" + mod_suffix_len=2 + fi +} # }}} +doboot() { # {{{ + if ! mkdir /mnt_root/old_root ; then + echo "Can't create /mnt_root/old_root" + exit_linuxrc=0 + fi + + if [ ! -f /mnt_root/linuxrc ] ; then + echo "Can't find /mnt_root/linuxrc!" + exit_linuxrc=0 + fi + + if [ ${exit_linuxrc} -ne 0 ] ; then + if ! pivot_root "/mnt_root" "/mnt_root/old_root" ; then + echo "Can't call pivot_root" + exit_linuxrc=0 + return + fi + cd / + + if ! mount --move /old_root/dev /dev ; then + echo "Can't remount /old_root/dev as /dev" + fi + + if ! mount --move /old_root/proc /proc ; then + echo "Can't remount /old_root/proc as /proc" + fi + + if ! mount --move /old_root/sys /sys ; then + echo "Can't remount /old_root/sys as /sys" + fi + + if ! umount /old_root/tmp ; then + echo "Can't umount /old_root/tmp" + fi + + else + rmdir /mnt_root/old_root || echo "Can't remove /mnt_root/old_root" + + umount /mnt_root || echo "Can't umount /mnt_root" + rmdir /mnt_root || echo "Can't remove /mnt_root" + fi +} # }}} +trymount() { # {{{ + source=${1} + target=${2} + mount -t iso9600 -o ro ${source} ${target} && return 0 + mount -t ext3 -o ro ${source} ${target} && return 0 + mount -t ext2 -o ro ${source} ${target} && return 0 + mount -t minix -o ro ${source} ${target} && return 0 + mount -t vfat -o ro ${source} ${target} && return 0 + return -1 +} # }}} +httpload() { # {{{ + echo -n "Enter base URL (e.g. http://1.2.3.4/rock): " + + read baseurl + [ -z "${baseurl}" ] && return + + cat < " + read cmd par + if [ "${cmd}" == "cd" ] ; then + cd ${par} + elif [ -f "${cmd}${mod_suffix}" ] ; then + insmod ${PWD%/}/${cmd}${mod_suffix} ${par} + elif [ -z "${cmd}" ] ; then + break + else + echo "No such module: ${cmd}" + fi + done + return +} # }}} +getdevice () { # {{{ + cdroms="${1}" + floppies="${2}" + autoboot="${3}" + devicelists="/dev/cdroms/* /dev/floppy/*" + + [ "${cdroms}" == "0" -a "${floppies}" == "0" ] && return -1 + + devnr=0 + for dev in ${devicelists} ; do + [ -e "${dev}" ] || continue + [[ ${dev} = /dev/cdroms* ]] && [ "${cdroms}" == "0" ] && continue + [[ ${dev} = /dev/floppy* ]] && [ "${floppies}" == "0" ] && continue + + eval "device_${devnr}='${dev}'" + devnr=$((${devnr}+1)) + done + + [ ${devnr} -eq 0 ] && return -1 + + x=0 + floppy=1 + cdrom=1 + while [ ${x} -lt ${devnr} ] ; do + eval "device=\${device_${x}}" + if [[ ${device} = /dev/cdrom* ]] ; then + echo " ${x}. CD-ROM #${cdrom} (IDE/ATAPI or SCSI)" + cdrom=$((${cdrom}+1)) + fi + if [[ ${device} = /dev/flopp* ]] ; then + echo " ${x}. FDD (Floppy Disk Drive) #${floppy}" + floppy=$((${floppy}+1)) + fi + x=$((${x}+1)) + done + + echo -en "\nEnter number or device file name (default=0): " + + if [ ${autoboot} -eq 1 ] ; then + echo "0" + text=0 + else + read text + fi + + [ -z "${text}" ] && text=0 + + while : ; do + if [ -e "${text}" ] ; then + devicefile="${text}" + return 0 + fi + + eval "text=\"\${device_${text}}\"" + if [ -n "${text}" ] ; then + devicefile="${text}" + return 0 + fi + + echo -n "No such device found. Try again (enter=back): " + read text + [ -z "${text}" ] && return -1 + done + + return 1; +} # }}} +load_ramdisk_file() { # {{{ + autoboot=${1} + + echo -en "Select a device for loading the 2nd stage system from: \n\n" + + getdevice 1 1 ${autoboot} || return + + cat << EOF +Select a stage 2 image file: + + 1. ${STAGE_2_BIG_IMAGE} + 2. ${STAGE_2_SMALL_IMAGE} +EOF + echo -n "Enter number or image file name (default=1): " + if [ ${autoboot} -eq 1 ] ; then + echo "1" + text=1 + else + read text + fi + + if [ -z "${text}" ] ; then + filename="${STAGE_2_BIG_IMAGE}" + elif [ "${text}" == "1" ] ; then + filename="${STAGE_2_BIG_IMAGE}" + elif [ "${text}" == "2" ] ; then + filename="${STAGE_2_SMALL_IMAGE}" + else + filename="${text}" + fi + + exit_linuxrc=1 + echo "Using ${devicefile}:${filename}." + + if ! mkdir -p /mnt_source ; then + echo "Can't create /mnt_source" + exit_linuxrc=0 + fi + + if ! mount ${devicefile} "/mnt_source" ; then + echo "Can't mount /mnt_source" + exit_linuxrc=0 + fi + + if ! mkdir -p /mnt_root ; then + echo "Can't create /mnt_root" + exit_linuxrc=0 + fi + + if ! mount -t tmpfs -o ${TMPFS_OPTIONS} none /mnt_root ; then + echo "Can't mount tmpfs on /mnt_root" + exit_linuxrc=0 + fi + + echo "Extracting 2nd stage filesystem to ram ..." + if ! tar ${STAGE_2_COMPRESS_ARG} -C /mnt_root -xf /mnt_source/${filename} ; then + echo "Can't extract /mnt/source/${filename}" + exit_linuxrc=0 + return 1 + fi + + if ! umount "/mnt_source" ; then + echo "Can't umount /mnt_source" + exit_linuxrc=0 + fi + + if ! rmdir "/mnt_source" ; then + echo "Can't remove /mnt_source" + exit_linuxrc=0 + fi + + ROCK_INSTALL_SOURCE_DEV=${devicefile} + ROCK_INSTALL_SOURCE_FILE=${filename} + doboot +} # }}} +activate_swap() { # {{{ + echo + echo -n "Enter file name of swap device: " + + read text + if [ -n "${text}" ] ; then + swapon ${text} + fi +} # }}} +config_net() { # {{{ + ip addr + echo + ip route + echo + + echo -n "Enter interface name (eth0): " + read dv + [ -z "${dv}" ] && dv="eth0" + + echo -n "Enter ip (192.168.0.254/24): " + read ip + [ -z "${ip}" ] && ip="192.168.0.254/24" + + ip addr add ${ip} dev ${dv} + ip link set ${dv} up + + echo -n "Enter default gateway (none): " + read gw + [ -n "${gw}" ] && ip route add default via ${gw} + + ip addr + echo + ip route + echo +} # }}} +autoload_modules () { # {{{ + while read cmd mod rest ; do + [ -n "${rest}" ] && continue + [ -z "${cmd}" ] && continue + if [ "${cmd}" == "modprobe" -o "${cmd}" == "insmod" ] ; then + echo "${cmd} ${mod}" + ${cmd} ${mod} 2>&1 >/dev/null + fi + done < <( /bin/gawk -f /bin/hwscan ) +} # }}} +exec_sh() { # {{{ + echo "Quit the shell to return to the stage 1 loader!" + /bin/sh +} # }}} +checkisomd5() { # {{{ + echo "Select a device for checking: " + + getdevice 1 0 0 || return + echo "Running check..." + + /bin/checkisomd5 ${devicefile} + + echo "done" + echo "Press Return key to continue." + read +} # }}} + +input=1 +exit_linuxrc=0 +[ -z "${autoboot}" ] && autoboot=0 +mount -t ramfs none /dev || echo "Can't mount a ramfs on /dev" +mount -t sysfs none /sys || echo "Can't mount sysfs on /sys" +mount -t proc none /proc || echo "Can't mount /proc" +mount -t tmpfs -o ${TMPFS_OPTIONS} none /tmp || echo "Can't mount /tmpfs" +udevstart +cd /dev +rm -rf fd +ln -s /proc/self/fd +cd - +mod_load_info + +autoload_modules +if [ ${autoboot} -eq 1 ] ; then + load_ramdisk_file 1 +fi +autoboot=0 +cat << EOF + ============================================ + === ROCK Linux 1st stage boot system === + ============================================ + +The ROCK Linux install / rescue system boots up in two stages. You +are now in the first of this two stages and if everything goes right +you will not spend much time here. Just load your SCSI and networking +drivers (if needed) and configure the installation source so the +2nd stage boot system can be loaded and you can start the installation. +EOF +while [ ${exit_linuxrc} -eq 0 ] ; do + cat < /etc/mtab -mount -t sysfs none /sys freeramdisk /dev/rd/* 2> /dev/null mkdir -p /lib/modules/$( uname -r ) echo -n >> /lib/modules/$( uname -r )/modules.dep +udevd --daemon cd /dev ; rm -f fd ln -sf /proc/kcore core ln -sf /proc/self/fd fd @@ -54,7 +54,7 @@ if [ -z "$ttydevs" ]; then ttydevs="vc/1 vc/2 vc/3 vc/4 vc/5 vc/6" fi -if [[ "$ttydevs" = tts/* ]] ; then +if [[ "$ttydevs" = *tts/* ]] ; then echo -n "Connection speed in Baud (default: 9600): " ; read baud [ -z "$baud" ] && baud=9600 else