massive change caused by udev use in initramfs:
- added udevd, udevtrigger & udevsettle spawning from init, reproducing nead same logic, found in initrd, created by /sbin/mkinitd - lots of obsolete by this change stuff removed - use external /sbin/modprobe form klibc utils in places, where manual module loading still needed - pack unchangeable part of initramfs into `initfs' file (gzipped cpio archive), which may be concatenated later with other parts (especially kernel modules) to form actual initramfs image.
This commit is contained in:
parent
85b34d353b
commit
0a6af0fb35
@ -1 +1 @@
|
|||||||
tar.bz2: . name=propagator-@version@ base=
|
tar: . name=@name@-@version@-@release@ base=@name@-@version@
|
||||||
|
161
Makefile
161
Makefile
@ -1,40 +1,3 @@
|
|||||||
#******************************************************************************
|
|
||||||
#
|
|
||||||
# mdk-stage1 - the program that will load second-stage install
|
|
||||||
#
|
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
# Portions from Erik Troan (ewt@redhat.com) Copyright 1996 Red Hat Software
|
|
||||||
#
|
|
||||||
#*****************************************************************************
|
|
||||||
#
|
|
||||||
# Currently:
|
|
||||||
#
|
|
||||||
# ix86
|
|
||||||
# init with minilibc
|
|
||||||
# stage1 with dietlibc except some targets
|
|
||||||
#
|
|
||||||
# ppc
|
|
||||||
# init with dietlibc
|
|
||||||
# stage1 with glibc
|
|
||||||
#
|
|
||||||
# ia64
|
|
||||||
# init with glibc
|
|
||||||
# stage1 with glibc
|
|
||||||
#
|
|
||||||
#*****************************************************************************
|
|
||||||
|
|
||||||
PACKAGE = propagator
|
PACKAGE = propagator
|
||||||
|
|
||||||
DESTDIR =
|
DESTDIR =
|
||||||
@ -43,13 +6,49 @@ BINDIR ?= /usr/bin
|
|||||||
LIBDIR ?= /usr/lib
|
LIBDIR ?= /usr/lib
|
||||||
BINSDIR ?= $(LIBDIR)/$(PACKAGE)/bin
|
BINSDIR ?= $(LIBDIR)/$(PACKAGE)/bin
|
||||||
|
|
||||||
|
INSTALL = /usr/bin/install
|
||||||
TARGETS = init stage1 gencpio
|
TARGETS = init stage1 gencpio
|
||||||
|
|
||||||
all: version.h $(TARGETS)
|
all: version.h $(TARGETS)
|
||||||
|
|
||||||
include Makefile.common
|
#---------------------------------------------------------------
|
||||||
|
L ?= GLIBC
|
||||||
|
#L = KLIBC
|
||||||
|
|
||||||
DEFS =
|
ifeq ($(L),KLIBC)
|
||||||
|
CC = klcc
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(F),)
|
||||||
|
ifeq ($(L),GLIBC)
|
||||||
|
F = NEWT
|
||||||
|
else
|
||||||
|
F = STDIO
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
CFLAGS += -Os -pipe -Wall
|
||||||
|
|
||||||
|
GLIBC_INCLUDES =
|
||||||
|
KLIBC_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_LIBC =
|
||||||
|
KLIBC_LIBC =
|
||||||
|
STAGE1_LIBC = $($(L)_LIBC)
|
||||||
|
|
||||||
|
STRIPCMD = strip -R .note -R .comment
|
||||||
|
#---------------------------------------------------------------
|
||||||
|
DEFS = -D_GNU_SOURCE
|
||||||
INIT_DEFS =
|
INIT_DEFS =
|
||||||
STAGE1_DEFS =
|
STAGE1_DEFS =
|
||||||
|
|
||||||
@ -66,47 +65,34 @@ ifneq ($(WITHOUT_USBNET),)
|
|||||||
STAGE1_DEFS += -DDISABLE_USBNET
|
STAGE1_DEFS += -DDISABLE_USBNET
|
||||||
endif
|
endif
|
||||||
|
|
||||||
COMPILE = $(CC) $(DEFS) $(CFLAGS)
|
COMPILE = $(CC) $(CFLAGS) $(DEFS)
|
||||||
|
|
||||||
#- stage1 "loader"
|
#- stage1 "loader"
|
||||||
# i386 name is invalid to force this feature off
|
# i386 name is invalid to force this feature off
|
||||||
ifeq (xi386, $(ARCH))
|
|
||||||
INITSRC = minilibc.c init.c
|
|
||||||
INIT_DEFS = -DINIT_HEADERS=\"minilibc.h\"
|
|
||||||
else
|
|
||||||
INITSRC = init.c
|
INITSRC = init.c
|
||||||
ifeq (ia64, $(ARCH))
|
INIT_DEFS = $(INCLUDES)
|
||||||
INIT_DEFS = -DINIT_HEADERS=\"init-libc-headers.h\" $(GLIBC_INCLUDES)
|
|
||||||
else
|
|
||||||
INIT_DEFS = -DINIT_HEADERS=\"init-libc-headers.h\" $(DIETLIBC_INCLUDES)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
INITOBJS = $(subst .c,.o,$(INITSRC))
|
INITOBJS = $(addprefix $(L)-,$(subst .c,.o,$(INITSRC)))
|
||||||
|
|
||||||
#- frontends
|
#- frontends
|
||||||
NEWT_FRONTEND_SRC = newt-frontend.c
|
NEWT_FRONTEND_SRC = newt-frontend.c
|
||||||
GLIBC_NEWT_FRONTEND_LIBS = $(LIBDIR)/libnewt.a $(LIBDIR)/libslang.a
|
NEWT_FRONTEND_LIBS = $(LIBDIR)/libnewt.a $(LIBDIR)/libslang.a
|
||||||
DIETLIBC_NEWT_FRONTEND_LIBS = $(DIET_LIBDIR)/libnewt.a $(DIET_LIBDIR)/libslang.a
|
|
||||||
|
|
||||||
STDIO_FRONTEND_SRC = stdio-frontend.c
|
STDIO_FRONTEND_SRC = stdio-frontend.c
|
||||||
GLIBC_STDIO_FRONTEND_LIBS =
|
STDIO_FRONTEND_LIBS =
|
||||||
DIETLIBC_STDIO_FRONTEND_LIBS =
|
|
||||||
|
|
||||||
|
FRONTEND_OBJS = $(addprefix $(L)-,$(subst .c,.o,$($(F)_FRONTEND_SRC)))
|
||||||
|
FRONTEND_LINK = $(FRONTEND_OBJS) $($(F)_FRONTEND_LIBS)
|
||||||
|
|
||||||
FRONTEND_OBJS = $(subst .c,.o,$($(F)_FRONTEND_SRC))
|
GLIBC_STAGE1_OWN_LIBS =
|
||||||
FRONTEND_LINK = $(FRONTEND_OBJS) $($(L)_$(F)_FRONTEND_LIBS)
|
KLIBC_STAGE1_OWN_LIBS =
|
||||||
|
|
||||||
GLIBC_STAGE1_OWN_LIBS = $(LIBDIR)/libmar.a $(LIBDIR)/libbz2.a
|
|
||||||
DIETLIBC_STAGE1_OWN_LIBS = $(DIET_LIBDIR)/libmar.a $(DIET_LIBDIR)/libbz2.a
|
|
||||||
STAGE1_OWN_LIBS = $($(L)_STAGE1_OWN_LIBS)
|
STAGE1_OWN_LIBS = $($(L)_STAGE1_OWN_LIBS)
|
||||||
|
|
||||||
|
ifeq ($(L),KLIBC)
|
||||||
ifeq (DIETLIBC, $(L))
|
STAGE1_NETWORK_LIBS =
|
||||||
STAGE1_NETWORK_LIBS = $(DIET_LIBDIR)/librpc.a
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq (GLIBC, $(L))
|
ifeq ($(L),GLIBC)
|
||||||
STAGE1_NETWORK_LIBS = $(LIBDIR)/libresolv.a
|
STAGE1_NETWORK_LIBS = $(LIBDIR)/libresolv.a
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -116,25 +102,16 @@ STAGE1SRC = stage1.c log.c tools.c modules.c probing.c \
|
|||||||
mount.c lomount.c automatic.c frontend-common.c \
|
mount.c lomount.c automatic.c frontend-common.c \
|
||||||
cdrom.c disk.c \
|
cdrom.c disk.c \
|
||||||
network.c nfsmount.c dhcp.c url.c dns.c adsl.c
|
network.c nfsmount.c dhcp.c url.c dns.c adsl.c
|
||||||
|
|
||||||
ALLSRC = $(INITSRC) $(STAGE1SRC)
|
ALLSRC = $(INITSRC) $(STAGE1SRC)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
STAGE1OBJS = $(subst .c,.o,$(STAGE1SRC))
|
STAGE1OBJS = $(addprefix $(L)-,$(subst .c,.o,$(STAGE1SRC)))
|
||||||
|
|
||||||
ifeq (xi386, $(ARCH))
|
LDFLAGS_INIT = $($(L)_LDFLAGS_STAGE1)
|
||||||
LDFLAGS_INIT = -static -nostdlib /usr/lib/crt1.o
|
INIT_LIBC = $($(L)_LIBC)
|
||||||
else
|
|
||||||
ifeq (ia64, $(ARCH))
|
|
||||||
LDFLAGS_INIT = $(GLIBC_LDFLAGS_STAGE1)
|
|
||||||
INIT_LIBC = $(GLIBC_LIBC)
|
|
||||||
else
|
|
||||||
LDFLAGS_INIT = $(GLIBC_LDFLAGS_STAGE1)
|
|
||||||
INIT_LIBC = $(GLIBC_LIBC)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
init: $(INITOBJS) $(INIT_LIBC)
|
||||||
init: $(INITOBJS) $(INIT_LIBC)
|
|
||||||
$(CC) -o $@ $^ $(LDFLAGS_INIT)
|
$(CC) -o $@ $^ $(LDFLAGS_INIT)
|
||||||
$(STRIPCMD) $@
|
$(STRIPCMD) $@
|
||||||
|
|
||||||
@ -142,19 +119,29 @@ stage1: $(STAGE1OBJS) $(STAGE1_OWN_LIBS) $(STAGE1_NETWORK_LIBS) $(FRONTEND_LINK)
|
|||||||
$(CC) -o $@ $^ $(LDFLAGS_STAGE1)
|
$(CC) -o $@ $^ $(LDFLAGS_STAGE1)
|
||||||
$(STRIPCMD) $@
|
$(STRIPCMD) $@
|
||||||
|
|
||||||
$(INITOBJS): %.o: %.c
|
$(INITOBJS): $(L)-%.o: %.c
|
||||||
$(COMPILE) $(INIT_DEFS) -c $<
|
$(COMPILE) $(INIT_DEFS) -c $< -o $@
|
||||||
|
|
||||||
$(STAGE1OBJS): %.o: %.c
|
$(STAGE1OBJS): $(L)-%.o: %.c
|
||||||
$(COMPILE) $(INCLUDES) $(STAGE1_DEFS) -c $< -o $@
|
$(COMPILE) $(INCLUDES) $(STAGE1_DEFS) -c $< -o $@
|
||||||
|
|
||||||
.c.o:
|
$(FRONTEND_OBJS): $(L)-%.o: %.c
|
||||||
$(COMPILE) $(INCLUDES) -c $<
|
$(COMPILE) $(INCLUDES) -c $< -o $@
|
||||||
|
|
||||||
version.h: /etc/altlinux-release
|
version.h: /etc/altlinux-release
|
||||||
@sed 's|^ALT Linux \([^ ]\+\)\([^(]\+\)(\([^)]\+\))|\
|
@sed 's|^ALT Linux \([^ ]\+\)\([^(]\+\)(\([^)]\+\))|\
|
||||||
echo \\#define VERSION \\"\2\\";echo \\#define DISTRIB_NAME \\"ALT Linux\2\1 \\(\3\\)\\"|' < $^ |sh > $@
|
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) -D -m0644 initfs $(DESTDIR)$(LIBDIR)/$(PACKAGE)/initfs
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f *.o .depend $(TARGETS) version.h
|
rm -f *.o .depend $(TARGETS) version.h
|
||||||
|
|
||||||
@ -164,11 +151,3 @@ clean:
|
|||||||
ifeq (.depend,$(wildcard .depend))
|
ifeq (.depend,$(wildcard .depend))
|
||||||
include .depend
|
include .depend
|
||||||
endif
|
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)
|
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
# -*- makefile -*-
|
|
||||||
#******************************************************************************
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
#*****************************************************************************
|
|
||||||
|
|
||||||
#include /usr/lib/dietlibc/Makefile.rules
|
|
||||||
|
|
||||||
#DIET_LIBDIR = /usr/lib/dietlibc/lib-$(ARCH)
|
|
||||||
|
|
||||||
#- default lib is dietlibc (honoured by main Makefile whenever possible)
|
|
||||||
#L = DIETLIBC
|
|
||||||
L = GLIBC
|
|
||||||
|
|
||||||
#- default frontend is newt (honoured by main Makefile whenever possible)
|
|
||||||
F = NEWT
|
|
||||||
# F = STDIO
|
|
||||||
|
|
||||||
#- override in some situations
|
|
||||||
ifeq (ia64, $(ARCH))
|
|
||||||
L = GLIBC
|
|
||||||
endif
|
|
||||||
ifeq (ppc, $(ARCH))
|
|
||||||
L = GLIBC
|
|
||||||
endif
|
|
||||||
|
|
||||||
#- flags used by all stuff
|
|
||||||
ifeq (ppc, $(ARCH))
|
|
||||||
CFLAGS += -Os -pipe -Wall -fomit-frame-pointer
|
|
||||||
else
|
|
||||||
CFLAGS += -pipe -Wall -O2 -D_GNU_SOURCE
|
|
||||||
endif
|
|
||||||
|
|
||||||
GLIBC_INCLUDES =
|
|
||||||
INCLUDES = -I. $($(L)_INCLUDES)
|
|
||||||
|
|
||||||
GCC_LIBDIR=$(shell dirname `gcc -print-libgcc-file-name`)
|
|
||||||
LIBGCC_A=$(shell gcc -print-libgcc-file-name)
|
|
||||||
|
|
||||||
GLIBC_LDFLAGS_STAGE1 = -static
|
|
||||||
DIETLIBC_LDFLAGS_STAGE1 = -nostdlib
|
|
||||||
# $(LIBGCC_A)
|
|
||||||
LDFLAGS_STAGE1 = $($(L)_LDFLAGS_STAGE1)
|
|
||||||
|
|
||||||
GLIBC_LIBC =
|
|
||||||
DIETLIBC_LIBC = $(DIET_LIBDIR)/libc.a $(DIET_LIBDIR)/libcompat.a
|
|
||||||
STAGE1_LIBC = $($(L)_LIBC)
|
|
||||||
|
|
||||||
STRIPCMD = strip -R .note -R .comment
|
|
6
adsl.c
6
adsl.c
@ -145,9 +145,9 @@ enum return_type perform_adsl(struct interface_info * intf)
|
|||||||
intf->boot_proto = BOOTPROTO_ADSL_PPPOE;
|
intf->boot_proto = BOOTPROTO_ADSL_PPPOE;
|
||||||
|
|
||||||
wait_message("Waiting for ADSL connection to show up...");
|
wait_message("Waiting for ADSL connection to show up...");
|
||||||
my_insmod("ppp_generic", ANY_DRIVER_TYPE, NULL);
|
my_insmod("ppp_generic", NULL);
|
||||||
my_insmod("ppp_async", ANY_DRIVER_TYPE, NULL);
|
my_insmod("ppp_async", NULL);
|
||||||
my_insmod("ppp", ANY_DRIVER_TYPE, NULL);
|
my_insmod("ppp", NULL);
|
||||||
results = adsl_connect(intf->device, answers[0], answers[1]);
|
results = adsl_connect(intf->device, answers[0], answers[1]);
|
||||||
remove_wait_message();
|
remove_wait_message();
|
||||||
|
|
||||||
|
10
cdrom.c
10
cdrom.c
@ -113,8 +113,8 @@ enum return_type cdrom_prepare(void)
|
|||||||
char * choice;
|
char * choice;
|
||||||
int i, count = 0;
|
int i, count = 0;
|
||||||
enum return_type results;
|
enum return_type results;
|
||||||
my_insmod("ide-cd", ANY_DRIVER_TYPE, NULL);
|
my_insmod("ide-cd", NULL);
|
||||||
my_insmod("sr_mod", ANY_DRIVER_TYPE, NULL);
|
my_insmod("sr_mod", NULL);
|
||||||
update_splash();
|
update_splash();
|
||||||
|
|
||||||
get_medias(CDROM, &medias, &medias_models);
|
get_medias(CDROM, &medias, &medias_models);
|
||||||
@ -127,7 +127,7 @@ enum return_type cdrom_prepare(void)
|
|||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
stg1_error_message("No CDROM device found.");
|
stg1_error_message("No CDROM device found.");
|
||||||
i = ask_insmod(MEDIA_ADAPTERS);
|
i = ask_insmod();
|
||||||
if (i == RETURN_BACK)
|
if (i == RETURN_BACK)
|
||||||
return RETURN_BACK;
|
return RETURN_BACK;
|
||||||
return cdrom_prepare();
|
return cdrom_prepare();
|
||||||
@ -137,7 +137,7 @@ enum return_type cdrom_prepare(void)
|
|||||||
results = try_with_device(*medias, *medias_models);
|
results = try_with_device(*medias, *medias_models);
|
||||||
if (results == RETURN_OK)
|
if (results == RETURN_OK)
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
i = ask_insmod(MEDIA_ADAPTERS);
|
i = ask_insmod();
|
||||||
if (i == RETURN_BACK)
|
if (i == RETURN_BACK)
|
||||||
return RETURN_BACK;
|
return RETURN_BACK;
|
||||||
return cdrom_prepare();
|
return cdrom_prepare();
|
||||||
@ -187,7 +187,7 @@ enum return_type cdrom_prepare(void)
|
|||||||
if (results == RETURN_BACK)
|
if (results == RETURN_BACK)
|
||||||
return cdrom_prepare();
|
return cdrom_prepare();
|
||||||
|
|
||||||
i = ask_insmod(MEDIA_ADAPTERS);
|
i = ask_insmod();
|
||||||
if (i == RETURN_BACK)
|
if (i == RETURN_BACK)
|
||||||
return RETURN_BACK;
|
return RETURN_BACK;
|
||||||
return cdrom_prepare();
|
return cdrom_prepare();
|
||||||
|
10
disk.c
10
disk.c
@ -282,8 +282,8 @@ enum return_type disk_prepare(void)
|
|||||||
int i, count = 0;
|
int i, count = 0;
|
||||||
enum return_type results;
|
enum return_type results;
|
||||||
|
|
||||||
my_insmod("ide-disk", ANY_DRIVER_TYPE, NULL);
|
my_insmod("ide-disk", NULL);
|
||||||
my_insmod("sd_mod", ANY_DRIVER_TYPE, NULL);
|
my_insmod("sd_mod", NULL);
|
||||||
get_medias(DISK, &medias, &medias_models);
|
get_medias(DISK, &medias, &medias_models);
|
||||||
|
|
||||||
ptr = medias;
|
ptr = medias;
|
||||||
@ -294,7 +294,7 @@ enum return_type disk_prepare(void)
|
|||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
stg1_error_message("No DISK drive found.");
|
stg1_error_message("No DISK drive found.");
|
||||||
i = ask_insmod(MEDIA_ADAPTERS);
|
i = ask_insmod();
|
||||||
if (i == RETURN_BACK)
|
if (i == RETURN_BACK)
|
||||||
return RETURN_BACK;
|
return RETURN_BACK;
|
||||||
return disk_prepare();
|
return disk_prepare();
|
||||||
@ -304,7 +304,7 @@ enum return_type disk_prepare(void)
|
|||||||
results = try_with_device(*medias);
|
results = try_with_device(*medias);
|
||||||
if (results == RETURN_OK)
|
if (results == RETURN_OK)
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
i = ask_insmod(MEDIA_ADAPTERS);
|
i = ask_insmod();
|
||||||
if (i == RETURN_BACK)
|
if (i == RETURN_BACK)
|
||||||
return RETURN_BACK;
|
return RETURN_BACK;
|
||||||
return disk_prepare();
|
return disk_prepare();
|
||||||
@ -319,7 +319,7 @@ enum return_type disk_prepare(void)
|
|||||||
results = try_with_device(choice);
|
results = try_with_device(choice);
|
||||||
if (results == RETURN_OK)
|
if (results == RETURN_OK)
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
i = ask_insmod(MEDIA_ADAPTERS);
|
i = ask_insmod();
|
||||||
if (i == RETURN_BACK)
|
if (i == RETURN_BACK)
|
||||||
return RETURN_BACK;
|
return RETURN_BACK;
|
||||||
return disk_prepare();
|
return disk_prepare();
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
(the dietlibc is a replacement for the glibc, which aim is to produce
|
|
||||||
smaller statically linked binaries)
|
|
||||||
|
|
||||||
|
|
||||||
The use for dietlibc in the stage1 was clear because currently used
|
|
||||||
install process on x86 is from a 1.44 Mbytes floppy. On this floppy we
|
|
||||||
need to fit the kernel, modules (scsi and network access), and the code to
|
|
||||||
do the basic things to load the stage2. The only part on which we could
|
|
||||||
progress was the code.
|
|
||||||
|
|
||||||
As always, figures demonstrate evidences. Here are the size of the
|
|
||||||
binaries used for the cdrom, disk, network and full floppy installs, using
|
|
||||||
newt as the UI library:
|
|
||||||
|
|
||||||
- with glibc
|
|
||||||
|
|
||||||
-rwxr-xr-x 1 gc gc 569448 May 15 15:29 stage1-cdrom
|
|
||||||
-rwxr-xr-x 1 gc gc 572264 May 15 15:29 stage1-disk
|
|
||||||
-rwxr-xr-x 1 gc gc 624712 May 15 15:30 stage1-network
|
|
||||||
-rwxr-xr-x 1 gc gc 720360 May 15 15:29 stage1-full
|
|
||||||
|
|
||||||
- with dietlibc
|
|
||||||
|
|
||||||
-rwxr-xr-x 1 gc gc 169332 May 15 14:26 stage1-cdrom
|
|
||||||
-rwxr-xr-x 1 gc gc 172180 May 15 14:26 stage1-disk
|
|
||||||
-rwxr-xr-x 1 gc gc 198612 May 15 14:26 stage1-network
|
|
||||||
-rwxr-xr-x 1 gc gc 251764 May 15 14:26 stage1-full
|
|
||||||
|
|
||||||
|
|
||||||
The `stage1-full' binary has code for many things, most notably: data
|
|
||||||
decrunching (bzlib), archive extraction (in-house format), module loading
|
|
||||||
(insmod from busybox), PCI detection, ide and scsi handling,
|
|
||||||
cdrom/disk/loopback mounting, DHCP client negociation (redhat+grub), NFS
|
|
||||||
mounting (util-linux), FTP and HTTP transmission (redhat), pcmcia
|
|
||||||
initializing (pcmcia-cs), UI interaction (slang/newt); with use of the
|
|
||||||
dietlibc, the binary is only 250 kbytes!
|
|
||||||
|
|
||||||
|
|
||||||
Due to the modular coding, it is also possible to choose to not use
|
|
||||||
slang/newt as the UI, but a stdio-only UI. In that case, the binaries get
|
|
||||||
even smaller:
|
|
||||||
|
|
||||||
-rwxr-xr-x 1 gc gc 104500 May 15 15:46 stage1-cdrom*
|
|
||||||
-rwxr-xr-x 1 gc gc 107348 May 15 15:46 stage1-disk*
|
|
||||||
-rwxr-xr-x 1 gc gc 133972 May 15 15:47 stage1-network*
|
|
||||||
-rwxr-xr-x 1 gc gc 187348 May 15 15:46 stage1-full*
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gc [Tue May 15 15:58:34 2001]
|
|
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Portions from Erik Troan (ewt@redhat.com)
|
|
||||||
*
|
|
||||||
* Copyright 1996 Red Hat Software
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/vfs.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#ifdef __LIBC_DIETLIBC__
|
|
||||||
#include <sys/i386-ioctl.h>
|
|
||||||
#endif
|
|
||||||
#include <sys/mount.h>
|
|
||||||
#include <linux/un.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <linux/unistd.h>
|
|
||||||
#include <sys/select.h>
|
|
||||||
|
|
||||||
#ifndef SOCK_STREAM
|
|
||||||
#define SOCK_STREAM 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline _syscall3(int, syslog, int, type, char *, bufp, int, len);
|
|
||||||
static inline _syscall3(int, reboot, int, magic, int, magic2, int, flag);
|
|
||||||
|
|
||||||
#ifdef __LIBC_DIETLIBC__
|
|
||||||
char ** environ = NULL;
|
|
||||||
#endif
|
|
275
init.c
275
init.c
@ -19,11 +19,18 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef INIT_HEADERS
|
#include <errno.h>
|
||||||
#include "init-libc-headers.h"
|
#include <string.h>
|
||||||
#else
|
#include <stdlib.h>
|
||||||
#include INIT_HEADERS
|
#include <stdio.h>
|
||||||
#endif
|
#include <unistd.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/klog.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/vfs.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include "config-stage1.h"
|
#include "config-stage1.h"
|
||||||
|
|
||||||
@ -31,9 +38,13 @@
|
|||||||
#define TIOCSCTTY 0x540
|
#define TIOCSCTTY 0x540
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MKDEV(ma,mi) ((ma)<<8 | (mi))
|
||||||
|
#define RAMFS_MAGIC 0x858458f6
|
||||||
|
#define TMPFS_MAGIC 0x01021994
|
||||||
|
|
||||||
char * env[] = {
|
char * env[] = {
|
||||||
"PATH=/usr/bin:/bin:/sbin:/usr/sbin:/usr/X11R6/bin",
|
"PATH=/usr/bin:/bin:/sbin:/usr/sbin",
|
||||||
"LD_LIBRARY_PATH=/lib:/usr/lib:/usr/X11R6/lib",
|
"LD_LIBRARY_PATH=/lib:/usr/lib",
|
||||||
"HOME=/",
|
"HOME=/",
|
||||||
"TERM=linux",
|
"TERM=linux",
|
||||||
"TERMINFO=/etc/terminfo",
|
"TERMINFO=/etc/terminfo",
|
||||||
@ -42,6 +53,11 @@ char * env[] = {
|
|||||||
|
|
||||||
char ** myenv = NULL;
|
char ** myenv = NULL;
|
||||||
|
|
||||||
|
char *stage[] = {"/sbin/stage1", NULL};
|
||||||
|
char *udevd[] = {"/sbin/udevd", NULL};
|
||||||
|
char *udevtrigger[] = {"/sbin/udevtrigger", NULL};
|
||||||
|
char *udevsettle[] = {"/sbin/udevsettle", NULL};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this needs to handle the following cases:
|
* this needs to handle the following cases:
|
||||||
*
|
*
|
||||||
@ -51,21 +67,14 @@ char ** myenv = NULL;
|
|||||||
* 4) run from a floppy that's been loaded into a ramdisk
|
* 4) run from a floppy that's been loaded into a ramdisk
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int klog_pid;
|
void fatal(const char *msg)
|
||||||
|
|
||||||
|
|
||||||
void fatal_error(const char *msg)
|
|
||||||
{
|
{
|
||||||
printf("FATAL ERROR IN INIT: %s : %s\n\nI can't recover from this, please reboot manually and send bugreport.\n", msg,strerror(errno));
|
printf("FATAL ERROR IN INIT: %s\nI can't recover from this,"
|
||||||
|
"please reboot manually and send bugreport.\n", msg);
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_error(char *msg)
|
void warn(char *msg)
|
||||||
{
|
|
||||||
printf("E: %s\n", msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_warning(char *msg)
|
|
||||||
{
|
{
|
||||||
printf("W: %s\n", msg);
|
printf("W: %s\n", msg);
|
||||||
}
|
}
|
||||||
@ -74,52 +83,50 @@ void print_warning(char *msg)
|
|||||||
* (1) watch /proc/kmsg and copy the stuff to /dev/tty4
|
* (1) watch /proc/kmsg and copy the stuff to /dev/tty4
|
||||||
* (2) listens to /dev/log and copy also this stuff (log from programs)
|
* (2) listens to /dev/log and copy also this stuff (log from programs)
|
||||||
*/
|
*/
|
||||||
void doklog()
|
pid_t doklog()
|
||||||
{
|
{
|
||||||
int in, out, i, ii;
|
int in, out, i, ii;
|
||||||
int log;
|
pid_t pid;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
|
||||||
/* open kernel message logger */
|
/* open kernel message logger */
|
||||||
in = open("/proc/kmsg", O_RDONLY,0);
|
if ((in = open("/proc/kmsg", O_RDONLY, 0)) < 0)
|
||||||
if (in < 0) {
|
fatal("failed to open /proc/kmsg");
|
||||||
print_error("could not open /proc/kmsg");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((log = open("/tmp/syslog", O_WRONLY | O_CREAT, 0644)) < 0) {
|
if (mknod("/dev/tty4", S_IFCHR, MKDEV(4, 4)) < 0 ||
|
||||||
perror("/tmp/syslog");
|
(out = open("/dev/tty4", O_WRONLY, 0)) < 0)
|
||||||
print_error("error opening /tmp/syslog");
|
fatal("failed to open /dev/tty4");
|
||||||
sleep(5);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((klog_pid = fork())) {
|
if ((pid = fork())) {
|
||||||
|
if (pid < 0) fatal("doklog");
|
||||||
close(in);
|
close(in);
|
||||||
close(log);
|
close(out);
|
||||||
return;
|
return pid;
|
||||||
} else {
|
|
||||||
close(0);
|
|
||||||
close(1);
|
|
||||||
close(2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out = open("/dev/tty4", O_WRONLY, 0);
|
/* child */
|
||||||
if (out < 0) {
|
close(0);
|
||||||
perror("can't open /dev/tty4");
|
close(1);
|
||||||
print_warning("couldn't open tty for syslog -- still using /tmp/syslog\n");
|
close(2);
|
||||||
}
|
|
||||||
|
|
||||||
/* disable on-console syslog output */
|
/* disable on-console syslog output */
|
||||||
syslog(8, NULL, 1);
|
klogctl(8, NULL, 1);
|
||||||
|
|
||||||
while (1) {
|
while (1)
|
||||||
i = read(in, buf, sizeof(buf));
|
if ((i = read(in, buf, sizeof(buf))) > 0)
|
||||||
if (i > 0) {
|
ii = write(out, buf, i);
|
||||||
if (out >= 0)
|
}
|
||||||
ii = write(out, buf, i);
|
|
||||||
ii = write(log, buf, i);
|
pid_t spawn(char *av[])
|
||||||
}
|
{
|
||||||
|
pid_t pid;
|
||||||
|
if ((pid = fork())) {
|
||||||
|
if (pid < 0) fatal(av[0]);
|
||||||
|
return pid;
|
||||||
|
} else {
|
||||||
|
execve(av[0], av, env);
|
||||||
|
perror(av[0]);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +138,7 @@ void grab_env(int fd)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ((i = read(fd, buf, sizeof(buf))) < 0) {
|
if ((i = read(fd, buf, sizeof(buf))) < 0) {
|
||||||
print_error("failed to read env from pipe");
|
warn("failed to read env from pipe");
|
||||||
myenv = env;
|
myenv = env;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -140,7 +147,7 @@ void grab_env(int fd)
|
|||||||
buf[i] = '\0';
|
buf[i] = '\0';
|
||||||
|
|
||||||
if ((ep = myenv = malloc(sizeof(char *) * 32)) == NULL) {
|
if ((ep = myenv = malloc(sizeof(char *) * 32)) == NULL) {
|
||||||
print_error("can't malloc env");
|
warn("can't malloc env");
|
||||||
myenv = env;
|
myenv = env;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -252,7 +259,7 @@ static int nuke(const char *what)
|
|||||||
|
|
||||||
if ( err ) {
|
if ( err ) {
|
||||||
errno = err;
|
errno = err;
|
||||||
fatal_error(what);
|
fatal(what);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -279,7 +286,7 @@ void unmount_filesystems(void)
|
|||||||
|
|
||||||
fd = open("/proc/mounts", O_RDONLY, 0);
|
fd = open("/proc/mounts", O_RDONLY, 0);
|
||||||
if (fd < 1) {
|
if (fd < 1) {
|
||||||
print_error("failed to open /proc/mounts");
|
warn("failed to open /proc/mounts");
|
||||||
sleep(2);
|
sleep(2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -332,66 +339,89 @@ void unmount_filesystems(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nb) {
|
if (nb) {
|
||||||
printf("failed to umount some filesystems\n");
|
fatal("failed to umount some filesystems\n");
|
||||||
while (1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAJOR(dev) ((dev)>>8)
|
|
||||||
#define MINOR(dev) ((dev) & 0xff)
|
|
||||||
#define MKDEV(ma,mi) ((ma)<<8 | (mi))
|
|
||||||
|
|
||||||
#define DEV_PERM 00400|00200|00040|00020
|
|
||||||
#define CHR_DEV 0020000|DEV_PERM
|
|
||||||
#define BLK_DEV 0060000|DEV_PERM
|
|
||||||
|
|
||||||
#define RAMFS_MAGIC 0x858458f6
|
|
||||||
#define TMPFS_MAGIC 0x01021994
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct stat rst, cst, ist;
|
struct stat rst, cst, ist;
|
||||||
struct statfs sfs;
|
struct statfs sfs;
|
||||||
pid_t installpid, childpid;
|
pid_t pid, klogpid, udevpid;
|
||||||
int wait_status;
|
int wait_status;
|
||||||
int fd;
|
int fd = -1;
|
||||||
int fds[2];
|
int fds[2];
|
||||||
int end_stage1 = 0;
|
|
||||||
|
|
||||||
if (mount("/proc", "/proc", "proc", 0, NULL))
|
if (mount("/proc", "/proc", "proc", 0, NULL))
|
||||||
fatal_error("Unable to mount proc filesystem");
|
fatal("failed to mount proc filesystem");
|
||||||
if (mount("/sysfs", "/sys", "sysfs", 0, NULL))
|
if (mount("sysfs", "/sys", "sysfs", 0, NULL))
|
||||||
fatal_error("Unable to mount sysfs filesystem");
|
fatal("failed to mount sysfs filesystem");
|
||||||
|
if (mount("udev", "/dev", "tmpfs", 0, "size=10M,mode=0755"))
|
||||||
|
fatal("failed to mount tmpfs filesystem");
|
||||||
|
|
||||||
/* ignore Control-C and keyboard stop signals */
|
/* ignore Control-C and keyboard stop signals */
|
||||||
signal(SIGINT, SIG_IGN);
|
signal(SIGINT, SIG_IGN);
|
||||||
signal(SIGTSTP, SIG_IGN);
|
signal(SIGTSTP, SIG_IGN);
|
||||||
|
|
||||||
fd = open("/dev/console", O_RDWR, 0);
|
if (mknod("/dev/console", S_IFCHR, MKDEV(5, 1)) < 0 ||
|
||||||
if (fd < 0)
|
(fd = open("/dev/console", O_RDWR, 0)) < 0) {
|
||||||
fatal_error("failed to open /dev/console");
|
fatal("failed to open /dev/console");
|
||||||
|
}
|
||||||
|
|
||||||
dup2(fd, 0);
|
dup2(fd, 0);
|
||||||
dup2(fd, 1);
|
dup2(fd, 1);
|
||||||
dup2(fd, 2);
|
dup2(fd, 2);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
if (mknod("/dev/null", S_IFCHR, MKDEV(1, 3)) < 0)
|
||||||
|
fatal("failed to create /dev/null");
|
||||||
|
|
||||||
/* I set me up as session leader (probably not necessary?) */
|
/* I set me up as session leader (probably not necessary?) */
|
||||||
setsid();
|
setsid();
|
||||||
if (ioctl(0, TIOCSCTTY, NULL)) {
|
if (ioctl(0, TIOCSCTTY, NULL)) {
|
||||||
perror("TIOCSCTTY");
|
perror("TIOCSCTTY");
|
||||||
print_error("could not set new controlling tty");
|
warn("could not set new controlling tty");
|
||||||
}
|
}
|
||||||
|
|
||||||
char my_hostname[] = "localhost.localdomain";
|
if (sethostname("localhost.localdomain", sizeof("localhost.localdomain")) < 0)
|
||||||
if (sethostname(my_hostname, sizeof(my_hostname)) < 0)
|
warn("could not set hostname");
|
||||||
print_error("could not set hostname");
|
|
||||||
|
|
||||||
/* the default domainname (as of 2.0.35) is "(none)", which confuses glibc */
|
/* the default domainname (as of 2.0.35) is "(none)", which confuses glibc */
|
||||||
if (setdomainname("", 0) < 0)
|
if (setdomainname("", 0) < 0)
|
||||||
print_error("could not set domainname");
|
warn("could not set domainname");
|
||||||
|
|
||||||
doklog();
|
if (mkdir("/dev/.initramfs", 0755) < 0 ||
|
||||||
|
mkdir("/dev/pts", 0755) < 0 ||
|
||||||
|
mkdir("/dev/shm", 0755) < 0)
|
||||||
|
fatal("mkdir\n");
|
||||||
|
|
||||||
|
if ((fd = open("/proc/sys/kernel/hotplug", O_WRONLY, 0)) < 0 ||
|
||||||
|
write(fd, "\n", sizeof("\n")) < sizeof("\n"))
|
||||||
|
fatal("/proc/sys/kernel/hotplug\n");
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
klogpid = doklog();
|
||||||
|
|
||||||
|
if (mkdir("/dev/.udev", 0755) < 0 ||
|
||||||
|
mkdir("/dev/.udev/db", 0755) < 0)
|
||||||
|
fatal("/dev/.udev/db");
|
||||||
|
|
||||||
|
printf("Spawning udevd...");
|
||||||
|
|
||||||
|
udevpid = spawn(udevd);
|
||||||
|
|
||||||
|
if (mkdir("/dev/.udev/queue", 0755) < 0 && errno != EEXIST)
|
||||||
|
fatal("cannot create /dev/.udev/queue");
|
||||||
|
|
||||||
|
if (waitpid(spawn(udevtrigger), &wait_status, 0) < 0 ||
|
||||||
|
!(WIFEXITED(wait_status)))
|
||||||
|
warn("udevtrigger");
|
||||||
|
|
||||||
|
if (waitpid(spawn(udevsettle), &wait_status, 0) < 0 ||
|
||||||
|
!(WIFEXITED(wait_status)))
|
||||||
|
warn("udevsettle");
|
||||||
|
|
||||||
|
printf("done\n");
|
||||||
|
|
||||||
/* Go into normal init mode - keep going, and then do a orderly shutdown
|
/* Go into normal init mode - keep going, and then do a orderly shutdown
|
||||||
when:
|
when:
|
||||||
@ -404,33 +434,19 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* create a pipe for env passing */
|
/* create a pipe for env passing */
|
||||||
if (pipe(fds) < 0)
|
if (pipe(fds) < 0)
|
||||||
fatal_error("failed to create env pipe");
|
fatal("failed to create env pipe");
|
||||||
|
|
||||||
fcntl(fds[0], F_SETFD, 1);
|
fcntl(fds[0], F_SETFD, 1);
|
||||||
fcntl(fds[1], F_SETFD, 0);
|
fcntl(fds[1], F_SETFD, 0);
|
||||||
|
|
||||||
if (!(installpid = fork())) {
|
pid = spawn(stage);
|
||||||
/* child */
|
|
||||||
char * child_argv[2];
|
|
||||||
child_argv[0] = "/sbin/stage1";
|
|
||||||
child_argv[1] = NULL;
|
|
||||||
execve(child_argv[0], child_argv, env);
|
|
||||||
printf("error in exec of stage1 :-(\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(fds[1]);
|
close(fds[1]);
|
||||||
|
while (pid != wait(&wait_status));
|
||||||
while (!end_stage1) {
|
|
||||||
childpid = wait4(-1, &wait_status, 0, NULL);
|
|
||||||
if (childpid == installpid)
|
|
||||||
end_stage1 = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(WIFEXITED(wait_status))) {
|
if (!(WIFEXITED(wait_status))) {
|
||||||
/* something went wrong */
|
/* something went wrong */
|
||||||
|
|
||||||
printf("wait_status: %i, install exited abnormally :-( ", wait_status);
|
printf("wait_status: %i, install exited abnormally ", wait_status);
|
||||||
if (WIFSIGNALED(wait_status))
|
if (WIFSIGNALED(wait_status))
|
||||||
printf("-- received signal %d", WTERMSIG(wait_status));
|
printf("-- received signal %d", WTERMSIG(wait_status));
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@ -455,15 +471,23 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
grab_env(fds[0]);
|
grab_env(fds[0]);
|
||||||
|
|
||||||
kill(klog_pid, 9);
|
if (waitpid(spawn(udevsettle), &wait_status, 0) < 0 ||
|
||||||
waitpid(klog_pid, &wait_status, 0);
|
!(WIFEXITED(wait_status)))
|
||||||
|
warn("udevsettle");
|
||||||
|
|
||||||
|
kill(udevpid, 9);
|
||||||
|
waitpid(udevpid, &wait_status, 0);
|
||||||
|
nuke_dir("/dev/.udev/queue");
|
||||||
|
|
||||||
|
kill(klogpid, 9);
|
||||||
|
waitpid(klogpid, &wait_status, 0);
|
||||||
|
|
||||||
printf("Spawning init ...");
|
printf("Spawning init ...");
|
||||||
|
|
||||||
/* rest was seamlessy stolen from klibc */
|
/* rest was seamlessy stolen from klibc */
|
||||||
/* First, change to the new root directory */
|
/* First, change to the new root directory */
|
||||||
if (chdir(STAGE2_LOCATION))
|
if (chdir(STAGE2_LOCATION))
|
||||||
fatal_error("chdir to new root");
|
fatal("chdir to new root");
|
||||||
|
|
||||||
/* This is a potentially highly destructive program. Take some
|
/* This is a potentially highly destructive program. Take some
|
||||||
extra precautions. */
|
extra precautions. */
|
||||||
@ -471,71 +495,66 @@ int main(int argc, char **argv)
|
|||||||
/* Make sure the current directory is not on the same filesystem
|
/* Make sure the current directory is not on the same filesystem
|
||||||
as the root directory */
|
as the root directory */
|
||||||
if ( stat("/", &rst) || stat(".", &cst) )
|
if ( stat("/", &rst) || stat(".", &cst) )
|
||||||
fatal_error("stat");
|
fatal("stat");
|
||||||
|
|
||||||
if ( rst.st_dev == cst.st_dev )
|
if ( rst.st_dev == cst.st_dev )
|
||||||
fatal_error("current directory on the same filesystem as the root");
|
fatal("current directory on the same filesystem as the root");
|
||||||
|
|
||||||
/* The initramfs should have /init */
|
/* The initramfs should have /init */
|
||||||
if ( stat("/init", &ist) || !S_ISREG(ist.st_mode) )
|
if ( stat("/init", &ist) || !S_ISREG(ist.st_mode) )
|
||||||
fatal_error("can't find /init on initramfs");
|
fatal("can't find /init on initramfs");
|
||||||
|
|
||||||
/* Make sure we're on a ramfs */
|
/* Make sure we're on a ramfs */
|
||||||
if ( statfs("/", &sfs) )
|
if ( statfs("/", &sfs) )
|
||||||
fatal_error("statfs /");
|
fatal("statfs /");
|
||||||
if ( sfs.f_type != RAMFS_MAGIC && sfs.f_type != TMPFS_MAGIC )
|
if ( sfs.f_type != RAMFS_MAGIC && sfs.f_type != TMPFS_MAGIC )
|
||||||
fatal_error("rootfs not a ramfs or tmpfs");
|
fatal("rootfs not a ramfs or tmpfs");
|
||||||
|
|
||||||
/* Okay, I think we should be safe... */
|
/* Okay, I think we should be safe... */
|
||||||
|
|
||||||
/* overmount image under new root if needed */
|
/* overmount image under new root if needed */
|
||||||
if ( statfs(IMAGE_LOCATION, &sfs) )
|
if ( statfs(IMAGE_LOCATION, &sfs) )
|
||||||
fatal_error("statfs "IMAGE_LOCATION);
|
fatal("statfs "IMAGE_LOCATION);
|
||||||
/* if something is mounted under IMAGE_LOCATION ? */
|
/* if something is mounted under IMAGE_LOCATION ? */
|
||||||
if ( sfs.f_type != RAMFS_MAGIC && sfs.f_type != TMPFS_MAGIC ) {
|
if ( sfs.f_type != RAMFS_MAGIC && sfs.f_type != TMPFS_MAGIC ) {
|
||||||
if ( mount(IMAGE_LOCATION, "." IMAGE_LOCATION, NULL, MS_MOVE, NULL) )
|
if ( mount(IMAGE_LOCATION, "." IMAGE_LOCATION, NULL, MS_MOVE, NULL) )
|
||||||
fatal_error("overmounting image location");
|
fatal("overmounting image location");
|
||||||
/* test for nested mount: disk or nfs with iso image */
|
/* test for nested mount: disk or nfs with iso image */
|
||||||
if ( statfs(IMAGE_LOCATION, &sfs) )
|
if ( statfs(IMAGE_LOCATION, &sfs) )
|
||||||
fatal_error("nested statfs "IMAGE_LOCATION);
|
fatal("nested statfs "IMAGE_LOCATION);
|
||||||
if ( sfs.f_type != RAMFS_MAGIC && sfs.f_type != TMPFS_MAGIC )
|
if ( sfs.f_type != RAMFS_MAGIC && sfs.f_type != TMPFS_MAGIC )
|
||||||
if ( mount(IMAGE_LOCATION, "." IMAGE_LOCATION "/isolinux", NULL, MS_MOVE, NULL) )
|
if ( mount(IMAGE_LOCATION, "." IMAGE_LOCATION "/isolinux", NULL, MS_MOVE, NULL) )
|
||||||
fatal_error("overmounting nested image location");
|
fatal("overmounting nested image location");
|
||||||
}
|
}
|
||||||
|
|
||||||
umount("/sys");
|
umount("/sys");
|
||||||
umount("/proc/bus/usb");
|
umount("/proc/bus/usb");
|
||||||
umount("/proc");
|
umount("/proc");
|
||||||
|
|
||||||
|
if (mount("/dev", "./dev", NULL, MS_MOVE, NULL))
|
||||||
|
fatal("overmounting /dev");
|
||||||
|
|
||||||
/* Delete rootfs contents */
|
/* Delete rootfs contents */
|
||||||
if ( nuke_dir("/") )
|
if (nuke_dir("/"))
|
||||||
fatal_error("nuking initramfs contents");
|
fatal("nuking initramfs contents");
|
||||||
|
|
||||||
/* Overmount the root */
|
/* Overmount the root */
|
||||||
if ( mount(".", "/", NULL, MS_MOVE, NULL) )
|
if (mount(".", "/", NULL, MS_MOVE, NULL))
|
||||||
fatal_error("overmounting root");
|
fatal("overmounting root");
|
||||||
|
|
||||||
/* chroot, chdir */
|
/* chroot, chdir */
|
||||||
if (chroot(".") || chdir("/"))
|
if (chroot(".") || chdir("/"))
|
||||||
fatal_error("chroot");
|
fatal("chroot");
|
||||||
|
|
||||||
/* Open /dev/console */
|
|
||||||
if ((fd = open("/dev/console", O_RDWR)) != -1) {
|
|
||||||
dup2(fd, 0);
|
|
||||||
dup2(fd, 1);
|
|
||||||
dup2(fd, 2);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for given init */
|
/* Check for given init */
|
||||||
if (stat(STAGE2_BINNAME, &ist) || !S_ISREG(ist.st_mode))
|
if (stat(STAGE2_BINNAME, &ist) || !S_ISREG(ist.st_mode))
|
||||||
fatal_error("can't find init on root fs");
|
fatal("can't find init on root fs");
|
||||||
|
|
||||||
/* Spawn init */
|
/* Spawn init */
|
||||||
printf(" done.\n");
|
printf(" done.\n");
|
||||||
|
|
||||||
argv[0] = STAGE2_BINNAME;
|
argv[0] = STAGE2_BINNAME;
|
||||||
execve(argv[0], argv, myenv);
|
execve(argv[0], argv, myenv);
|
||||||
fatal_error("stage2"); /* Failed to spawn init */
|
fatal("stage2"); /* Failed to spawn init */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -63,14 +63,15 @@ int
|
|||||||
set_loop (const char *device, const char *file)
|
set_loop (const char *device, const char *file)
|
||||||
{
|
{
|
||||||
struct loop_info loopinfo;
|
struct loop_info loopinfo;
|
||||||
int fd, ffd, mode;
|
int i, fd, ffd, mode;
|
||||||
|
|
||||||
mode = O_RDONLY;
|
mode = O_RDONLY;
|
||||||
|
|
||||||
if ((ffd = open (file, mode)) < 0)
|
if ((ffd = open (file, mode)) < 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if ((fd = open (device, mode)) < 0) {
|
for (i=3; i && (fd = open(device, mode)) < 0; --i, sleep(1));
|
||||||
|
if (fd < 0) {
|
||||||
close(ffd);
|
close(ffd);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -139,7 +140,7 @@ lomount(char *loopfile, char *where)
|
|||||||
flag = MS_MGC_VAL;
|
flag = MS_MGC_VAL;
|
||||||
flag |= MS_RDONLY;
|
flag |= MS_RDONLY;
|
||||||
|
|
||||||
my_insmod("loop", ANY_DRIVER_TYPE, NULL);
|
my_insmod("loop", NULL);
|
||||||
|
|
||||||
if (set_loop(loopdev, loopfile)) {
|
if (set_loop(loopdev, loopfile)) {
|
||||||
log_message("set_loop failed on %s (%s)", loopdev, strerror(errno));
|
log_message("set_loop failed on %s (%s)", loopdev, strerror(errno));
|
||||||
|
251
minilibc.c
251
minilibc.c
@ -1,251 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Portions from Erik Troan (ewt@redhat.com)
|
|
||||||
*
|
|
||||||
* Copyright 1996 Red Hat Software
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define MINILIBC_INTERNAL
|
|
||||||
|
|
||||||
#include "minilibc.h"
|
|
||||||
|
|
||||||
int atexit (void (*__func) (void))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void exit()
|
|
||||||
{
|
|
||||||
_do_exit(0);
|
|
||||||
for (;;); /* Shut up gcc */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char ** _environ = NULL;
|
|
||||||
int errno = 0;
|
|
||||||
|
|
||||||
void _init (int __status)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void __libc_init_first (int __status)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int __libc_start_main (int (*main) (int, char **, char **), int argc,
|
|
||||||
char **argv, void (*init) (void), void (*fini) (void),
|
|
||||||
void (*rtld_fini) (void), void *stack_end)
|
|
||||||
{
|
|
||||||
exit ((*main) (argc, argv, NULL));
|
|
||||||
/* never get here */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _fini (int __status)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int socket(int a, int b, int c)
|
|
||||||
{
|
|
||||||
unsigned long args[] = { a, b, c };
|
|
||||||
|
|
||||||
return socketcall(SYS_SOCKET, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int bind(int a, void * b, int c)
|
|
||||||
{
|
|
||||||
unsigned long args[] = { a, (long) b, c };
|
|
||||||
|
|
||||||
return socketcall(SYS_BIND, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int listen(int a, int b)
|
|
||||||
{
|
|
||||||
unsigned long args[] = { a, b, 0 };
|
|
||||||
|
|
||||||
return socketcall(SYS_LISTEN, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int accept(int a, void * addr, void * addr2)
|
|
||||||
{
|
|
||||||
unsigned long args[] = { a, (long) addr, (long) addr2 };
|
|
||||||
|
|
||||||
return socketcall(SYS_ACCEPT, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void sleep(int secs)
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
tv.tv_sec = secs;
|
|
||||||
tv.tv_usec = 0;
|
|
||||||
|
|
||||||
select(0, NULL, NULL, NULL, &tv);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int strlen(const char * string)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while (*string++) i++;
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * strncpy(char * dst, const char * src, int len)
|
|
||||||
{
|
|
||||||
char * chptr = dst;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
while (*src && i < len) *dst++ = *src++, i++;
|
|
||||||
if (i < len) *dst = '\0';
|
|
||||||
|
|
||||||
return chptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
char * strcpy(char * dst, const char * src)
|
|
||||||
{
|
|
||||||
char * chptr = dst;
|
|
||||||
|
|
||||||
while (*src) *dst++ = *src++;
|
|
||||||
*dst = '\0';
|
|
||||||
|
|
||||||
return chptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void * memcpy(void * dst, const void * src, size_t count)
|
|
||||||
{
|
|
||||||
char * a = dst;
|
|
||||||
const char * b = src;
|
|
||||||
|
|
||||||
while (count--)
|
|
||||||
*a++ = *b++;
|
|
||||||
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int strcmp(const char * a, const char * b)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
i = strlen(a); j = strlen(b);
|
|
||||||
if (i < j)
|
|
||||||
return -1;
|
|
||||||
else if (j < i)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
while (*a && (*a == *b)) a++, b++;
|
|
||||||
|
|
||||||
if (!*a) return 0;
|
|
||||||
|
|
||||||
if (*a < *b)
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int strncmp(const char * a, const char * b, int len)
|
|
||||||
{
|
|
||||||
char buf1[1000], buf2[1000];
|
|
||||||
|
|
||||||
strncpy(buf1, a, len);
|
|
||||||
strncpy(buf2, b, len);
|
|
||||||
buf1[len] = '\0';
|
|
||||||
buf2[len] = '\0';
|
|
||||||
|
|
||||||
return strcmp(buf1, buf2);
|
|
||||||
}
|
|
||||||
|
|
||||||
char * strchr(char * str, int ch)
|
|
||||||
{
|
|
||||||
char * chptr;
|
|
||||||
|
|
||||||
chptr = str;
|
|
||||||
while (*chptr)
|
|
||||||
{
|
|
||||||
if (*chptr == ch) return chptr;
|
|
||||||
chptr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char * strstr(char *haystack, char *needle)
|
|
||||||
{
|
|
||||||
char * tmp = haystack;
|
|
||||||
while ((tmp = strchr(tmp, needle[0])) != NULL) {
|
|
||||||
int i = 1;
|
|
||||||
while (i < strlen(tmp) && i < strlen(needle) && tmp[i] == needle[i])
|
|
||||||
i++;
|
|
||||||
if (needle[i] == '\0')
|
|
||||||
return tmp;
|
|
||||||
tmp++;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Minimum printf which handles only characters, %d's and %s's */
|
|
||||||
void printf(char * fmt, ...)
|
|
||||||
{
|
|
||||||
char buf[2048];
|
|
||||||
char * start = buf;
|
|
||||||
char * chptr = buf;
|
|
||||||
va_list args;
|
|
||||||
char * strarg;
|
|
||||||
int numarg;
|
|
||||||
|
|
||||||
strncpy(buf, fmt, sizeof(buf));
|
|
||||||
va_start(args, fmt);
|
|
||||||
|
|
||||||
while (start)
|
|
||||||
{
|
|
||||||
while (*chptr != '%' && *chptr) chptr++;
|
|
||||||
|
|
||||||
if (*chptr == '%')
|
|
||||||
{
|
|
||||||
*chptr++ = '\0';
|
|
||||||
print_str_init(1, start);
|
|
||||||
|
|
||||||
switch (*chptr++)
|
|
||||||
{
|
|
||||||
case 's':
|
|
||||||
strarg = va_arg(args, char *);
|
|
||||||
print_str_init(1, strarg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'd':
|
|
||||||
numarg = va_arg(args, int);
|
|
||||||
print_int_init(1, numarg);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
start = chptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
print_str_init(1, start);
|
|
||||||
start = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
144
minilibc.h
144
minilibc.h
@ -1,144 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Portions from Erik Troan (ewt@redhat.com)
|
|
||||||
*
|
|
||||||
* Copyright 1996 Red Hat Software
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#define _LOOSE_KERNEL_NAMES 1
|
|
||||||
|
|
||||||
#define NULL ((void *) 0)
|
|
||||||
|
|
||||||
#define WIFSTOPPED(status) (((status) & 0xff) == 0x7f)
|
|
||||||
#define WIFSIGNALED(status) (!WIFSTOPPED(status) && !WIFEXITED(status))
|
|
||||||
#define WEXITSTATUS(status) (((status) & 0xff00) >> 8)
|
|
||||||
#define WTERMSIG(status) ((status) & 0x7f)
|
|
||||||
#define WSTOPSIG(status) WEXITSTATUS(status)
|
|
||||||
#define WIFEXITED(status) (WTERMSIG(status) == 0)
|
|
||||||
|
|
||||||
#define MS_MGC_VAL 0xc0ed0000
|
|
||||||
|
|
||||||
#define isspace(a) (a == ' ' || a == '\t')
|
|
||||||
|
|
||||||
extern char ** _environ;
|
|
||||||
|
|
||||||
extern int errno;
|
|
||||||
|
|
||||||
/* Aieee, gcc 2.95+ creates a stub for posix_types.h on i386 which brings
|
|
||||||
glibc headers in and thus makes __FD_SET etc. not defined with 2.3+ kernels. */
|
|
||||||
#define _FEATURES_H 1
|
|
||||||
#include <linux/socket.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <linux/time.h>
|
|
||||||
#include <linux/if.h>
|
|
||||||
#include <linux/un.h>
|
|
||||||
#include <linux/loop.h>
|
|
||||||
#include <linux/net.h>
|
|
||||||
#include <asm/posix_types.h>
|
|
||||||
#include <asm/termios.h>
|
|
||||||
#include <asm/ioctls.h>
|
|
||||||
#include <asm/unistd.h>
|
|
||||||
#include <asm/fcntl.h>
|
|
||||||
#include <asm/signal.h>
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef MINILIBC_INTERNAL
|
|
||||||
static inline _syscall5(int,mount,const char *,spec,const char *,dir,const char *,type,unsigned long,rwflag,const void *,data);
|
|
||||||
static inline _syscall5(int,_newselect,int,n,fd_set *,rd,fd_set *,wr,fd_set *,ex,struct timeval *,timeval);
|
|
||||||
static inline _syscall4(int,wait4,pid_t,pid,int *,status,int,opts,void *,rusage)
|
|
||||||
static inline _syscall3(int,write,int,fd,const char *,buf,unsigned long,count)
|
|
||||||
static inline _syscall3(int,reboot,int,magic,int,magic_too,int,flag)
|
|
||||||
static inline _syscall3(int,execve,const char *,fn,void *,argv,void *,envp)
|
|
||||||
static inline _syscall3(int,read,int,fd,const char *,buf,unsigned long,count)
|
|
||||||
static inline _syscall3(int,open,const char *,fn,int,flags,mode_t,mode)
|
|
||||||
static inline _syscall3(int,ioctl,int,fd,int,request,void *,argp)
|
|
||||||
static inline _syscall2(int,dup2,int,one,int,two)
|
|
||||||
static inline _syscall2(int,kill,pid_t,pid,int,sig)
|
|
||||||
static inline _syscall2(int,symlink,const char *,a,const char *,b)
|
|
||||||
static inline _syscall2(int,chmod,const char * ,path,mode_t,mode)
|
|
||||||
static inline _syscall2(int,sethostname,const char *,name,int,len)
|
|
||||||
static inline _syscall2(int,setdomainname,const char *,name,int,len)
|
|
||||||
static inline _syscall2(int,setpgid,int,name,int,len)
|
|
||||||
static inline _syscall2(int,signal,int,num,void *,len)
|
|
||||||
static inline _syscall1(int,umount,const char *,dir)
|
|
||||||
static inline _syscall1(int,unlink,const char *,fn)
|
|
||||||
static inline _syscall1(int,close,int,fd)
|
|
||||||
static inline _syscall1(int,swapoff,const char *,fn)
|
|
||||||
static inline _syscall0(int,getpid)
|
|
||||||
static inline _syscall0(int,sync)
|
|
||||||
#ifdef __sparc__
|
|
||||||
/* Nonstandard fork calling convention :( */
|
|
||||||
static inline int fork(void) {
|
|
||||||
int __res;
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
"mov %0, %%g1\n\t"
|
|
||||||
"t 0x10\n\t"
|
|
||||||
"bcc 1f\n\t"
|
|
||||||
"dec %%o1\n\t"
|
|
||||||
"sethi %%hi(%2), %%g1\n\t"
|
|
||||||
"st %%o0, [%%g1 + %%lo(%2)]\n\t"
|
|
||||||
"b 2f\n\t"
|
|
||||||
"mov -1, %0\n\t"
|
|
||||||
"1:\n\t"
|
|
||||||
"and %%o0, %%o1, %0\n\t"
|
|
||||||
"2:\n\t"
|
|
||||||
: "=r" (__res)
|
|
||||||
: "0" (__NR_fork), "i" (&errno)
|
|
||||||
: "g1", "o0", "cc");
|
|
||||||
return __res;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static inline _syscall0(int,fork)
|
|
||||||
#endif
|
|
||||||
static inline _syscall0(pid_t,setsid)
|
|
||||||
static inline _syscall3(int,syslog,int, type, char *, buf, int, len);
|
|
||||||
#else
|
|
||||||
static inline _syscall5(int,_newselect,int,n,fd_set *,rd,fd_set *,wr,fd_set *,ex,struct timeval *,timeval);
|
|
||||||
static inline _syscall3(int,write,int,fd,const char *,buf,unsigned long,count)
|
|
||||||
static inline _syscall2(int,socketcall,int,code,unsigned long *, args)
|
|
||||||
#define __NR__do_exit __NR_exit
|
|
||||||
extern inline _syscall1(int,_do_exit,int,exitcode)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define select _newselect
|
|
||||||
|
|
||||||
extern int errno;
|
|
||||||
|
|
||||||
inline int socket(int a, int b, int c);
|
|
||||||
inline int bind(int a, void * b, int c);
|
|
||||||
inline int listen(int a, int b);
|
|
||||||
inline int accept(int a, void * addr, void * addr2);
|
|
||||||
|
|
||||||
void sleep(int secs);
|
|
||||||
|
|
||||||
int strlen(const char * string);
|
|
||||||
char * strcpy(char * dst, const char * src);
|
|
||||||
void * memcpy(void * dst, const void * src, size_t count);
|
|
||||||
int strcmp(const char * a, const char * b);
|
|
||||||
int strncmp(const char * a, const char * b, int len);
|
|
||||||
char * strchr(char * str, int ch);
|
|
||||||
char * strstr(char *haystack, char *needle);
|
|
||||||
char * strncpy(char * dst, const char * src, int len);
|
|
||||||
|
|
||||||
void print_str_init(int fd, char * string);
|
|
||||||
void print_int_init(int fd, int i);
|
|
||||||
/* Minimum printf which handles only characters, %d's and %s's */
|
|
||||||
void printf(char * fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
|
||||||
|
|
62
mkinitfs
Executable file
62
mkinitfs
Executable file
@ -0,0 +1,62 @@
|
|||||||
|
#!/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 <<EOF
|
||||||
|
dir /dev 0755 0 0
|
||||||
|
dir /image 0755 0 0
|
||||||
|
dir /proc 0755 0 0
|
||||||
|
dir /sys 0755 0 0
|
||||||
|
dir /root 0755 0 0
|
||||||
|
dir /tmp 0755 0 0
|
||||||
|
dir /var 0755 0 0
|
||||||
|
dir /var/lock 0755 0 0
|
||||||
|
|
||||||
|
dir /etc 0755 0 0
|
||||||
|
dir /etc/modprobe.d 0755 0 0
|
||||||
|
|
||||||
|
dir /etc/terminfo 0755 0 0
|
||||||
|
dir /etc/terminfo/l 0755 0 0
|
||||||
|
file /etc/terminfo/l/linux /lib/terminfo/l/linux 0644 0 0
|
||||||
|
|
||||||
|
dir /etc/udev 0755 0 0
|
||||||
|
dir /etc/udev/rules.d 0755 0 0
|
||||||
|
|
||||||
|
dir /lib 0755 0 0
|
||||||
|
dir /lib/udev 0755 0 0
|
||||||
|
|
||||||
|
dir /bin 0755 0 0
|
||||||
|
file /bin/sh /lib/mkinitrd/busybox 0755 0 0
|
||||||
|
|
||||||
|
dir /sbin 0755 0 0
|
||||||
|
file /sbin/modprobe /lib/mkinitrd/module-init-tools/sbin/modprobe 0755 0 0
|
||||||
|
file /sbin/stage1 stage1 0755 0 0
|
||||||
|
|
||||||
|
file /init init 0755 0 0
|
||||||
|
EOF
|
||||||
|
|
||||||
|
find /lib/mkinitrd/klibc/lib -xtype f|\
|
||||||
|
sed -e 's,/lib/mkinitrd/klibc,,' -e 's,^.\+$,file\t&\t/lib/mkinitrd/klibc&\t0755\t0 0,g'
|
||||||
|
find /lib/mkinitrd/udev -type f|\
|
||||||
|
sed -e 's,/lib/mkinitrd/udev,,' -e 's,^.\+$,file\t&\t/lib/mkinitrd/udev&\t0755\t0 0,g'
|
||||||
|
find /etc/modprobe.d/ /etc/udev/rules.d -type f|\
|
||||||
|
sed -e 's,^.\+$,file\t&\t&\t0644\t0 0,g'
|
||||||
|
) | `pwd`/gencpio - |gzip -c > $out
|
300
modules.c
300
modules.c
@ -21,6 +21,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -28,25 +29,12 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef CONFIG_USE_ZLIB
|
|
||||||
#include <zlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "stage1.h"
|
#include "stage1.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "frontend.h"
|
#include "frontend.h"
|
||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
#include "modules_descr.h"
|
|
||||||
#include "modules.h"
|
#include "modules.h"
|
||||||
|
|
||||||
extern int mar_extract_inplace(char *, const char *, void **, int *);
|
|
||||||
extern char ** mar_list_contents(char *);
|
|
||||||
|
|
||||||
static struct module_deps_elem * modules_deps = NULL;
|
|
||||||
|
|
||||||
static char * archive_name = "/modules/modules.mar";
|
|
||||||
int disable_modules = 0;
|
|
||||||
|
|
||||||
static const char *moderror(int err)
|
static const char *moderror(int err)
|
||||||
{
|
{
|
||||||
switch (err) {
|
switch (err) {
|
||||||
@ -108,295 +96,45 @@ int insmod_call(char *pathname, char *params)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum insmod_return insmod_archived_file(const char * mod_name, char * options)
|
static enum insmod_return modprobe(const char * mod_name, char * options)
|
||||||
{
|
{
|
||||||
void *file;
|
int pid, status;
|
||||||
char module_name[50];
|
if (!(pid = fork())) {
|
||||||
int len, i, rc;
|
char * argv[4];
|
||||||
|
argv[0] = "/sbin/modprobe";
|
||||||
strncpy(module_name, mod_name, sizeof(module_name));
|
argv[1] = mod_name;
|
||||||
strcat(module_name, ".ko");
|
argv[2] = options;
|
||||||
i = mar_extract_inplace(archive_name, module_name, &file, &len);
|
argv[3] = NULL;
|
||||||
if (i == 1) {
|
execve(argv[0], argv, NULL);
|
||||||
log_message("file-not-found-in-archive %s", module_name);
|
log_message("modprobe %s failed", mod_name);
|
||||||
return INSMOD_FAILED_FILE_NOT_FOUND;
|
|
||||||
}
|
}
|
||||||
if (i != 0)
|
waitpid(pid, &status, 0);
|
||||||
return INSMOD_FAILED;
|
return WIFEXITED(status) ? INSMOD_OK : INSMOD_FAILED;
|
||||||
|
|
||||||
rc = init_module(file, len, options == NULL ? "" : options);
|
|
||||||
free(file);
|
|
||||||
if (rc != 0 && errno != EEXIST) {
|
|
||||||
log_message("init_module: '%s': %s", module_name, moderror(errno));
|
|
||||||
return INSMOD_FAILED;
|
|
||||||
}
|
|
||||||
return INSMOD_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int load_modules_dependencies(void)
|
enum insmod_return my_insmod(const char * mod_name, char * options)
|
||||||
{
|
{
|
||||||
char * deps_file = "/modules/modules.dep";
|
|
||||||
char * buf, * ptr, * start, * end;
|
|
||||||
struct stat s;
|
|
||||||
int fd, line, i;
|
|
||||||
|
|
||||||
log_message("loading modules dependencies");
|
|
||||||
|
|
||||||
if (IS_TESTING)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fd = open(deps_file, O_RDONLY);
|
|
||||||
if (fd == -1) {
|
|
||||||
log_perror(deps_file);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
fstat(fd, &s);
|
|
||||||
buf = alloca(s.st_size + 1);
|
|
||||||
if (read(fd, buf, s.st_size) != s.st_size) {
|
|
||||||
log_perror(deps_file);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
buf[s.st_size] = '\0';
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
ptr = buf;
|
|
||||||
line = 0;
|
|
||||||
while (ptr) {
|
|
||||||
line++;
|
|
||||||
ptr = strchr(ptr + 1, '\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
modules_deps = malloc(sizeof(*modules_deps) * (line+1));
|
|
||||||
|
|
||||||
start = buf;
|
|
||||||
line = 0;
|
|
||||||
while (start < (buf+s.st_size) && *start) {
|
|
||||||
char * tmp_deps[50];
|
|
||||||
|
|
||||||
end = strchr(start, '\n');
|
|
||||||
*end = '\0';
|
|
||||||
|
|
||||||
ptr = strchr(start, ':');
|
|
||||||
if (!ptr) {
|
|
||||||
start = end + 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
*ptr = '\0';
|
|
||||||
ptr++;
|
|
||||||
|
|
||||||
while (*ptr && (*ptr == ' ')) ptr++;
|
|
||||||
if (!*ptr) {
|
|
||||||
start = end + 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* sort of a good line */
|
|
||||||
modules_deps[line].name = strdup(start);
|
|
||||||
|
|
||||||
start = ptr;
|
|
||||||
i = 0;
|
|
||||||
while (start && *start) {
|
|
||||||
ptr = strchr(start, ' ');
|
|
||||||
if (ptr) *ptr = '\0';
|
|
||||||
tmp_deps[i++] = strdup(start);
|
|
||||||
if (ptr)
|
|
||||||
start = ptr + 1;
|
|
||||||
else
|
|
||||||
start = NULL;
|
|
||||||
while (start && *start && *start == ' ')
|
|
||||||
start++;
|
|
||||||
}
|
|
||||||
tmp_deps[i++] = NULL;
|
|
||||||
|
|
||||||
modules_deps[line].deps = memdup(tmp_deps, sizeof(char *) * i);
|
|
||||||
|
|
||||||
line++;
|
|
||||||
start = end + 1;
|
|
||||||
}
|
|
||||||
modules_deps[line].name = NULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void init_modules_insmoding(void)
|
|
||||||
{
|
|
||||||
if (load_modules_dependencies()) {
|
|
||||||
log_message("warning, error initing modules stuff, modules loading disabled");
|
|
||||||
disable_modules = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int module_already_present(const char * name)
|
|
||||||
{
|
|
||||||
FILE * f;
|
|
||||||
int answ = 0;
|
|
||||||
f = fopen("/proc/modules", "rb");
|
|
||||||
while (1) {
|
|
||||||
char buf[500];
|
|
||||||
if (!fgets(buf, sizeof(buf), f)) break;
|
|
||||||
if (!strncmp(name, buf, strlen(name)) && buf[strlen(name)] == ' ')
|
|
||||||
answ = 1;
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
return answ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static enum insmod_return insmod_with_deps(const char * mod_name, char * options)
|
|
||||||
{
|
|
||||||
struct module_deps_elem * dep;
|
|
||||||
|
|
||||||
dep = modules_deps;
|
|
||||||
while (dep && dep->name && strcmp(dep->name, mod_name)) dep++;
|
|
||||||
|
|
||||||
if (dep && dep->name && dep->deps) {
|
|
||||||
char ** one_dep;
|
|
||||||
one_dep = dep->deps;
|
|
||||||
while (*one_dep) {
|
|
||||||
/* here, we can fail but we don't care, if the error is
|
|
||||||
* important, the desired module will fail also */
|
|
||||||
insmod_with_deps(*one_dep, NULL);
|
|
||||||
one_dep++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (module_already_present(mod_name))
|
|
||||||
return INSMOD_OK;
|
|
||||||
|
|
||||||
log_message("needs %s", mod_name);
|
|
||||||
return insmod_archived_file(mod_name, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
enum insmod_return my_insmod(const char * mod_name, enum driver_type type, char * options)
|
|
||||||
{
|
|
||||||
char alias[500];
|
|
||||||
int i;
|
int i;
|
||||||
#ifndef DISABLE_NETWORK
|
|
||||||
char ** net_devices = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
log_message("have to insmod %s", mod_name);
|
log_message("have to insmod %s", mod_name);
|
||||||
|
|
||||||
if (disable_modules) {
|
|
||||||
log_message("\tdisabled");
|
|
||||||
return INSMOD_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef DISABLE_NETWORK
|
|
||||||
if (type == NETWORK_DEVICES || type == BRIDGE_OTHER)
|
|
||||||
net_devices = get_net_devices();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (IS_TESTING)
|
if (IS_TESTING)
|
||||||
return INSMOD_OK;
|
return INSMOD_OK;
|
||||||
|
|
||||||
i = insmod_with_deps(mod_name, options);
|
i = modprobe(mod_name, options);
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
log_message("\tsucceeded %s", mod_name);
|
log_message("\tsucceeded %s", mod_name);
|
||||||
#ifndef DISABLE_MEDIAS
|
|
||||||
if (type == MEDIA_ADAPTERS) {
|
|
||||||
log_message("MEDIA: %s", alias);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifndef DISABLE_NETWORK
|
|
||||||
if (type == NETWORK_DEVICES || type == BRIDGE_OTHER) {
|
|
||||||
char ** new_net_devices = get_net_devices();
|
|
||||||
while (new_net_devices && *new_net_devices) {
|
|
||||||
char ** ptr = net_devices;
|
|
||||||
while (ptr && *ptr) {
|
|
||||||
if (!strcmp(*new_net_devices, *ptr))
|
|
||||||
goto already_present;
|
|
||||||
ptr++;
|
|
||||||
}
|
|
||||||
log_message("NET: %s", alias);
|
|
||||||
net_discovered_interface(*new_net_devices);
|
|
||||||
|
|
||||||
already_present:
|
|
||||||
new_net_devices++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} else
|
} else
|
||||||
log_message("warning, insmod failed (%s %s) (%d)", mod_name, options, i);
|
log_message("warning, insmod failed (%s %s) (%d)", mod_name, options, i);
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum return_type insmod_with_options(char * mod, enum driver_type type)
|
enum return_type ask_insmod()
|
||||||
{
|
{
|
||||||
char * questions[] = { "Options", NULL };
|
return RETURN_ERROR;
|
||||||
static char ** answers = NULL;
|
|
||||||
enum return_type results;
|
|
||||||
char options[500] = "options ";
|
|
||||||
|
|
||||||
results = ask_from_entries("Please enter the parameters to give to the kernel:", questions, &answers, 24, NULL);
|
|
||||||
if (results != RETURN_OK)
|
|
||||||
return results;
|
|
||||||
|
|
||||||
strcat(options, mod);
|
|
||||||
strcat(options, " ");
|
|
||||||
strcat(options, answers[0]); // because my_insmod will eventually modify the string
|
|
||||||
|
|
||||||
if (my_insmod(mod, type, answers[0]) != INSMOD_OK) {
|
|
||||||
stg1_error_message("Insmod failed.");
|
|
||||||
return RETURN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RETURN_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum return_type ask_insmod(enum driver_type type)
|
|
||||||
{
|
|
||||||
char * mytype;
|
|
||||||
char msg[200];
|
|
||||||
enum return_type results;
|
|
||||||
char * choice;
|
|
||||||
|
|
||||||
unset_param(MODE_AUTOMATIC); /* we are in a fallback mode */
|
|
||||||
|
|
||||||
if (type == MEDIA_ADAPTERS)
|
|
||||||
mytype = "IDE or SCSI";
|
|
||||||
else if (type == NETWORK_DEVICES)
|
|
||||||
mytype = "NET";
|
|
||||||
else
|
|
||||||
return RETURN_ERROR;
|
|
||||||
|
|
||||||
if (disable_modules)
|
|
||||||
return RETURN_BACK;
|
|
||||||
|
|
||||||
snprintf(msg, sizeof(msg), "Which driver should I try to gain %s access?", mytype);
|
|
||||||
|
|
||||||
{
|
|
||||||
char ** drivers = mar_list_contents(archive_name);
|
|
||||||
char ** descrs = malloc(sizeof(char *) * string_array_length(drivers));
|
|
||||||
char ** p_drivers = drivers;
|
|
||||||
char ** p_descrs = descrs;
|
|
||||||
while (p_drivers && *p_drivers) {
|
|
||||||
int i;
|
|
||||||
*p_descrs = NULL;
|
|
||||||
for (i = 0 ; i < modules_descriptions_num ; i++) {
|
|
||||||
if (!strncmp(*p_drivers, modules_descriptions[i].module, strlen(modules_descriptions[i].module))
|
|
||||||
&& (*p_drivers)[strlen(modules_descriptions[i].module)] == '.') /* one contains '.o' not the other */
|
|
||||||
*p_descrs = modules_descriptions[i].descr;
|
|
||||||
}
|
|
||||||
p_drivers++;
|
|
||||||
p_descrs++;
|
|
||||||
}
|
|
||||||
results = ask_from_list_comments(msg, drivers, descrs, &choice);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results == RETURN_OK) {
|
|
||||||
choice[strlen(choice)-3] = '\0'; /* remove trailing .ko */
|
|
||||||
return insmod_with_options(choice, type);
|
|
||||||
} else
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void update_modules(void)
|
void update_modules(void)
|
||||||
{
|
{
|
||||||
FILE * f;
|
FILE * f;
|
||||||
@ -406,7 +144,7 @@ void update_modules(void)
|
|||||||
|
|
||||||
stg1_info_message("Please insert the Update Modules floppy.");;
|
stg1_info_message("Please insert the Update Modules floppy.");;
|
||||||
|
|
||||||
my_insmod("floppy", ANY_DRIVER_TYPE, NULL);
|
my_insmod("floppy", NULL);
|
||||||
|
|
||||||
if (my_mount("/dev/fd0", floppy_mount_location, "ext2", 0) == -1) {
|
if (my_mount("/dev/fd0", floppy_mount_location, "ext2", 0) == -1) {
|
||||||
enum return_type results = ask_yes_no("I can't find a Linux ext2 floppy in first floppy drive.\n"
|
enum return_type results = ask_yes_no("I can't find a Linux ext2 floppy in first floppy drive.\n"
|
||||||
@ -453,7 +191,7 @@ void update_modules(void)
|
|||||||
entry++;
|
entry++;
|
||||||
}
|
}
|
||||||
if (!entry || !*entry) {
|
if (!entry || !*entry) {
|
||||||
enum insmod_return ret = my_insmod(module, ANY_DRIVER_TYPE, options);
|
enum insmod_return ret = my_insmod(module, options);
|
||||||
if (ret != INSMOD_OK) {
|
if (ret != INSMOD_OK) {
|
||||||
log_message("\t%s (marfile): failed", module);
|
log_message("\t%s (marfile): failed", module);
|
||||||
stg1_error_message("Insmod %s (marfile) failed.", module);
|
stg1_error_message("Insmod %s (marfile) failed.", module);
|
||||||
|
12
modules.h
12
modules.h
@ -22,16 +22,8 @@ extern long init_module(void *, unsigned long, const char *);
|
|||||||
|
|
||||||
enum insmod_return { INSMOD_OK, INSMOD_FAILED, INSMOD_FAILED_FILE_NOT_FOUND };
|
enum insmod_return { INSMOD_OK, INSMOD_FAILED, INSMOD_FAILED_FILE_NOT_FOUND };
|
||||||
|
|
||||||
void init_modules_insmoding(void);
|
enum return_type ask_insmod();
|
||||||
enum insmod_return my_insmod(const char * mod_name, enum driver_type type, char * options);
|
enum insmod_return my_insmod(const char * mod_name, char * options);
|
||||||
enum return_type ask_insmod(enum driver_type);
|
|
||||||
void update_modules(void);
|
void update_modules(void);
|
||||||
|
|
||||||
struct module_deps_elem {
|
|
||||||
char * name;
|
|
||||||
char ** deps;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern int disable_modules;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
14
mount.c
14
mount.c
@ -157,29 +157,29 @@ int my_mount(char *dev, char *location, char *fs, int force_rw)
|
|||||||
|
|
||||||
#ifndef DISABLE_MEDIAS
|
#ifndef DISABLE_MEDIAS
|
||||||
if (!strcmp(fs, "squashfs"))
|
if (!strcmp(fs, "squashfs"))
|
||||||
my_insmod("squashfs", ANY_DRIVER_TYPE, NULL);
|
my_insmod("squashfs", NULL);
|
||||||
|
|
||||||
if (!strcmp(fs, "ext2"))
|
if (!strcmp(fs, "ext2"))
|
||||||
my_insmod("ext2", ANY_DRIVER_TYPE, NULL);
|
my_insmod("ext2", NULL);
|
||||||
|
|
||||||
if (!strcmp(fs, "vfat")) {
|
if (!strcmp(fs, "vfat")) {
|
||||||
my_insmod("vfat", ANY_DRIVER_TYPE, NULL);
|
my_insmod("vfat", NULL);
|
||||||
opts = "check=relaxed";
|
opts = "check=relaxed";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(fs, "ntfs"))
|
if (!strcmp(fs, "ntfs"))
|
||||||
my_insmod("ntfs", ANY_DRIVER_TYPE, NULL);
|
my_insmod("ntfs", NULL);
|
||||||
|
|
||||||
if (!strcmp(fs, "reiserfs"))
|
if (!strcmp(fs, "reiserfs"))
|
||||||
my_insmod("reiserfs", ANY_DRIVER_TYPE, NULL);
|
my_insmod("reiserfs", NULL);
|
||||||
|
|
||||||
if (!strcmp(fs, "iso9660"))
|
if (!strcmp(fs, "iso9660"))
|
||||||
my_insmod("isofs", ANY_DRIVER_TYPE, NULL);
|
my_insmod("isofs", NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef DISABLE_NETWORK
|
#ifndef DISABLE_NETWORK
|
||||||
if (!strcmp(fs, "nfs")) {
|
if (!strcmp(fs, "nfs")) {
|
||||||
my_insmod("nfs", ANY_DRIVER_TYPE, NULL);
|
my_insmod("nfs", NULL);
|
||||||
log_message("preparing nfsmount for %s", dev);
|
log_message("preparing nfsmount for %s", dev);
|
||||||
rc = nfsmount_prepare(dev, &opts);
|
rc = nfsmount_prepare(dev, &opts);
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
|
@ -515,7 +515,7 @@ static enum return_type bringup_networking(struct interface_info * intf)
|
|||||||
static struct interface_info loopback;
|
static struct interface_info loopback;
|
||||||
enum return_type results = RETURN_ERROR;
|
enum return_type results = RETURN_ERROR;
|
||||||
|
|
||||||
my_insmod("af_packet", ANY_DRIVER_TYPE, NULL);
|
my_insmod("af_packet", NULL);
|
||||||
|
|
||||||
while (results != RETURN_OK) {
|
while (results != RETURN_OK) {
|
||||||
results = setup_network_interface(intf);
|
results = setup_network_interface(intf);
|
||||||
@ -563,7 +563,7 @@ static char * interface_select(void)
|
|||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
stg1_error_message("No NET device found.");
|
stg1_error_message("No NET device found.");
|
||||||
i = ask_insmod(NETWORK_DEVICES);
|
i = ask_insmod();
|
||||||
if (i == RETURN_BACK)
|
if (i == RETURN_BACK)
|
||||||
return NULL;
|
return NULL;
|
||||||
return interface_select();
|
return interface_select();
|
||||||
|
395
probing.c
395
probing.c
@ -33,10 +33,10 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <libgen.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
// #include <sys/socket.h>
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
@ -54,40 +54,6 @@ struct media_info {
|
|||||||
enum media_type type;
|
enum media_type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pci_module_map {
|
|
||||||
unsigned short vendor; /* PCI vendor id */
|
|
||||||
unsigned short device; /* PCI device id */
|
|
||||||
char * module; /* module to load */
|
|
||||||
struct pci_module_map * next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct usb_module_map {
|
|
||||||
unsigned short vendor; /* PCI vendor id */
|
|
||||||
unsigned short device; /* PCI device id */
|
|
||||||
char * module; /* module to load */
|
|
||||||
struct usb_module_map * next;
|
|
||||||
};
|
|
||||||
|
|
||||||
char *usb_hcd[] = {
|
|
||||||
"uhci-hcd",
|
|
||||||
"ohci-hcd",
|
|
||||||
"ehci-hcd",
|
|
||||||
};
|
|
||||||
|
|
||||||
#define HCD_NUM (sizeof(usb_hcd) / sizeof(char *))
|
|
||||||
|
|
||||||
static void warning_insmod_failed(enum insmod_return r)
|
|
||||||
{
|
|
||||||
if (IS_AUTOMATIC && r == INSMOD_FAILED_FILE_NOT_FOUND)
|
|
||||||
return;
|
|
||||||
if (r != INSMOD_OK) {
|
|
||||||
if (r == INSMOD_FAILED_FILE_NOT_FOUND)
|
|
||||||
stg1_error_message("This floppy doesn't contain the driver.");
|
|
||||||
else
|
|
||||||
stg1_error_message("Warning, installation of driver failed. (please include msg from <Alt-F3> for bugreports)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef DISABLE_NETWORK
|
#ifndef DISABLE_NETWORK
|
||||||
struct net_description_elem
|
struct net_description_elem
|
||||||
{
|
{
|
||||||
@ -101,11 +67,6 @@ static char * net_intf_too_early_name[50]; /* for modules providing more than on
|
|||||||
static int net_intf_too_early_number = 0;
|
static int net_intf_too_early_number = 0;
|
||||||
static int net_intf_too_early_ptr = 0;
|
static int net_intf_too_early_ptr = 0;
|
||||||
|
|
||||||
void prepare_intf_descr(const char * intf_descr)
|
|
||||||
{
|
|
||||||
intf_descr_for_discover = strdup(intf_descr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void net_discovered_interface(char * intf_name)
|
void net_discovered_interface(char * intf_name)
|
||||||
{
|
{
|
||||||
if (!intf_descr_for_discover) {
|
if (!intf_descr_for_discover) {
|
||||||
@ -128,335 +89,19 @@ void net_discovered_interface(char * intf_name)
|
|||||||
|
|
||||||
char * get_net_intf_description(char * intf_name)
|
char * get_net_intf_description(char * intf_name)
|
||||||
{
|
{
|
||||||
int i;
|
char dev[SYSFS_PATH_MAX];
|
||||||
for (i = 0; i < net_descr_number ; i++)
|
char drv[SYSFS_PATH_MAX];
|
||||||
if (!strcmp(net_descriptions[i].intf_name, intf_name))
|
ssize_t i;
|
||||||
return net_descriptions[i].intf_description;
|
|
||||||
return strdup("unknown");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct pci_module_map * get_pci_ids()
|
snprintf(dev, SYSFS_PATH_MAX, "/sys/class/net/%s/device/driver", intf_name);
|
||||||
{
|
if ((i = readlink(dev, drv, SYSFS_PATH_MAX)) > 0) {
|
||||||
static struct pci_module_map * pcidb = NULL;
|
drv[i] = '\0';
|
||||||
struct pci_module_map *new, *last = NULL;
|
return strdup(basename(drv));
|
||||||
char buf[50];
|
|
||||||
int v, d;
|
|
||||||
FILE *f;
|
|
||||||
|
|
||||||
if (pcidb) return pcidb;
|
|
||||||
|
|
||||||
log_message("loading pcimap file");
|
|
||||||
if (!(f = fopen("/modules/modules.map", "rb"))) {
|
|
||||||
log_message("couldn't open pcimap file");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (3 == (fscanf(f, "%x %x %48s", &v, &d, buf))) {
|
|
||||||
new = (struct pci_module_map *)malloc(sizeof(*pcidb));
|
|
||||||
new->vendor = v;
|
|
||||||
new->device = d;
|
|
||||||
new->module = strdup(buf);
|
|
||||||
new->next = NULL;
|
|
||||||
|
|
||||||
if (!pcidb) {
|
|
||||||
pcidb = last = new;
|
|
||||||
} else {
|
|
||||||
last->next = new;
|
|
||||||
last = new;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
return pcidb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* forward */
|
|
||||||
static void probe_that_type(enum driver_type type);
|
|
||||||
|
|
||||||
/* ---- PCI probe ---------------------------------------------- */
|
|
||||||
static void pci_probe(enum driver_type type)
|
|
||||||
{
|
|
||||||
FILE * f;
|
|
||||||
int n;
|
|
||||||
char buf[200];
|
|
||||||
char devname[22];
|
|
||||||
u_int8_t devdata[48];
|
|
||||||
static int need_usb_hcd[HCD_NUM];
|
|
||||||
struct pci_module_map * pci_ids = NULL;
|
|
||||||
int that_class;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case SCSI_ADAPTERS:
|
|
||||||
that_class = PCI_CLASS_STORAGE_SCSI << 8;
|
|
||||||
break;
|
|
||||||
case IDE_ADAPTERS:
|
|
||||||
that_class = PCI_CLASS_STORAGE_IDE << 8;
|
|
||||||
break;
|
|
||||||
case RAID_ADAPTERS:
|
|
||||||
that_class = PCI_CLASS_STORAGE_RAID << 8;
|
|
||||||
break;
|
|
||||||
case NETWORK_DEVICES:
|
|
||||||
that_class = PCI_CLASS_NETWORK_ETHERNET << 8;
|
|
||||||
break;
|
|
||||||
case BRIDGE_OTHER:
|
|
||||||
that_class = PCI_CLASS_BRIDGE_OTHER << 8;
|
|
||||||
break;
|
|
||||||
case USB_CONTROLLERS:
|
|
||||||
that_class = PCI_CLASS_SERIAL_USB << 8;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NULL == (pci_ids = get_pci_ids())) {
|
|
||||||
log_message("PCI: could not get pci ids");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(f = fopen("/proc/bus/pci/devices", "r"))) {
|
|
||||||
log_message("PCI: could not open proc file");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (NULL != fgets(buf, sizeof(buf), f)) {
|
|
||||||
int i, fd, matched, dfn, vendor, device, class, subv, subid;
|
|
||||||
struct pci_module_map * pcidb;
|
|
||||||
|
|
||||||
sscanf(buf, "%x %x", &dfn, &vendor);
|
|
||||||
device = vendor & 0xFFFF; /* because scanf from dietlibc does not support %4f */
|
|
||||||
vendor = (vendor >> 16) & 0xFFFF;
|
|
||||||
|
|
||||||
snprintf(devname, sizeof(devname), "/proc/bus/pci/%02x/%02x.%x",
|
|
||||||
dfn >> 8, PCI_SLOT(dfn & 0xff), PCI_FUNC(dfn & 0xff));
|
|
||||||
|
|
||||||
log_message("gathering info for %s", devname);
|
|
||||||
|
|
||||||
if ((fd = open(devname, O_RDONLY)) != -1) {
|
|
||||||
i = read(fd, devdata, sizeof(devdata));
|
|
||||||
close(fd);
|
|
||||||
} else continue;
|
|
||||||
|
|
||||||
class = devdata[9] | (devdata[10] << 8) | (devdata[11] << 16);
|
|
||||||
subv = devdata[0x2c] | (devdata[0x2d] << 8);
|
|
||||||
subid = devdata[0x2e] | (devdata[0x2f] << 8);
|
|
||||||
|
|
||||||
if (that_class != (class & 0xffff00)) continue;
|
|
||||||
|
|
||||||
log_message("found pci device: %04x %04x %06x %04x %04x",
|
|
||||||
vendor, device, class, subv, subid);
|
|
||||||
|
|
||||||
for (matched = 0, pcidb = pci_ids; pcidb; pcidb = pcidb->next) {
|
|
||||||
if (pcidb->vendor == vendor && pcidb->device == device) {
|
|
||||||
/* vendor & device matched */
|
|
||||||
log_message("(pcimap) module is \"%s\"", pcidb->module);
|
|
||||||
if( get_param_valued("noload") && strstr(get_param_valued("noload"),pcidb->module)) {
|
|
||||||
log_message("not loading due to 'noload=' \"%s\"", pcidb->module);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef DISABLE_MEDIAS
|
|
||||||
if (type == IDE_ADAPTERS || type == SCSI_ADAPTERS || type == RAID_ADAPTERS) {
|
|
||||||
int wait_msg = 0;
|
|
||||||
enum insmod_return failed;
|
|
||||||
if (IS_AUTOMATIC) {
|
|
||||||
wait_message("Loading driver for storage adapter: %s", pcidb->module);
|
|
||||||
wait_msg = 1;
|
|
||||||
} else
|
|
||||||
stg1_info_message("About to load driver for storage adapter: %s", pcidb->module);
|
|
||||||
failed = my_insmod(pcidb->module, type, NULL);
|
|
||||||
if (wait_msg)
|
|
||||||
remove_wait_message();
|
|
||||||
warning_insmod_failed(failed);
|
|
||||||
}
|
|
||||||
#endif /* DISABLE_MEDIAS */
|
|
||||||
#ifndef DISABLE_NETWORK
|
|
||||||
if (type == NETWORK_DEVICES || type == BRIDGE_OTHER) {
|
|
||||||
int wait_msg = 0;
|
|
||||||
enum insmod_return failed;
|
|
||||||
if (IS_AUTOMATIC) {
|
|
||||||
wait_message("Loading driver for network device: %s", pcidb->module);
|
|
||||||
wait_msg = 1;
|
|
||||||
} else
|
|
||||||
stg1_info_message("About to load driver for network device: %s",
|
|
||||||
pcidb->module);
|
|
||||||
prepare_intf_descr(pcidb->module);
|
|
||||||
failed = my_insmod(pcidb->module, type, NULL);
|
|
||||||
if (wait_msg)
|
|
||||||
remove_wait_message();
|
|
||||||
warning_insmod_failed(failed);
|
|
||||||
if (intf_descr_for_discover) /* for modules providing more than one net intf */
|
|
||||||
net_discovered_interface(NULL);
|
|
||||||
}
|
|
||||||
#endif /* DISABLE_NETWORK */
|
|
||||||
if (type == USB_CONTROLLERS) {
|
|
||||||
/* found explicitly declared module */
|
|
||||||
for (i=0; i < HCD_NUM; i++) {
|
|
||||||
if(ptr_begins_static_str(pcidb->module, usb_hcd[i])) {
|
|
||||||
need_usb_hcd[i] = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
matched = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} /* end of pcidb table */
|
|
||||||
|
|
||||||
#ifndef DISABLE_MEDIAS
|
|
||||||
if (!matched && type == IDE_ADAPTERS) {
|
|
||||||
/* probe ide-generic as last resort */
|
|
||||||
log_message("(guess) module is \"ide-generic\"");
|
|
||||||
int wait_msg = 0;
|
|
||||||
enum insmod_return failed;
|
|
||||||
|
|
||||||
if (IS_AUTOMATIC) {
|
|
||||||
wait_message("Loading driver for IDE adapter: ide-generic");
|
|
||||||
wait_msg = 1;
|
|
||||||
} else
|
|
||||||
stg1_info_message("About to load driver for IDE adapter: ide-generic");
|
|
||||||
|
|
||||||
failed = my_insmod("ide-generic", type, NULL);
|
|
||||||
if (wait_msg)
|
|
||||||
remove_wait_message();
|
|
||||||
warning_insmod_failed(failed);
|
|
||||||
}
|
|
||||||
#endif /* DISABLE_MEDIAS */
|
|
||||||
|
|
||||||
if (!matched && type == USB_CONTROLLERS && (class & 0xffff0f) == 0x0c0300) {
|
|
||||||
/* no module found, trying to identify one by class:
|
|
||||||
HCD: PCI Class:
|
|
||||||
uhci-hcd 0x000c0300
|
|
||||||
ohci-hcd 0x000c0310
|
|
||||||
ehci-hcd 0x000c0320
|
|
||||||
*/
|
|
||||||
log_message("(guess) module is \"%s\"", usb_hcd[(class & 0xf0)>>4]);
|
|
||||||
need_usb_hcd[(class & 0xf0)>>4] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
} /* end of this vendor & device */
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
/* load all usb controller modules now, starting from possible ehci-hcd */
|
|
||||||
/* to prevent case when old-timed module sitting on newer host controller */
|
|
||||||
if (type == USB_CONTROLLERS) {
|
|
||||||
enum insmod_return failed;
|
|
||||||
for (n=HCD_NUM-1; n >= 0; n--) {
|
|
||||||
if (need_usb_hcd[n]) {
|
|
||||||
/* do it AUTOMATIC -- for usb kbd case */
|
|
||||||
/* and ever silent
|
|
||||||
wait_message("Loading driver for USB controller: %s", usb_hcd[n]);
|
|
||||||
*/
|
|
||||||
failed = my_insmod(usb_hcd[n], USB_CONTROLLERS, NULL);
|
|
||||||
/*
|
|
||||||
remove_wait_message();
|
|
||||||
*/
|
|
||||||
warning_insmod_failed(failed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- USB probe ---------------------------------------------- */
|
|
||||||
static void usb_probe(enum driver_type type)
|
|
||||||
{
|
|
||||||
static int already_probed_usb_controllers = 0;
|
|
||||||
static int already_mounted_usbdev = 0;
|
|
||||||
static int already_probed_hid = 0;
|
|
||||||
|
|
||||||
FILE * f;
|
|
||||||
char buf[200];
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
#ifdef ENABLE_USBNET
|
|
||||||
case NETWORK_DEVICES:
|
|
||||||
#endif
|
|
||||||
case MEDIA_ADAPTERS:
|
|
||||||
case HID_DEVICES:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!already_probed_usb_controllers) {
|
|
||||||
already_probed_usb_controllers = 1;
|
|
||||||
probe_that_type(USB_CONTROLLERS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!already_mounted_usbdev) {
|
|
||||||
already_mounted_usbdev = 1;
|
|
||||||
if (mount("/proc/bus/usb", "/proc/bus/usb", "usbfs", 0, NULL)) {
|
|
||||||
log_message("USB: couldn't mount /proc/bus/usb");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* no need to show wait message -- we're doing this very first
|
|
||||||
wait_message("Waiting for USB stuff to show up.");
|
|
||||||
*/
|
|
||||||
sleep(2); /* sucking background work */
|
|
||||||
/*
|
|
||||||
remove_wait_message();
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* dirty hacks */
|
|
||||||
if (type == MEDIA_ADAPTERS) {
|
|
||||||
stg1_info_message("About to load driver for usb storage device: usb-storage");
|
|
||||||
my_insmod("usb-storage", ANY_DRIVER_TYPE, NULL);
|
|
||||||
sleep(5); /* wait for dust settles down */
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ENABLE_USBNET
|
|
||||||
if (type == NETWORK_DEVICES) {
|
|
||||||
stg1_info_message("About to load driver for usb network device: usbnet");
|
|
||||||
my_insmod("usbnet", ANY_DRIVER_TYPE, NULL);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!(f = fopen("/proc/bus/usb/devices", "r"))) {
|
|
||||||
log_message("USB: could not open proc file");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == HID_DEVICES && !already_probed_hid) {
|
|
||||||
while (NULL != fgets(buf, sizeof(buf), f)) {
|
|
||||||
if (strstr(buf, "Cls=03")) {
|
|
||||||
my_insmod("usbhid", ANY_DRIVER_TYPE, NULL);
|
|
||||||
already_probed_hid = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void probe_that_type(enum driver_type type)
|
|
||||||
{
|
|
||||||
if (IS_EXPERT) {
|
|
||||||
ask_insmod(type);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == MEDIA_ADAPTERS) {
|
|
||||||
update_splash();
|
|
||||||
pci_probe(IDE_ADAPTERS);
|
|
||||||
update_splash();
|
|
||||||
pci_probe(SCSI_ADAPTERS);
|
|
||||||
update_splash();
|
|
||||||
pci_probe(RAID_ADAPTERS);
|
|
||||||
update_splash();
|
|
||||||
usb_probe(MEDIA_ADAPTERS);
|
|
||||||
update_splash();
|
|
||||||
} else {
|
} else {
|
||||||
update_splash();
|
return strdup("unknown");
|
||||||
pci_probe(type);
|
|
||||||
update_splash();
|
|
||||||
usb_probe(type);
|
|
||||||
update_splash();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DISABLE_MEDIAS
|
#ifndef DISABLE_MEDIAS
|
||||||
static struct media_info * medias = NULL;
|
static struct media_info * medias = NULL;
|
||||||
@ -473,9 +118,7 @@ static void find_media(void)
|
|||||||
char *s;
|
char *s;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
if (!medias)
|
if (medias)
|
||||||
probe_that_type(MEDIA_ADAPTERS);
|
|
||||||
else
|
|
||||||
free(medias); /* that does not free the strings, by the way */
|
free(medias); /* that does not free the strings, by the way */
|
||||||
|
|
||||||
if ((dir = opendir("/sys/block")) == NULL) {
|
if ((dir = opendir("/sys/block")) == NULL) {
|
||||||
@ -601,13 +244,8 @@ void get_medias(enum media_type media, char *** names, char *** models)
|
|||||||
}
|
}
|
||||||
#endif /* DISABLE_MEDIAS */
|
#endif /* DISABLE_MEDIAS */
|
||||||
|
|
||||||
void probe_hiddev()
|
|
||||||
{
|
|
||||||
usb_probe(HID_DEVICES);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef DISABLE_NETWORK
|
#ifndef DISABLE_NETWORK
|
||||||
int net_device_available(char * device)
|
static int net_device_available(char * device)
|
||||||
{
|
{
|
||||||
struct ifreq req;
|
struct ifreq req;
|
||||||
int s;
|
int s;
|
||||||
@ -633,7 +271,6 @@ char ** get_net_devices(void)
|
|||||||
char * devices[] = {
|
char * devices[] = {
|
||||||
"eth0", "eth1", "eth2", "eth3", "eth4", "eth5",
|
"eth0", "eth1", "eth2", "eth3", "eth4", "eth5",
|
||||||
"tr0",
|
"tr0",
|
||||||
"plip0", "plip1", "plip2",
|
|
||||||
"fddi0",
|
"fddi0",
|
||||||
#ifdef ENABLE_USBNET
|
#ifdef ENABLE_USBNET
|
||||||
"usb0", "usb1", "usb2", "usb3",
|
"usb0", "usb1", "usb2", "usb3",
|
||||||
@ -643,14 +280,6 @@ char ** get_net_devices(void)
|
|||||||
char ** ptr = devices;
|
char ** ptr = devices;
|
||||||
char * tmp[50];
|
char * tmp[50];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
static int already_probed = 0;
|
|
||||||
|
|
||||||
if (!already_probed) {
|
|
||||||
already_probed = 1; /* cut off loop brought by: probe_that_type => my_insmod => get_net_devices */
|
|
||||||
probe_that_type(NETWORK_DEVICES);
|
|
||||||
/* for some chipsets having nic in it, i.e. nForcex */
|
|
||||||
probe_that_type(BRIDGE_OTHER);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (ptr && *ptr) {
|
while (ptr && *ptr) {
|
||||||
if (net_device_available(*ptr))
|
if (net_device_available(*ptr))
|
||||||
|
24
probing.h
24
probing.h
@ -24,40 +24,16 @@
|
|||||||
|
|
||||||
enum media_type { CDROM, DISK, FLOPPY, TAPE, UNKNOWN_MEDIA };
|
enum media_type { CDROM, DISK, FLOPPY, TAPE, UNKNOWN_MEDIA };
|
||||||
|
|
||||||
enum driver_type { IDE_ADAPTERS, SCSI_ADAPTERS, RAID_ADAPTERS, MEDIA_ADAPTERS, NETWORK_DEVICES, HID_DEVICES, USB_CONTROLLERS, BRIDGE_OTHER, ANY_DRIVER_TYPE };
|
|
||||||
|
|
||||||
void get_medias(enum media_type media, char *** names, char *** models);
|
void get_medias(enum media_type media, char *** names, char *** models);
|
||||||
void probe_hiddev();
|
void probe_hiddev();
|
||||||
char ** get_net_devices(void);
|
char ** get_net_devices(void);
|
||||||
void net_discovered_interface(char * intf_name);
|
void net_discovered_interface(char * intf_name);
|
||||||
char * get_net_intf_description(char * intf_name);
|
char * get_net_intf_description(char * intf_name);
|
||||||
void prepare_intf_descr(const char * intf_descr);
|
|
||||||
|
|
||||||
#ifndef PCI_SLOT
|
|
||||||
#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PCI_FUNC
|
|
||||||
#define PCI_FUNC(devfn) ((devfn) & 0x07)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SYSFS_PATH_MAX
|
#ifndef SYSFS_PATH_MAX
|
||||||
#define SYSFS_PATH_MAX 256
|
#define SYSFS_PATH_MAX 256
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* extract from linux/pci_ids.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define PCI_BASE_CLASS_STORAGE 0x01
|
|
||||||
#define PCI_CLASS_STORAGE_SCSI 0x0100
|
|
||||||
#define PCI_CLASS_STORAGE_IDE 0x0101
|
|
||||||
#define PCI_CLASS_STORAGE_RAID 0x0104
|
|
||||||
#define PCI_CLASS_NETWORK_ETHERNET 0x0200
|
|
||||||
#define PCI_CLASS_SERIAL_FIREWIRE 0x0c00
|
|
||||||
#define PCI_CLASS_SERIAL_USB 0x0c03
|
|
||||||
#define PCI_CLASS_BRIDGE_OTHER 0x0680
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* from scsi/scsi.h
|
* from scsi/scsi.h
|
||||||
*/
|
*/
|
||||||
|
@ -2,27 +2,27 @@
|
|||||||
%def_with splash
|
%def_with splash
|
||||||
|
|
||||||
Name: propagator
|
Name: propagator
|
||||||
Version: 20070301
|
Version: 20080301
|
||||||
Release: alt7
|
Release: alt1
|
||||||
|
|
||||||
Summary: 'Early userspace' set of binaries
|
Summary: 'Early userspace' set of binaries
|
||||||
License: GPL
|
License: GPL
|
||||||
Group: System/Kernel and hardware
|
Group: System/Kernel and hardware
|
||||||
|
|
||||||
Source0: %name-%version.tar.bz2
|
Source0: %name-%version-%release.tar
|
||||||
|
|
||||||
BuildRequires: mar >= 20070301-alt1 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
|
%description
|
||||||
%name is a set of binaries useful in 'early userspace' environment,
|
%name is a set of binaries useful in 'early userspace' environment,
|
||||||
including init and various helpers for hw probing and bootstrapping.
|
including init and various helpers for hw probing and bootstrapping.
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%setup -c
|
%setup
|
||||||
|
|
||||||
%build
|
%build
|
||||||
make %{?_with_shell:WITH_SHELL=t} %{?_with_splash:WITH_SPLASH=t} \
|
make %{?_with_shell:WITH_SHELL=t} %{?_with_splash:WITH_SPLASH=t}
|
||||||
LIBDIR=%_libdir CFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE"
|
|
||||||
|
|
||||||
%install
|
%install
|
||||||
%make_install DESTDIR=%buildroot LIBDIR=%_libdir install
|
%make_install DESTDIR=%buildroot LIBDIR=%_libdir install
|
||||||
@ -32,6 +32,9 @@ make %{?_with_shell:WITH_SHELL=t} %{?_with_splash:WITH_SPLASH=t} \
|
|||||||
%_libdir/%name
|
%_libdir/%name
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Sat Mar 1 2008 Sergey Bolshakov <sbolshakov@altlinux.ru> 20080301-alt1
|
||||||
|
- use udev from now
|
||||||
|
|
||||||
* Wed Aug 8 2007 Sergey Bolshakov <sbolshakov@altlinux.ru> 20070301-alt7
|
* Wed Aug 8 2007 Sergey Bolshakov <sbolshakov@altlinux.ru> 20070301-alt7
|
||||||
- do not show %name build date on tty1, closes \#12491
|
- do not show %name build date on tty1, closes \#12491
|
||||||
|
|
||||||
|
111
stage1.c
111
stage1.c
@ -47,10 +47,6 @@
|
|||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
#include "insmod.h"
|
#include "insmod.h"
|
||||||
|
|
||||||
#ifdef ENABLE_PCMCIA
|
|
||||||
#include "pcmcia/pcmcia.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef DISABLE_CDROM
|
#ifndef DISABLE_CDROM
|
||||||
#include "cdrom.h"
|
#include "cdrom.h"
|
||||||
#endif
|
#endif
|
||||||
@ -180,65 +176,6 @@ static void spawn_splash(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
char * interactive_fifo = "/tmp/stage1-fifo";
|
|
||||||
static pid_t interactive_pid = 0;
|
|
||||||
|
|
||||||
/* spawns my small interactive on console #6 */
|
|
||||||
static void spawn_interactive(void)
|
|
||||||
{
|
|
||||||
#ifdef SPAWN_INTERACTIVE
|
|
||||||
int fd;
|
|
||||||
char * dev = "/dev/tty6";
|
|
||||||
|
|
||||||
printf("spawning my interactive on %s\n", dev);
|
|
||||||
|
|
||||||
if (!IS_TESTING) {
|
|
||||||
fd = open(dev, O_RDWR);
|
|
||||||
if (fd == -1) {
|
|
||||||
printf("cannot open %s -- no interactive\n", dev);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mkfifo(interactive_fifo, O_RDWR)) {
|
|
||||||
printf("cannot create fifo -- no interactive\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(interactive_pid = fork())) {
|
|
||||||
int fif_out;
|
|
||||||
|
|
||||||
dup2(fd, 0);
|
|
||||||
dup2(fd, 1);
|
|
||||||
dup2(fd, 2);
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
setsid();
|
|
||||||
if (ioctl(0, TIOCSCTTY, NULL))
|
|
||||||
perror("could not set new controlling tty");
|
|
||||||
|
|
||||||
fif_out = open(interactive_fifo, O_WRONLY);
|
|
||||||
printf("Please enter your command (availables: [+,-] [rescue,expert]).\n");
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
char s[50];
|
|
||||||
int i = 0;
|
|
||||||
printf("? ");
|
|
||||||
fflush(stdout);
|
|
||||||
read(0, &(s[i++]), 1);
|
|
||||||
fcntl(0, F_SETFL, O_NONBLOCK);
|
|
||||||
while (read(0, &(s[i++]), 1) > 0 && i < sizeof(s));
|
|
||||||
fcntl(0, F_SETFL, 0);
|
|
||||||
write(fif_out, s, i-2);
|
|
||||||
printf("Ok.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -258,7 +195,7 @@ static void expert_third_party_modules(void)
|
|||||||
if (results != RETURN_OK)
|
if (results != RETURN_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
my_insmod("floppy", ANY_DRIVER_TYPE, NULL);
|
my_insmod("floppy", NULL);
|
||||||
|
|
||||||
if (my_mount("/dev/fd0", floppy_mount_location, "ext2", 0) == -1) {
|
if (my_mount("/dev/fd0", floppy_mount_location, "ext2", 0) == -1) {
|
||||||
stg1_error_message("I can't find a Linux ext2 floppy in first floppy drive.");
|
stg1_error_message("I can't find a Linux ext2 floppy in first floppy drive.");
|
||||||
@ -298,27 +235,6 @@ static void expert_third_party_modules(void)
|
|||||||
return expert_third_party_modules();
|
return expert_third_party_modules();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void handle_pcmcia(char ** pcmcia_adapter)
|
|
||||||
{
|
|
||||||
#ifdef ENABLE_PCMCIA
|
|
||||||
*pcmcia_adapter = pcmcia_probe();
|
|
||||||
if (!*pcmcia_adapter) {
|
|
||||||
log_message("no pcmcia adapter found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
my_insmod("pcmcia_core", ANY_DRIVER_TYPE, "probe_io=0");
|
|
||||||
my_insmod(*pcmcia_adapter, ANY_DRIVER_TYPE, NULL);
|
|
||||||
my_insmod("ds", ANY_DRIVER_TYPE, NULL);
|
|
||||||
|
|
||||||
/* call to cardmgr takes time, let's use the wait message */
|
|
||||||
wait_message("Enabling PCMCIA extension cards...");
|
|
||||||
log_message("cardmgr rc: %d", cardmgr_call());
|
|
||||||
remove_wait_message();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************
|
/************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -405,20 +321,9 @@ void getversion()
|
|||||||
int main(int argc, char **argv, char **env)
|
int main(int argc, char **argv, char **env)
|
||||||
{
|
{
|
||||||
enum return_type ret;
|
enum return_type ret;
|
||||||
char * pcmcia_adapter = NULL;
|
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
open_log();
|
open_log();
|
||||||
if (strstr(argv[0], "modprobe"))
|
|
||||||
{
|
|
||||||
if (argc == 4)
|
|
||||||
return(my_insmod(argv[argc-1], ANY_DRIVER_TYPE, NULL));
|
|
||||||
else
|
|
||||||
return(255);
|
|
||||||
}
|
|
||||||
|
|
||||||
spawn_interactive();
|
|
||||||
|
|
||||||
getversion();
|
getversion();
|
||||||
log_message("welcome to the %s install (alt-stage1, built " __DATE__ " " __TIME__")", version);
|
log_message("welcome to the %s install (alt-stage1, built " __DATE__ " " __TIME__")", version);
|
||||||
process_cmdline();
|
process_cmdline();
|
||||||
@ -427,19 +332,8 @@ int main(int argc, char **argv, char **env)
|
|||||||
spawn_splash();
|
spawn_splash();
|
||||||
prepare_progress();
|
prepare_progress();
|
||||||
update_splash();
|
update_splash();
|
||||||
init_modules_insmoding();
|
|
||||||
snprintf(buf, sizeof(buf), "Welcome to %s", version);
|
snprintf(buf, sizeof(buf), "Welcome to %s", version);
|
||||||
init_frontend(buf);
|
init_frontend(buf);
|
||||||
probe_hiddev();
|
|
||||||
|
|
||||||
if (IS_EXPERT)
|
|
||||||
expert_third_party_modules();
|
|
||||||
|
|
||||||
if (IS_UPDATEMODULES)
|
|
||||||
update_modules();
|
|
||||||
|
|
||||||
update_splash();
|
|
||||||
handle_pcmcia(&pcmcia_adapter);
|
|
||||||
update_splash();
|
update_splash();
|
||||||
|
|
||||||
if (IS_RESCUE && total_memory() < MEM_LIMIT_RESCUE) {
|
if (IS_RESCUE && total_memory() < MEM_LIMIT_RESCUE) {
|
||||||
@ -460,9 +354,6 @@ int main(int argc, char **argv, char **env)
|
|||||||
fatal_error("could not select an installation method");
|
fatal_error("could not select an installation method");
|
||||||
|
|
||||||
/* all went good */
|
/* all went good */
|
||||||
if (interactive_pid != 0)
|
|
||||||
kill(interactive_pid, 9);
|
|
||||||
|
|
||||||
if (shell_pid != 0)
|
if (shell_pid != 0)
|
||||||
kill(shell_pid, 9);
|
kill(shell_pid, 9);
|
||||||
|
|
||||||
|
10
tools.c
10
tools.c
@ -30,9 +30,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <bzlib.h>
|
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
|
|
||||||
#include "stage1.h"
|
#include "stage1.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
@ -520,12 +520,12 @@ int string_array_length(char ** a)
|
|||||||
|
|
||||||
int do_losetup(char * device, char * target)
|
int do_losetup(char * device, char * target)
|
||||||
{
|
{
|
||||||
int loopfd, targfd;
|
int i, loopfd, targfd;
|
||||||
struct loop_info loopInfo;
|
struct loop_info loopInfo;
|
||||||
|
|
||||||
my_insmod("loop", ANY_DRIVER_TYPE, NULL);
|
my_insmod("loop", NULL);
|
||||||
|
/* wait for udev's dust settles down */
|
||||||
loopfd = open( device, O_RDONLY );
|
for (i=3; i && (loopfd = open(device, O_RDONLY)) < 0; --i, sleep(1));
|
||||||
if ( loopfd < 0 )
|
if ( loopfd < 0 )
|
||||||
{
|
{
|
||||||
log_message( "losetup: error opening %s: %s", device, strerror(errno) );
|
log_message( "losetup: error opening %s: %s", device, strerror(errno) );
|
||||||
|
Loading…
Reference in New Issue
Block a user