diff --git a/Makefile b/Makefile index 703008a..4d7ad25 100644 --- a/Makefile +++ b/Makefile @@ -4,17 +4,14 @@ DESTDIR = BINDIR ?= /usr/bin LIBDIR ?= /usr/lib -BINSDIR ?= $(LIBDIR)/$(PACKAGE)/bin -TARGETS = init stage1 - -all: version.h $(TARGETS) +INSTALL = /usr/bin/install #--------------------------------------------------------------- L ?= GLIBC #L = KLIBC -ifeq (KLIBC, $(L)) +ifeq ($(L),KLIBC) CC = klcc endif @@ -26,31 +23,31 @@ F = STDIO endif endif -CFLAGS += -Os -pipe -Wall -D_GNU_SOURCE +CFLAGS += -Os -pipe -Wall GLIBC_INCLUDES = KLIBC_INCLUDES = -INCLUDES = -I. $($(L)_INCLUDES) +INCLUDES = $($(L)_INCLUDES) -GCC_LIBDIR=$(shell dirname `gcc -print-libgcc-file-name`) -LIBGCC_A=$(shell gcc -print-libgcc-file-name) - -GLIBC_LDFLAGS_STAGE1 = -static -KLIBC_LDFLAGS_STAGE1 = - -# $(LIBGCC_A) -LDFLAGS_STAGE1 = $($(L)_LDFLAGS_STAGE1) +GLIBC_LDFLAGS = -static +KLIBC_LDFLAGS = +LDFLAGS = $($(L)_LDFLAGS) GLIBC_LIBC = KLIBC_LIBC = -STAGE1_LIBC = $($(L)_LIBC) +LIBC = $($(L)_LIBC) STRIPCMD = strip -R .note -R .comment -#--------------------------------------------------------------- -DEFS = -INIT_DEFS = -STAGE1_DEFS = +#--------------------------------------------------------------- +DEFS = -D_GNU_SOURCE + +#--------------------------------------------------------------- +INITSRC = init.c +INITOBJS = $(addprefix $(L)-,$(subst .c,.o,$(INITSRC))) + +#--------------------------------------------------------------- +STAGE1_DEFS = ifneq ($(WITH_SHELL),) STAGE1_DEFS += -DSPAWN_SHELL endif @@ -64,14 +61,7 @@ ifneq ($(WITHOUT_USBNET),) STAGE1_DEFS += -DDISABLE_USBNET endif -COMPILE = $(CC) $(DEFS) $(CFLAGS) - -#- stage1 "loader" -# i386 name is invalid to force this feature off -INITSRC = init.c -INIT_DEFS = $(INCLUDES) - -INITOBJS = $(addprefix $(L)-,$(subst .c,.o,$(INITSRC))) +COMPILE = $(CC) $(CFLAGS) $(DEFS) #- frontends NEWT_FRONTEND_SRC = newt-frontend.c @@ -87,35 +77,26 @@ GLIBC_STAGE1_OWN_LIBS = KLIBC_STAGE1_OWN_LIBS = STAGE1_OWN_LIBS = $($(L)_STAGE1_OWN_LIBS) -ifeq ($(L),KLIBC) -STAGE1_NETWORK_LIBS = -endif +KLIBC_STAGE1_NETWORK_LIBS = +GLIBC_STAGE1_NETWORK_LIBS = $(LIBDIR)/libresolv.a +STAGE1_NETWORK_LIBS = $($(L)_STAGE1_NETWORK_LIBS) -ifeq ($(L),GLIBC) -STAGE1_NETWORK_LIBS = $(LIBDIR)/libresolv.a -endif - -############################################################################### -# stage1 itself STAGE1SRC = stage1.c log.c tools.c modules.c probing.c \ mount.c lomount.c automatic.c frontend-common.c \ cdrom.c disk.c \ - network.c nfsmount.c dhcp.c url.c dns.c adsl.c - -ALLSRC = $(INITSRC) $(STAGE1SRC) -############################################################################### + network.c dhcp.c url.c dns.c adsl.c STAGE1OBJS = $(addprefix $(L)-,$(subst .c,.o,$(STAGE1SRC))) -LDFLAGS_INIT = $($(L)_LDFLAGS_STAGE1) -INIT_LIBC = $($(L)_LIBC) +#--------------------------------------------------------------- +ALLSRC = $(INITSRC) $(STAGE1SRC) -init: $(INITOBJS) $(INIT_LIBC) - $(CC) -o $@ $^ $(LDFLAGS_INIT) - $(STRIPCMD) $@ +TARGETS = init gencpio -stage1: $(STAGE1OBJS) $(STAGE1_OWN_LIBS) $(STAGE1_NETWORK_LIBS) $(FRONTEND_LINK) $(STAGE1_LIBC) - $(CC) -o $@ $^ $(LDFLAGS_STAGE1) +all: version.h $(TARGETS) + +init: $(INITOBJS) $(STAGE1OBJS) $(STAGE1_OWN_LIBS) $(STAGE1_NETWORK_LIBS) $(FRONTEND_LINK) $(STAGE1_LIBC) + $(CC) -o $@ $^ $(LDFLAGS) $(STRIPCMD) $@ $(INITOBJS): $(L)-%.o: %.c @@ -131,27 +112,23 @@ version.h: /etc/altlinux-release @sed 's|^ALT Linux \([^ ]\+\)\([^(]\+\)(\([^)]\+\))|\ echo \\#define VERSION \\"\2\\";echo \\#define DISTRIB_NAME \\"ALT Linux\2\1 \\(\3\\)\\"|' < $^ |sh > $@ +gencpio: gen_init_cpio.c + $(CC) $(CFLAGS) $(DEFS) -o $@ $^ + +initfs: mkinitfs $(TARGETS) + sh $< $@ + +install: initfs + $(INSTALL) -D -m0755 gencpio $(DESTDIR)$(BINDIR)/gencpio + $(INSTALL) -m0755 mkmodpack $(DESTDIR)$(BINDIR)/mkmodpack + $(INSTALL) -D -m0644 initfs $(DESTDIR)$(LIBDIR)/$(PACKAGE)/initfs + clean: rm -f *.o .depend $(TARGETS) version.h -.depend: +.depend: version.h $(CPP) $(CFLAGS) -M $(ALLSRC) > .depend ifeq (.depend,$(wildcard .depend)) include .depend endif - -gencpio: gen_init_cpio.c - $(CC) $(CFLAGS) -o $@ $^ - -install: $(TARGETS) - mkdir -p $(DESTDIR)$(BINDIR) $(DESTDIR)$(BINSDIR) - install -m0755 gencpio $(DESTDIR)$(BINDIR) - install -m0755 init stage1 $(DESTDIR)$(BINSDIR) - -initfs: all mkinitfs - sh mkinitfs > $@ - -test: initfs modpack - cat $^ > $@ - qstage -initrd test diff --git a/init.c b/init.c index 7c3cf6c..eec3e13 100644 --- a/init.c +++ b/init.c @@ -33,6 +33,7 @@ #include #include "config-stage1.h" +#include "lomount.h" #if defined(__powerpc__) #define TIOCSCTTY 0x540 @@ -53,11 +54,20 @@ char * env[] = { char ** myenv = NULL; +<<<<<<< HEAD:init.c char *stage[] = {"/sbin/stage1", NULL}; +======= +>>>>>>> e918341c2dd1189e2ef8991eba56480304bead8b:init.c char *udevd[] = {"/sbin/udevd", NULL}; char *udevtrigger[] = {"/sbin/udevtrigger", NULL}; char *udevsettle[] = {"/sbin/udevsettle", NULL}; +<<<<<<< HEAD:init.c +======= + +extern void stage1(); + +>>>>>>> e918341c2dd1189e2ef8991eba56480304bead8b:init.c /* * this needs to handle the following cases: * @@ -130,7 +140,7 @@ pid_t spawn(char *av[]) } } -void grab_env(int fd) +void take_env(int fd) { static char buf[PIPE_BUF]; char *p = buf; @@ -159,24 +169,6 @@ void grab_env(int fd) *ep = NULL; } -#define LOOP_CLR_FD 0x4C01 - -void del_loop(char *device) -{ - int fd; - if ((fd = open(device, O_RDONLY, 0)) < 0) { - printf("del_loop open failed\n"); - return; - } - - if (ioctl(fd, LOOP_CLR_FD, 0) < 0) { - printf("del_loop ioctl failed"); - return; - } - - close(fd); -} - /* initramfs cleaner */ @@ -348,7 +340,10 @@ int main(int argc, char **argv) struct stat rst, cst, ist; struct statfs sfs; pid_t pid, klogpid, udevpid; +<<<<<<< HEAD:init.c sigset_t sig; +======= +>>>>>>> e918341c2dd1189e2ef8991eba56480304bead8b:init.c int wait_status; int fd = -1; int fds[2]; @@ -442,9 +437,13 @@ int main(int argc, char **argv) fcntl(fds[0], F_SETFD, 1); fcntl(fds[1], F_SETFD, 0); - pid = spawn(stage); - close(fds[1]); - while (pid != wait(&wait_status)); + if ((pid = fork())) { + if (pid < 0) fatal("Failed to spawn stage1"); + close(fds[1]); + while (pid != wait(&wait_status)); + } else { + stage1(); + } if (!(WIFEXITED(wait_status))) { /* something went wrong */ @@ -472,7 +471,7 @@ int main(int argc, char **argv) while (1); } - grab_env(fds[0]); + take_env(fds[0]); if (waitpid(spawn(udevsettle), &wait_status, 0) < 0 || !(WIFEXITED(wait_status))) diff --git a/lomount.c b/lomount.c index 24ed23c..da9ec96 100644 --- a/lomount.c +++ b/lomount.c @@ -114,12 +114,11 @@ set_loop (const char *device, const char *file) char * loopdev = "/dev/loop3"; /* Ugly. But do I care? */ -void -del_loop(void) +void del_loop(char *device) { int fd; - if ((fd = open (loopdev, O_RDONLY)) < 0) + if ((fd = open (device, O_RDONLY)) < 0) return; if (ioctl (fd, LOOP_CLR_FD, 0) < 0) @@ -148,7 +147,7 @@ lomount(char *loopfile, char *where) } if (my_mount(loopdev, where, "iso9660", 0)) { - del_loop(); + del_loop(loopdev); return 1; } @@ -165,7 +164,7 @@ loumount() umount(where_mounted); where_mounted = NULL; } - del_loop(); + del_loop(loopdev); return 0; } diff --git a/lomount.h b/lomount.h index 3b8a30a..b06c27d 100644 --- a/lomount.h +++ b/lomount.h @@ -17,5 +17,6 @@ int lomount(char *loopfile, char *where); int loumount(void); +void del_loop(char *device); #endif diff --git a/mkinitfs b/mkinitfs new file mode 100755 index 0000000..6038005 --- /dev/null +++ b/mkinitfs @@ -0,0 +1,63 @@ +#!/bin/sh -e + +out=$1 +shift + +[ -n "$out" ] || { + echo "Usage: mkinitfs outfile" >&2 + exit 1 +} + +exit_handler() +{ + local rc=$? + trap - EXIT + [ $rc -eq 0 ] || rm -f -- $out + exit $rc +} + +trap exit_handler HUP PIPE INT TERM QUIT EXIT + +( + +cat < $out diff --git a/mkmodpack b/mkmodpack new file mode 100644 index 0000000..7b991f3 --- /dev/null +++ b/mkmodpack @@ -0,0 +1,220 @@ +#!/bin/sh + +PROG=mkmodpack +VERSION=0.1 +CATCHED= + +Exit() +{ + local rc=$? + [ -z "$1" ] || rc="$1" + CATCHED=1 + exit $rc +} + +Warning() +{ + echo "$PROG: warning: $*" >&2 +} + +Fatal() +{ + echo "$PROG: $*" >&2 + Exit 1 +} + +KERNEL= +OUTPUT= +WORKDIR= +TEMPLATE= +pattern= +uname_r="$(uname -r)" + +exit_handler() +{ + local rc=$? + trap - EXIT + [ -n "$CATCHED" -o $rc -eq 0 ] || + echo "$PROG: unhandled error, exiting..." + [ -z "$WORKDIR" ] || rm -rf "$WORKDIR" + [ -z "$TEMPLATE" ] || rm -f "$TEMPLATE" + exit $rc +} + +signal_handler() +{ + echo 'Interrupted!' >&2 + Exit 1 +} + +trap exit_handler EXIT +trap signal_handler SIGHUP SIGPIPE SIGINT SIGTERM SIGQUIT + +FIRMWARE_DIRS="/lib/firmware /usr/lib/hotplug/firmware" + +Usage() +{ + cat >&2 </dev/null |grep -wf "$pattern" + else + modprobe --set-version="$KERNEL" --list "$@" 2>/dev/null + fi +} + +ListModuleFiles() +{ + modprobe --set-version="$KERNEL" --show-depends \ + --ignore-all-commands "$@" 2>/dev/null +} + +AddUniqueModule() +{ + local path="$1" modules= + modules="$MODULES +$path" + modules="$(echo "$modules" |sort)" + if [ -z "$(echo "$modules" |uniq -d)" ]; then + echo "$modules" + fi +} + +AddModuleFile() +{ + local path="$1" name="$1" modules= + name="${name##*/}" + name="${name%.gz}" + name="${name%.ko}" + + modules=$(AddUniqueModule "$path") + if [ -n "$modules" ]; then + MODULES="$modules" + AddModuleFirmware "$name" "$path" + fi +} + +AddModuleFirmware() +{ + local mod_name="$1" && shift + local mod_path="$1" && shift + local fw_list fw_name fw_dir fw_file + + fw_list="$(modinfo -F firmware "$mod_path")" || return + [ -n "$fw_list" ] || return + for fw_name in $fw_list; do + fw_file= + for fw_dir in $FIRMWARE_DIRS; do + if [ -r "$fw_dir/$fw_name" ]; then + fw_file="$fw_dir/$fw_name" + break + fi + done + [ -n "$fw_file" ] || { + Warning "Firmware file \"$fw_name\" for module \"$mod_name\" not found" + continue + } + FILES="$FILES +file /lib/firmware/$fw_name $fw_file 0644 0 0" + done +} + +AddModule() +{ + local path="$1" name="$1" m list + name="${name##*/}" + name="${name%.gz}" + name="${name%.ko}" + + list=`ListModuleFiles "$name"` + for m in $list; do + [ -z "${m##/lib/modules/*}" ] || continue + AddModuleFile "$m" + done +} + +TEMP=`getopt -n "$0" -o k:,o:,p:,h -l kernel:,output:,pattern:,help,version -- "$@"` || exit 1 +eval set -- "$TEMP" + +while :; do + case "$1" in + -k|--kernel) + shift + KERNEL="$1" + ;; + -o|--output) + shift + OUTPUT="$1" + ;; + -p|--pattern*) + shift + pattern="$1" + ;; + -h|--help) + Usage 0 + ;; + --version) + echo "$PROG: version $VERSION" + exit 0 + ;; + --) shift; break + ;; + *) Fatal "Unrecognized option: $1" + ;; + esac + shift +done + +[ -n "$KERNEL" ] || KERNEL="$uname_r" +[ -d "/lib/modules/$KERNEL" ] || Fatal "Directory /lib/modules/$KERNEL does not exists." + +#--------------------------------------------------------------- +MODULES= +FILES= + +for m in $(ListModules); do + AddModule "$m" +done + +WORKDIR=`mktemp -td mkmodpack.XXXXXXXXXX` || Fatal "Failed to create working directory." +TEMPLATE=`mktemp -t mkmodpack.XXXXXXXXXX` || Fatal "Failed to create temporary file." + +echo "$MODULES" |cpio -pmd "$WORKDIR" 2>/dev/null || Fatal "Failed to copy modules to working directory." +depmod -a -F "/boot/System.map-$KERNEL" -b "$WORKDIR" "$KERNEL" || Fatal "Failed to create modules dependencies." + +( +cd "$WORKDIR" +find "lib/modules/$KERNEL" -type d |sed -e 's,^.\+$,dir\t/&\t0755\t0 0,g' +find "lib/modules/$KERNEL" -type f |sed -e "s,^.\+$,file\t/&\t$WORKDIR/&\t0644\t0 0,g" +echo "$FILES" +) > "$TEMPLATE" + +if [ -n "$OUTPUT" ]; then + gencpio "$TEMPLATE" |gzip -c > "$OUTPUT" +else + gencpio "$TEMPLATE" |gzip -c +fi + +Exit 0 diff --git a/mount.c b/mount.c index 466a357..d5044af 100644 --- a/mount.c +++ b/mount.c @@ -25,11 +25,19 @@ #include #include #include +#include + +#ifndef DISABLE_NETWORK +#include +#include +#include +#endif + #include "log.h" #include "modules.h" #include "mount.h" - +#include "dns.h" #ifndef DISABLE_MEDIAS @@ -117,6 +125,48 @@ int ensure_dev_exists(char *dev) } #endif /* DISABLE_MEDIAS */ +#ifndef DISABLE_NETWORK + +static int nfsmount(char *dev, char *location) +{ + char spec[PATH_MAX + 17], *sep; + struct sockaddr_in saddr; + int n, pid, status; + + if ((sep = strchr(dev, ':'))) { + *sep = '\0'; + } else { + log_message("nfsmount: directory to mount not in host:dir format"); + return -1; + } + + saddr.sin_family = AF_INET; + if (!inet_aton(dev, &saddr.sin_addr) && + mygethostbyname(dev, &saddr.sin_addr)) { + log_message("nfsmount: can't get address for %s", dev); + *sep = ':'; + return -1; + } + + *sep = ':'; + strcpy(spec, inet_ntoa(saddr.sin_addr)); + n = strlen(spec); + strncpy(spec + n, sep, sizeof(spec) - n); + log_message("nfsmount %s %s", spec, location); + + if (!(pid = fork())) { + char * argv[] = {"/bin/nfsmount", spec, location, NULL}; + close(0); + close(1); + close(2); + execve(argv[0], argv, NULL); + exit(1); + } + + waitpid(pid, &status, 0); + return (WIFEXITED(status) && !WEXITSTATUS(status)) ? 0 : -1; +} +#endif /* mounts, creating the device if needed+possible */ int my_mount(char *dev, char *location, char *fs, int force_rw) @@ -155,6 +205,12 @@ int my_mount(char *dev, char *location, char *fs, int force_rw) } } +#ifndef DISABLE_NETWORK + if (!strcmp(fs, "nfs")) { + return nfsmount(dev, location); + } +#endif + #ifndef DISABLE_MEDIAS if (!strcmp(fs, "squashfs")) my_insmod("squashfs", NULL); @@ -177,16 +233,6 @@ int my_mount(char *dev, char *location, char *fs, int force_rw) my_insmod("isofs", NULL); #endif -#ifndef DISABLE_NETWORK - if (!strcmp(fs, "nfs")) { - my_insmod("nfs", NULL); - log_message("preparing nfsmount for %s", dev); - rc = nfsmount_prepare(dev, &opts); - if (rc != 0) - return rc; - } -#endif - rc = mount(dev, location, fs, flags, opts); if (rc != 0) { log_perror("mount failed"); diff --git a/mount.h b/mount.h index 8279546..6c5ea10 100644 --- a/mount.h +++ b/mount.h @@ -22,10 +22,6 @@ #ifndef _MOUNT_H_ #define _MOUNT_H_ -#ifndef DISABLE_NETWORK -#include "nfsmount.h" -#endif - int my_mount(char *dev, char *location, char *fs, int force_rw); #ifndef DISABLE_MEDIAS diff --git a/probing.c b/probing.c index 5a5b3ea..41965fd 100644 --- a/probing.c +++ b/probing.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/propagator.spec b/propagator.spec index 8e0fec7..02ba426 100644 --- a/propagator.spec +++ b/propagator.spec @@ -2,8 +2,8 @@ %def_with splash Name: propagator -Version: 20070301 -Release: alt7 +Version: 20080301 +Release: alt1 Summary: 'Early userspace' set of binaries License: GPL @@ -11,7 +11,8 @@ Group: System/Kernel and hardware Source0: %name-%version-%release.tar -BuildRequires: bzlib-devel-static libnewt-devel-static libslang-devel-static +BuildRequires: libnewt-devel-static libslang-devel-static +BuildRequires: mkinitrd-busybox module-init-tools-initramfs udev-initramfs %description %name is a set of binaries useful in 'early userspace' environment, @@ -21,19 +22,20 @@ including init and various helpers for hw probing and bootstrapping. %setup %build -make CFLAGS="$RPM_OPT_FLAGS" \ - %{?_with_shell:WITH_SHELL=t} \ - %{?_with_splash:WITH_SPLASH=t} \ - LIBDIR=%_libdir +make %{?_with_shell:WITH_SHELL=t} %{?_with_splash:WITH_SPLASH=t} %install %make_install DESTDIR=%buildroot LIBDIR=%_libdir install %files %_bindir/gencpio +%_bindir/mkmodpack %_libdir/%name %changelog +* Sat Mar 1 2008 Sergey Bolshakov 20080301-alt1 +- use udev from now + * Wed Aug 8 2007 Sergey Bolshakov 20070301-alt7 - do not show %name build date on tty1, closes \#12491 diff --git a/stage1.c b/stage1.c index 789a040..c258824 100644 --- a/stage1.c +++ b/stage1.c @@ -59,6 +59,7 @@ #include "disk.h" #endif +extern char *env[]; /************************************************************ * globals */ @@ -134,7 +135,7 @@ static void spawn_shell(void) if (ioctl(0, TIOCSCTTY, NULL)) log_perror("could not set new controlling tty"); - execve(shell_name[0], shell_name, grab_env()); + execve(shell_name[0], shell_name, env); log_message("execve of %s failed: %s", shell_name[0], strerror(errno)); exit(-1); } @@ -167,11 +168,11 @@ static void spawn_splash(void) dup2(fd, 2); close(fd); setsid(); - execve(splash_name[0], splash_name, NULL); + execve(splash_name[0], splash_name, env); log_message("execve of %s failed: %s", splash_name[0], strerror(errno)); exit(-1); } - + close(fd); #endif } @@ -318,7 +319,7 @@ void getversion() fclose(f); } -int main(int argc, char **argv, char **env) +void stage1() { enum return_type ret; char buf[128]; @@ -356,11 +357,11 @@ int main(int argc, char **argv, char **env) /* all went good */ if (shell_pid != 0) kill(shell_pid, 9); - + if (splash_pid != 0) kill(splash_pid, 9); pass_env(4); - return 0; /* shut up compiler (we can't get here anyway!) */ + exit(0); } diff --git a/tools.c b/tools.c index dd8c60f..10ac901 100644 --- a/tools.c +++ b/tools.c @@ -32,6 +32,7 @@ #include #include #include + #include "stage1.h" #include "log.h" #include "mount.h" @@ -374,7 +375,7 @@ int update_splash() return 0; splashstep++; progress = (65534 * splashstep ) / splashcount; - log_message("boostplash progress: %i",progress); + log_message("bootsplash progress: %i",progress); sprintf(data,"show %i\n",progress); return write(splashfd,data,strlen(data)); }