Browse Source

Benjamin Schieder:


			
			
				rocklinux
			
			
		
Benjamin Schieder 20 years ago
parent
commit
a51d5eb04f
9 changed files with 558 additions and 772 deletions
  1. +1
    -1
      package/base/sysfiles/etc_fstab.txt
  2. +1
    -1
      package/base/sysfiles/etc_initscript.txt
  3. +1
    -1
      package/base/sysfiles/stone_mod_hardware.sh
  4. +4
    -3
      package/base/sysfiles/stone_mod_install.sh
  5. +82
    -50
      target/bootdisk/build_stage1.sh
  6. +2
    -4
      target/bootdisk/config.in
  7. +0
    -710
      target/bootdisk/linuxrc.c
  8. +465
    -0
      target/bootdisk/linuxrc.sh
  9. +2
    -2
      target/bootdisk/linuxrc2.sh

+ 1
- 1
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

+ 1
- 1
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

+ 1
- 1
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

+ 4
- 3
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

+ 82
- 50
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

+ 2
- 4
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

+ 0
- 710
target/bootdisk/linuxrc.c

@ -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 <sys/mount.h>
#include <sys/swap.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/klog.h>
#include <sys/utsname.h>
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
#include <stdarg.h>
#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;
}

+ 465
- 0
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 <<EOF
Select a stage 2 image file:
0. ${STAGE_2_BIG_IMAGE}
1. ${STAGE_2_SMALL_IMAGE}
EOF
echo -n "Enter number or image file name (default=0): "
read filename
if [ -z "${filename}" ] ; then
filename="${STAGE_2_BIG_IMAGE}"
elif [ "${filename}" == "0" ] ; then
filename=${STAGE_2_BIG_IMAGE}
elif [ "${filename}" == "1" ] ; then
filename="${STAGE_2_SMALL_IMAGE}"
fi
url="${baseurl%/}/${filename}"
echo "[ ${url} ]"
ROCK_INSTALL_SOURCE_URL=${baseurl}
exit_linuxrc=1;
if ! mkdir /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 /mnt_root"
exit_linuxrc=0
fi
wget -O - ${url} | tar ${STAGE_2_COMPRESS_ARG} -C /mnt_root -xf -
echo "finished ... now booting 2nd stage"
doboot
} # }}}
load_modules() { # {{{
# this starts the module loading shell
directory=${1}
cat <<EOF
module loading shell
you can navigate through the filestem with 'cd'. for loading a module
simply enter the shown name, to exit press enter on a blank line.
EOF
cd ${directory}
while : ; do
echo "Directories:"
count=0
while read inode ; do
[ -d "${inode}" ] || continue
echo -n " [ ${inode} ]"
count=$((${count}+1))
if [ ${count} -gt 3 ] ; then
echo
count=0
fi
done < <( ls ) | expand -t1,3,19,21,23,39,41,43,59,61,63,78
echo
echo "Modules:"
count=0
while read inode ; do
[ -f "${inode}" ] || continue
[ "${inode%${mod_suffix}}" == "${inode}" ] && continue
echo -n " [ ${inode%${mod_suffix}} ]"
count=$((${count}+1))
if [ ${count} -gt 3 ] ; then
echo
count=0
fi
done < <( ls ) | expand -t1,3,19,21,23,39,41,43,59,61,63,78
echo
echo -n "[${PWD##*/} ] > "
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 <<EOF
0. Load 2nd stage system from local device
1. Load 2nd stage system from network
2. Configure network interfaces (IPv4 only)
3. Load kernel modules from this disk
4. Load kernel modules from another disk
5. Activate already formatted swap device
6. Execute a shell (for experts!)
7. Validate a CD/DVD against its embedded checksum
EOF
echo -n "What do you want to do [0-7] (default=0)? "
read text
[ -z "${text}" ] && text=0
input=${text//[^0-9]/}
case "${input}" in
0)
load_ramdisk_file 0
;;
1)
httpload
;;
2)
config_net
;;
3)
load_modules "${mod_dir}"
;;
4)
mkdir "/mnt_floppy" || echo "Can't create /mnt_floppy"
trymount "/dev/floppy/0" "/mnt_floppy" && load_modules "/mnt_floppy"
umount "/mnt_floppy" || echo "Can't umount /mnt_floppy"
rmdir "/mnt_floppy" || echo "Can't remove /mnt_floppy"
;;
5)
activate_swap
;;
6)
exec_sh
;;
7)
checkisomd5
;;
*)
echo "No such option present!"
esac
done
exec /linuxrc
echo "Can't start /linuxrc!! Life sucks.\n\n"

+ 2
- 2
target/bootdisk/linuxrc2.sh

@ -10,12 +10,12 @@ else
done
fi
grep -v "^rootfs " /proc/mounts > /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

Loading…
Cancel
Save