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
|
||||
|
||||
DESTDIR =
|
||||
@ -43,13 +6,49 @@ BINDIR ?= /usr/bin
|
||||
LIBDIR ?= /usr/lib
|
||||
BINSDIR ?= $(LIBDIR)/$(PACKAGE)/bin
|
||||
|
||||
INSTALL = /usr/bin/install
|
||||
TARGETS = init stage1 gencpio
|
||||
|
||||
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 =
|
||||
STAGE1_DEFS =
|
||||
|
||||
@ -66,47 +65,34 @@ ifneq ($(WITHOUT_USBNET),)
|
||||
STAGE1_DEFS += -DDISABLE_USBNET
|
||||
endif
|
||||
|
||||
COMPILE = $(CC) $(DEFS) $(CFLAGS)
|
||||
COMPILE = $(CC) $(CFLAGS) $(DEFS)
|
||||
|
||||
#- stage1 "loader"
|
||||
# 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
|
||||
ifeq (ia64, $(ARCH))
|
||||
INIT_DEFS = -DINIT_HEADERS=\"init-libc-headers.h\" $(GLIBC_INCLUDES)
|
||||
else
|
||||
INIT_DEFS = -DINIT_HEADERS=\"init-libc-headers.h\" $(DIETLIBC_INCLUDES)
|
||||
endif
|
||||
endif
|
||||
INIT_DEFS = $(INCLUDES)
|
||||
|
||||
INITOBJS = $(subst .c,.o,$(INITSRC))
|
||||
INITOBJS = $(addprefix $(L)-,$(subst .c,.o,$(INITSRC)))
|
||||
|
||||
#- frontends
|
||||
NEWT_FRONTEND_SRC = newt-frontend.c
|
||||
GLIBC_NEWT_FRONTEND_LIBS = $(LIBDIR)/libnewt.a $(LIBDIR)/libslang.a
|
||||
DIETLIBC_NEWT_FRONTEND_LIBS = $(DIET_LIBDIR)/libnewt.a $(DIET_LIBDIR)/libslang.a
|
||||
NEWT_FRONTEND_LIBS = $(LIBDIR)/libnewt.a $(LIBDIR)/libslang.a
|
||||
|
||||
STDIO_FRONTEND_SRC = stdio-frontend.c
|
||||
GLIBC_STDIO_FRONTEND_LIBS =
|
||||
DIETLIBC_STDIO_FRONTEND_LIBS =
|
||||
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))
|
||||
FRONTEND_LINK = $(FRONTEND_OBJS) $($(L)_$(F)_FRONTEND_LIBS)
|
||||
|
||||
GLIBC_STAGE1_OWN_LIBS = $(LIBDIR)/libmar.a $(LIBDIR)/libbz2.a
|
||||
DIETLIBC_STAGE1_OWN_LIBS = $(DIET_LIBDIR)/libmar.a $(DIET_LIBDIR)/libbz2.a
|
||||
GLIBC_STAGE1_OWN_LIBS =
|
||||
KLIBC_STAGE1_OWN_LIBS =
|
||||
STAGE1_OWN_LIBS = $($(L)_STAGE1_OWN_LIBS)
|
||||
|
||||
|
||||
ifeq (DIETLIBC, $(L))
|
||||
STAGE1_NETWORK_LIBS = $(DIET_LIBDIR)/librpc.a
|
||||
ifeq ($(L),KLIBC)
|
||||
STAGE1_NETWORK_LIBS =
|
||||
endif
|
||||
|
||||
ifeq (GLIBC, $(L))
|
||||
ifeq ($(L),GLIBC)
|
||||
STAGE1_NETWORK_LIBS = $(LIBDIR)/libresolv.a
|
||||
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 \
|
||||
cdrom.c disk.c \
|
||||
network.c nfsmount.c dhcp.c url.c dns.c adsl.c
|
||||
|
||||
ALLSRC = $(INITSRC) $(STAGE1SRC)
|
||||
###############################################################################
|
||||
|
||||
STAGE1OBJS = $(subst .c,.o,$(STAGE1SRC))
|
||||
STAGE1OBJS = $(addprefix $(L)-,$(subst .c,.o,$(STAGE1SRC)))
|
||||
|
||||
ifeq (xi386, $(ARCH))
|
||||
LDFLAGS_INIT = -static -nostdlib /usr/lib/crt1.o
|
||||
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
|
||||
LDFLAGS_INIT = $($(L)_LDFLAGS_STAGE1)
|
||||
INIT_LIBC = $($(L)_LIBC)
|
||||
|
||||
|
||||
init: $(INITOBJS) $(INIT_LIBC)
|
||||
init: $(INITOBJS) $(INIT_LIBC)
|
||||
$(CC) -o $@ $^ $(LDFLAGS_INIT)
|
||||
$(STRIPCMD) $@
|
||||
|
||||
@ -142,19 +119,29 @@ stage1: $(STAGE1OBJS) $(STAGE1_OWN_LIBS) $(STAGE1_NETWORK_LIBS) $(FRONTEND_LINK)
|
||||
$(CC) -o $@ $^ $(LDFLAGS_STAGE1)
|
||||
$(STRIPCMD) $@
|
||||
|
||||
$(INITOBJS): %.o: %.c
|
||||
$(COMPILE) $(INIT_DEFS) -c $<
|
||||
$(INITOBJS): $(L)-%.o: %.c
|
||||
$(COMPILE) $(INIT_DEFS) -c $< -o $@
|
||||
|
||||
$(STAGE1OBJS): %.o: %.c
|
||||
$(STAGE1OBJS): $(L)-%.o: %.c
|
||||
$(COMPILE) $(INCLUDES) $(STAGE1_DEFS) -c $< -o $@
|
||||
|
||||
.c.o:
|
||||
$(COMPILE) $(INCLUDES) -c $<
|
||||
$(FRONTEND_OBJS): $(L)-%.o: %.c
|
||||
$(COMPILE) $(INCLUDES) -c $< -o $@
|
||||
|
||||
version.h: /etc/altlinux-release
|
||||
@sed 's|^ALT Linux \([^ ]\+\)\([^(]\+\)(\([^)]\+\))|\
|
||||
echo \\#define VERSION \\"\2\\";echo \\#define DISTRIB_NAME \\"ALT Linux\2\1 \\(\3\\)\\"|' < $^ |sh > $@
|
||||
|
||||
gencpio: gen_init_cpio.c
|
||||
$(CC) $(CFLAGS) $(DEFS) -o $@ $^
|
||||
|
||||
initfs: mkinitfs $(TARGETS)
|
||||
sh $< $@
|
||||
|
||||
install: initfs
|
||||
$(INSTALL) -D -m0755 gencpio $(DESTDIR)$(BINDIR)/gencpio
|
||||
$(INSTALL) -D -m0644 initfs $(DESTDIR)$(LIBDIR)/$(PACKAGE)/initfs
|
||||
|
||||
clean:
|
||||
rm -f *.o .depend $(TARGETS) version.h
|
||||
|
||||
@ -164,11 +151,3 @@ clean:
|
||||
ifeq (.depend,$(wildcard .depend))
|
||||
include .depend
|
||||
endif
|
||||
|
||||
gencpio: gen_init_cpio.c
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
install: $(TARGETS)
|
||||
mkdir -p $(DESTDIR)$(BINDIR) $(DESTDIR)$(BINSDIR)
|
||||
install -m0755 gencpio $(DESTDIR)$(BINDIR)
|
||||
install -m0755 init stage1 $(DESTDIR)$(BINSDIR)
|
||||
|
@ -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;
|
||||
|
||||
wait_message("Waiting for ADSL connection to show up...");
|
||||
my_insmod("ppp_generic", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("ppp_async", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("ppp", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("ppp_generic", NULL);
|
||||
my_insmod("ppp_async", NULL);
|
||||
my_insmod("ppp", NULL);
|
||||
results = adsl_connect(intf->device, answers[0], answers[1]);
|
||||
remove_wait_message();
|
||||
|
||||
|
10
cdrom.c
10
cdrom.c
@ -113,8 +113,8 @@ enum return_type cdrom_prepare(void)
|
||||
char * choice;
|
||||
int i, count = 0;
|
||||
enum return_type results;
|
||||
my_insmod("ide-cd", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("sr_mod", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("ide-cd", NULL);
|
||||
my_insmod("sr_mod", NULL);
|
||||
update_splash();
|
||||
|
||||
get_medias(CDROM, &medias, &medias_models);
|
||||
@ -127,7 +127,7 @@ enum return_type cdrom_prepare(void)
|
||||
|
||||
if (count == 0) {
|
||||
stg1_error_message("No CDROM device found.");
|
||||
i = ask_insmod(MEDIA_ADAPTERS);
|
||||
i = ask_insmod();
|
||||
if (i == RETURN_BACK)
|
||||
return RETURN_BACK;
|
||||
return cdrom_prepare();
|
||||
@ -137,7 +137,7 @@ enum return_type cdrom_prepare(void)
|
||||
results = try_with_device(*medias, *medias_models);
|
||||
if (results == RETURN_OK)
|
||||
return RETURN_OK;
|
||||
i = ask_insmod(MEDIA_ADAPTERS);
|
||||
i = ask_insmod();
|
||||
if (i == RETURN_BACK)
|
||||
return RETURN_BACK;
|
||||
return cdrom_prepare();
|
||||
@ -187,7 +187,7 @@ enum return_type cdrom_prepare(void)
|
||||
if (results == RETURN_BACK)
|
||||
return cdrom_prepare();
|
||||
|
||||
i = ask_insmod(MEDIA_ADAPTERS);
|
||||
i = ask_insmod();
|
||||
if (i == RETURN_BACK)
|
||||
return RETURN_BACK;
|
||||
return cdrom_prepare();
|
||||
|
10
disk.c
10
disk.c
@ -282,8 +282,8 @@ enum return_type disk_prepare(void)
|
||||
int i, count = 0;
|
||||
enum return_type results;
|
||||
|
||||
my_insmod("ide-disk", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("sd_mod", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("ide-disk", NULL);
|
||||
my_insmod("sd_mod", NULL);
|
||||
get_medias(DISK, &medias, &medias_models);
|
||||
|
||||
ptr = medias;
|
||||
@ -294,7 +294,7 @@ enum return_type disk_prepare(void)
|
||||
|
||||
if (count == 0) {
|
||||
stg1_error_message("No DISK drive found.");
|
||||
i = ask_insmod(MEDIA_ADAPTERS);
|
||||
i = ask_insmod();
|
||||
if (i == RETURN_BACK)
|
||||
return RETURN_BACK;
|
||||
return disk_prepare();
|
||||
@ -304,7 +304,7 @@ enum return_type disk_prepare(void)
|
||||
results = try_with_device(*medias);
|
||||
if (results == RETURN_OK)
|
||||
return RETURN_OK;
|
||||
i = ask_insmod(MEDIA_ADAPTERS);
|
||||
i = ask_insmod();
|
||||
if (i == RETURN_BACK)
|
||||
return RETURN_BACK;
|
||||
return disk_prepare();
|
||||
@ -319,7 +319,7 @@ enum return_type disk_prepare(void)
|
||||
results = try_with_device(choice);
|
||||
if (results == RETURN_OK)
|
||||
return RETURN_OK;
|
||||
i = ask_insmod(MEDIA_ADAPTERS);
|
||||
i = ask_insmod();
|
||||
if (i == RETURN_BACK)
|
||||
return RETURN_BACK;
|
||||
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
|
285
init.c
285
init.c
@ -19,11 +19,18 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef INIT_HEADERS
|
||||
#include "init-libc-headers.h"
|
||||
#else
|
||||
#include INIT_HEADERS
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#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"
|
||||
|
||||
@ -31,9 +38,13 @@
|
||||
#define TIOCSCTTY 0x540
|
||||
#endif
|
||||
|
||||
#define MKDEV(ma,mi) ((ma)<<8 | (mi))
|
||||
#define RAMFS_MAGIC 0x858458f6
|
||||
#define TMPFS_MAGIC 0x01021994
|
||||
|
||||
char * env[] = {
|
||||
"PATH=/usr/bin:/bin:/sbin:/usr/sbin:/usr/X11R6/bin",
|
||||
"LD_LIBRARY_PATH=/lib:/usr/lib:/usr/X11R6/lib",
|
||||
"PATH=/usr/bin:/bin:/sbin:/usr/sbin",
|
||||
"LD_LIBRARY_PATH=/lib:/usr/lib",
|
||||
"HOME=/",
|
||||
"TERM=linux",
|
||||
"TERMINFO=/etc/terminfo",
|
||||
@ -42,6 +53,11 @@ char * env[] = {
|
||||
|
||||
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:
|
||||
*
|
||||
@ -51,21 +67,14 @@ char ** myenv = NULL;
|
||||
* 4) run from a floppy that's been loaded into a ramdisk
|
||||
*/
|
||||
|
||||
int klog_pid;
|
||||
|
||||
|
||||
void fatal_error(const char *msg)
|
||||
void fatal(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);
|
||||
}
|
||||
|
||||
void print_error(char *msg)
|
||||
{
|
||||
printf("E: %s\n", msg);
|
||||
}
|
||||
|
||||
void print_warning(char *msg)
|
||||
void warn(char *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
|
||||
* (2) listens to /dev/log and copy also this stuff (log from programs)
|
||||
*/
|
||||
void doklog()
|
||||
pid_t doklog()
|
||||
{
|
||||
int in, out, i, ii;
|
||||
int log;
|
||||
pid_t pid;
|
||||
char buf[1024];
|
||||
|
||||
/* open kernel message logger */
|
||||
in = open("/proc/kmsg", O_RDONLY,0);
|
||||
if (in < 0) {
|
||||
print_error("could not open /proc/kmsg");
|
||||
return;
|
||||
}
|
||||
if ((in = open("/proc/kmsg", O_RDONLY, 0)) < 0)
|
||||
fatal("failed to open /proc/kmsg");
|
||||
|
||||
if ((log = open("/tmp/syslog", O_WRONLY | O_CREAT, 0644)) < 0) {
|
||||
perror("/tmp/syslog");
|
||||
print_error("error opening /tmp/syslog");
|
||||
sleep(5);
|
||||
return;
|
||||
}
|
||||
if (mknod("/dev/tty4", S_IFCHR, MKDEV(4, 4)) < 0 ||
|
||||
(out = open("/dev/tty4", O_WRONLY, 0)) < 0)
|
||||
fatal("failed to open /dev/tty4");
|
||||
|
||||
if ((klog_pid = fork())) {
|
||||
if ((pid = fork())) {
|
||||
if (pid < 0) fatal("doklog");
|
||||
close(in);
|
||||
close(log);
|
||||
return;
|
||||
} else {
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
}
|
||||
|
||||
out = open("/dev/tty4", O_WRONLY, 0);
|
||||
if (out < 0) {
|
||||
perror("can't open /dev/tty4");
|
||||
print_warning("couldn't open tty for syslog -- still using /tmp/syslog\n");
|
||||
close(out);
|
||||
return pid;
|
||||
}
|
||||
|
||||
/* child */
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
|
||||
/* disable on-console syslog output */
|
||||
syslog(8, NULL, 1);
|
||||
klogctl(8, NULL, 1);
|
||||
|
||||
while (1) {
|
||||
i = read(in, buf, sizeof(buf));
|
||||
if (i > 0) {
|
||||
if (out >= 0)
|
||||
ii = write(out, buf, i);
|
||||
ii = write(log, buf, i);
|
||||
}
|
||||
while (1)
|
||||
if ((i = read(in, buf, sizeof(buf))) > 0)
|
||||
ii = write(out, 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;
|
||||
|
||||
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;
|
||||
return;
|
||||
}
|
||||
@ -140,11 +147,11 @@ void grab_env(int fd)
|
||||
buf[i] = '\0';
|
||||
|
||||
if ((ep = myenv = malloc(sizeof(char *) * 32)) == NULL) {
|
||||
print_error("can't malloc env");
|
||||
warn("can't malloc env");
|
||||
myenv = env;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
*ep++ = p;
|
||||
p += strlen(p);
|
||||
@ -252,7 +259,7 @@ static int nuke(const char *what)
|
||||
|
||||
if ( err ) {
|
||||
errno = err;
|
||||
fatal_error(what);
|
||||
fatal(what);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -279,7 +286,7 @@ void unmount_filesystems(void)
|
||||
|
||||
fd = open("/proc/mounts", O_RDONLY, 0);
|
||||
if (fd < 1) {
|
||||
print_error("failed to open /proc/mounts");
|
||||
warn("failed to open /proc/mounts");
|
||||
sleep(2);
|
||||
return;
|
||||
}
|
||||
@ -332,66 +339,89 @@ void unmount_filesystems(void)
|
||||
}
|
||||
|
||||
if (nb) {
|
||||
printf("failed to umount some filesystems\n");
|
||||
while (1);
|
||||
fatal("failed to umount some filesystems\n");
|
||||
}
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
struct stat rst, cst, ist;
|
||||
struct statfs sfs;
|
||||
pid_t installpid, childpid;
|
||||
pid_t pid, klogpid, udevpid;
|
||||
int wait_status;
|
||||
int fd;
|
||||
int fd = -1;
|
||||
int fds[2];
|
||||
int end_stage1 = 0;
|
||||
|
||||
|
||||
if (mount("/proc", "/proc", "proc", 0, NULL))
|
||||
fatal_error("Unable to mount proc filesystem");
|
||||
if (mount("/sysfs", "/sys", "sysfs", 0, NULL))
|
||||
fatal_error("Unable to mount sysfs filesystem");
|
||||
|
||||
fatal("failed to mount proc filesystem");
|
||||
if (mount("sysfs", "/sys", "sysfs", 0, NULL))
|
||||
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 */
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGTSTP, SIG_IGN);
|
||||
|
||||
fd = open("/dev/console", O_RDWR, 0);
|
||||
if (fd < 0)
|
||||
fatal_error("failed to open /dev/console");
|
||||
|
||||
if (mknod("/dev/console", S_IFCHR, MKDEV(5, 1)) < 0 ||
|
||||
(fd = open("/dev/console", O_RDWR, 0)) < 0) {
|
||||
fatal("failed to open /dev/console");
|
||||
}
|
||||
|
||||
dup2(fd, 0);
|
||||
dup2(fd, 1);
|
||||
dup2(fd, 2);
|
||||
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?) */
|
||||
setsid();
|
||||
if (ioctl(0, TIOCSCTTY, NULL)) {
|
||||
perror("TIOCSCTTY");
|
||||
print_error("could not set new controlling tty");
|
||||
warn("could not set new controlling tty");
|
||||
}
|
||||
|
||||
char my_hostname[] = "localhost.localdomain";
|
||||
if (sethostname(my_hostname, sizeof(my_hostname)) < 0)
|
||||
print_error("could not set hostname");
|
||||
if (sethostname("localhost.localdomain", sizeof("localhost.localdomain")) < 0)
|
||||
warn("could not set hostname");
|
||||
|
||||
/* the default domainname (as of 2.0.35) is "(none)", which confuses glibc */
|
||||
if (setdomainname("", 0) < 0)
|
||||
print_error("could not set domainname");
|
||||
warn("could not set domainname");
|
||||
|
||||
if (mkdir("/dev/.initramfs", 0755) < 0 ||
|
||||
mkdir("/dev/pts", 0755) < 0 ||
|
||||
mkdir("/dev/shm", 0755) < 0)
|
||||
fatal("mkdir\n");
|
||||
|
||||
doklog();
|
||||
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
|
||||
when:
|
||||
@ -404,33 +434,19 @@ int main(int argc, char **argv)
|
||||
|
||||
/* create a pipe for env passing */
|
||||
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[1], F_SETFD, 0);
|
||||
|
||||
if (!(installpid = fork())) {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
pid = spawn(stage);
|
||||
close(fds[1]);
|
||||
|
||||
while (!end_stage1) {
|
||||
childpid = wait4(-1, &wait_status, 0, NULL);
|
||||
if (childpid == installpid)
|
||||
end_stage1 = 1;
|
||||
}
|
||||
while (pid != wait(&wait_status));
|
||||
|
||||
if (!(WIFEXITED(wait_status))) {
|
||||
/* 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))
|
||||
printf("-- received signal %d", WTERMSIG(wait_status));
|
||||
printf("\n");
|
||||
@ -455,15 +471,23 @@ int main(int argc, char **argv)
|
||||
|
||||
grab_env(fds[0]);
|
||||
|
||||
kill(klog_pid, 9);
|
||||
waitpid(klog_pid, &wait_status, 0);
|
||||
if (waitpid(spawn(udevsettle), &wait_status, 0) < 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 ...");
|
||||
|
||||
/* rest was seamlessy stolen from klibc */
|
||||
/* First, change to the new root directory */
|
||||
if (chdir(STAGE2_LOCATION))
|
||||
fatal_error("chdir to new root");
|
||||
fatal("chdir to new root");
|
||||
|
||||
/* This is a potentially highly destructive program. Take some
|
||||
extra precautions. */
|
||||
@ -471,71 +495,66 @@ int main(int argc, char **argv)
|
||||
/* Make sure the current directory is not on the same filesystem
|
||||
as the root directory */
|
||||
if ( stat("/", &rst) || stat(".", &cst) )
|
||||
fatal_error("stat");
|
||||
fatal("stat");
|
||||
|
||||
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 */
|
||||
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 */
|
||||
if ( statfs("/", &sfs) )
|
||||
fatal_error("statfs /");
|
||||
fatal("statfs /");
|
||||
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... */
|
||||
|
||||
/* overmount image under new root if needed */
|
||||
if ( statfs(IMAGE_LOCATION, &sfs) )
|
||||
fatal_error("statfs "IMAGE_LOCATION);
|
||||
fatal("statfs "IMAGE_LOCATION);
|
||||
/* if something is mounted under IMAGE_LOCATION ? */
|
||||
if ( sfs.f_type != RAMFS_MAGIC && sfs.f_type != TMPFS_MAGIC ) {
|
||||
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 */
|
||||
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 ( mount(IMAGE_LOCATION, "." IMAGE_LOCATION "/isolinux", NULL, MS_MOVE, NULL) )
|
||||
fatal_error("overmounting nested image location");
|
||||
fatal("overmounting nested image location");
|
||||
}
|
||||
|
||||
umount("/sys");
|
||||
umount("/proc/bus/usb");
|
||||
umount("/proc");
|
||||
|
||||
if (mount("/dev", "./dev", NULL, MS_MOVE, NULL))
|
||||
fatal("overmounting /dev");
|
||||
|
||||
/* Delete rootfs contents */
|
||||
if ( nuke_dir("/") )
|
||||
fatal_error("nuking initramfs contents");
|
||||
if (nuke_dir("/"))
|
||||
fatal("nuking initramfs contents");
|
||||
|
||||
/* Overmount the root */
|
||||
if ( mount(".", "/", NULL, MS_MOVE, NULL) )
|
||||
fatal_error("overmounting root");
|
||||
if (mount(".", "/", NULL, MS_MOVE, NULL))
|
||||
fatal("overmounting root");
|
||||
|
||||
/* chroot, chdir */
|
||||
if (chroot(".") || chdir("/"))
|
||||
fatal_error("chroot");
|
||||
|
||||
/* Open /dev/console */
|
||||
if ((fd = open("/dev/console", O_RDWR)) != -1) {
|
||||
dup2(fd, 0);
|
||||
dup2(fd, 1);
|
||||
dup2(fd, 2);
|
||||
close(fd);
|
||||
}
|
||||
fatal("chroot");
|
||||
|
||||
/* Check for given init */
|
||||
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 */
|
||||
printf(" done.\n");
|
||||
|
||||
argv[0] = STAGE2_BINNAME;
|
||||
execve(argv[0], argv, myenv);
|
||||
fatal_error("stage2"); /* Failed to spawn init */
|
||||
fatal("stage2"); /* Failed to spawn init */
|
||||
return 0;
|
||||
}
|
||||
|
@ -63,14 +63,15 @@ int
|
||||
set_loop (const char *device, const char *file)
|
||||
{
|
||||
struct loop_info loopinfo;
|
||||
int fd, ffd, mode;
|
||||
int i, fd, ffd, mode;
|
||||
|
||||
mode = O_RDONLY;
|
||||
|
||||
if ((ffd = open (file, mode)) < 0)
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
@ -139,7 +140,7 @@ lomount(char *loopfile, char *where)
|
||||
flag = MS_MGC_VAL;
|
||||
flag |= MS_RDONLY;
|
||||
|
||||
my_insmod("loop", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("loop", NULL);
|
||||
|
||||
if (set_loop(loopdev, loopfile)) {
|
||||
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
|
302
modules.c
302
modules.c
@ -21,6 +21,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mount.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
@ -28,25 +29,12 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef CONFIG_USE_ZLIB
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
#include "stage1.h"
|
||||
#include "log.h"
|
||||
#include "frontend.h"
|
||||
#include "mount.h"
|
||||
#include "modules_descr.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)
|
||||
{
|
||||
switch (err) {
|
||||
@ -108,295 +96,45 @@ int insmod_call(char *pathname, char *params)
|
||||
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;
|
||||
char module_name[50];
|
||||
int len, i, rc;
|
||||
|
||||
strncpy(module_name, mod_name, sizeof(module_name));
|
||||
strcat(module_name, ".ko");
|
||||
i = mar_extract_inplace(archive_name, module_name, &file, &len);
|
||||
if (i == 1) {
|
||||
log_message("file-not-found-in-archive %s", module_name);
|
||||
return INSMOD_FAILED_FILE_NOT_FOUND;
|
||||
int pid, status;
|
||||
if (!(pid = fork())) {
|
||||
char * argv[4];
|
||||
argv[0] = "/sbin/modprobe";
|
||||
argv[1] = mod_name;
|
||||
argv[2] = options;
|
||||
argv[3] = NULL;
|
||||
execve(argv[0], argv, NULL);
|
||||
log_message("modprobe %s failed", mod_name);
|
||||
}
|
||||
if (i != 0)
|
||||
return 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;
|
||||
waitpid(pid, &status, 0);
|
||||
return WIFEXITED(status) ? INSMOD_OK : INSMOD_FAILED;
|
||||
}
|
||||
|
||||
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;
|
||||
#ifndef DISABLE_NETWORK
|
||||
char ** net_devices = NULL;
|
||||
#endif
|
||||
|
||||
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)
|
||||
return INSMOD_OK;
|
||||
|
||||
i = insmod_with_deps(mod_name, options);
|
||||
i = modprobe(mod_name, options);
|
||||
if (i == 0) {
|
||||
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
|
||||
log_message("warning, insmod failed (%s %s) (%d)", mod_name, options, 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 };
|
||||
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;
|
||||
return RETURN_ERROR;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
FILE * f;
|
||||
@ -406,7 +144,7 @@ void update_modules(void)
|
||||
|
||||
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) {
|
||||
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++;
|
||||
}
|
||||
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) {
|
||||
log_message("\t%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 };
|
||||
|
||||
void init_modules_insmoding(void);
|
||||
enum insmod_return my_insmod(const char * mod_name, enum driver_type type, char * options);
|
||||
enum return_type ask_insmod(enum driver_type);
|
||||
enum return_type ask_insmod();
|
||||
enum insmod_return my_insmod(const char * mod_name, char * options);
|
||||
void update_modules(void);
|
||||
|
||||
struct module_deps_elem {
|
||||
char * name;
|
||||
char ** deps;
|
||||
};
|
||||
|
||||
extern int disable_modules;
|
||||
|
||||
#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
|
||||
if (!strcmp(fs, "squashfs"))
|
||||
my_insmod("squashfs", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("squashfs", NULL);
|
||||
|
||||
if (!strcmp(fs, "ext2"))
|
||||
my_insmod("ext2", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("ext2", NULL);
|
||||
|
||||
if (!strcmp(fs, "vfat")) {
|
||||
my_insmod("vfat", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("vfat", NULL);
|
||||
opts = "check=relaxed";
|
||||
}
|
||||
|
||||
if (!strcmp(fs, "ntfs"))
|
||||
my_insmod("ntfs", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("ntfs", NULL);
|
||||
|
||||
if (!strcmp(fs, "reiserfs"))
|
||||
my_insmod("reiserfs", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("reiserfs", NULL);
|
||||
|
||||
if (!strcmp(fs, "iso9660"))
|
||||
my_insmod("isofs", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("isofs", NULL);
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_NETWORK
|
||||
if (!strcmp(fs, "nfs")) {
|
||||
my_insmod("nfs", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("nfs", NULL);
|
||||
log_message("preparing nfsmount for %s", dev);
|
||||
rc = nfsmount_prepare(dev, &opts);
|
||||
if (rc != 0)
|
||||
|
@ -515,7 +515,7 @@ static enum return_type bringup_networking(struct interface_info * intf)
|
||||
static struct interface_info loopback;
|
||||
enum return_type results = RETURN_ERROR;
|
||||
|
||||
my_insmod("af_packet", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("af_packet", NULL);
|
||||
|
||||
while (results != RETURN_OK) {
|
||||
results = setup_network_interface(intf);
|
||||
@ -563,7 +563,7 @@ static char * interface_select(void)
|
||||
|
||||
if (count == 0) {
|
||||
stg1_error_message("No NET device found.");
|
||||
i = ask_insmod(NETWORK_DEVICES);
|
||||
i = ask_insmod();
|
||||
if (i == RETURN_BACK)
|
||||
return NULL;
|
||||
return interface_select();
|
||||
|
395
probing.c
395
probing.c
@ -33,10 +33,10 @@
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
// #include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mount.h>
|
||||
@ -54,40 +54,6 @@ struct media_info {
|
||||
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
|
||||
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_ptr = 0;
|
||||
|
||||
void prepare_intf_descr(const char * intf_descr)
|
||||
{
|
||||
intf_descr_for_discover = strdup(intf_descr);
|
||||
}
|
||||
|
||||
void net_discovered_interface(char * intf_name)
|
||||
{
|
||||
if (!intf_descr_for_discover) {
|
||||
@ -128,335 +89,19 @@ void net_discovered_interface(char * intf_name)
|
||||
|
||||
char * get_net_intf_description(char * intf_name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < net_descr_number ; i++)
|
||||
if (!strcmp(net_descriptions[i].intf_name, intf_name))
|
||||
return net_descriptions[i].intf_description;
|
||||
return strdup("unknown");
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct pci_module_map * get_pci_ids()
|
||||
{
|
||||
static struct pci_module_map * pcidb = NULL;
|
||||
struct pci_module_map *new, *last = NULL;
|
||||
char buf[50];
|
||||
int v, d;
|
||||
FILE *f;
|
||||
|
||||
if (pcidb) return pcidb;
|
||||
char dev[SYSFS_PATH_MAX];
|
||||
char drv[SYSFS_PATH_MAX];
|
||||
ssize_t i;
|
||||
|
||||
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();
|
||||
snprintf(dev, SYSFS_PATH_MAX, "/sys/class/net/%s/device/driver", intf_name);
|
||||
if ((i = readlink(dev, drv, SYSFS_PATH_MAX)) > 0) {
|
||||
drv[i] = '\0';
|
||||
return strdup(basename(drv));
|
||||
} else {
|
||||
update_splash();
|
||||
pci_probe(type);
|
||||
update_splash();
|
||||
usb_probe(type);
|
||||
update_splash();
|
||||
return strdup("unknown");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_MEDIAS
|
||||
static struct media_info * medias = NULL;
|
||||
@ -473,9 +118,7 @@ static void find_media(void)
|
||||
char *s;
|
||||
int count = 0;
|
||||
|
||||
if (!medias)
|
||||
probe_that_type(MEDIA_ADAPTERS);
|
||||
else
|
||||
if (medias)
|
||||
free(medias); /* that does not free the strings, by the way */
|
||||
|
||||
if ((dir = opendir("/sys/block")) == NULL) {
|
||||
@ -601,13 +244,8 @@ void get_medias(enum media_type media, char *** names, char *** models)
|
||||
}
|
||||
#endif /* DISABLE_MEDIAS */
|
||||
|
||||
void probe_hiddev()
|
||||
{
|
||||
usb_probe(HID_DEVICES);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_NETWORK
|
||||
int net_device_available(char * device)
|
||||
static int net_device_available(char * device)
|
||||
{
|
||||
struct ifreq req;
|
||||
int s;
|
||||
@ -633,7 +271,6 @@ char ** get_net_devices(void)
|
||||
char * devices[] = {
|
||||
"eth0", "eth1", "eth2", "eth3", "eth4", "eth5",
|
||||
"tr0",
|
||||
"plip0", "plip1", "plip2",
|
||||
"fddi0",
|
||||
#ifdef ENABLE_USBNET
|
||||
"usb0", "usb1", "usb2", "usb3",
|
||||
@ -643,14 +280,6 @@ char ** get_net_devices(void)
|
||||
char ** ptr = devices;
|
||||
char * tmp[50];
|
||||
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) {
|
||||
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 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 probe_hiddev();
|
||||
char ** get_net_devices(void);
|
||||
void net_discovered_interface(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
|
||||
#define SYSFS_PATH_MAX 256
|
||||
#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
|
||||
*/
|
||||
|
@ -2,27 +2,27 @@
|
||||
%def_with splash
|
||||
|
||||
Name: propagator
|
||||
Version: 20070301
|
||||
Release: alt7
|
||||
Version: 20080301
|
||||
Release: alt1
|
||||
|
||||
Summary: 'Early userspace' set of binaries
|
||||
License: GPL
|
||||
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
|
||||
%name is a set of binaries useful in 'early userspace' environment,
|
||||
including init and various helpers for hw probing and bootstrapping.
|
||||
|
||||
%prep
|
||||
%setup -c
|
||||
%setup
|
||||
|
||||
%build
|
||||
make %{?_with_shell:WITH_SHELL=t} %{?_with_splash:WITH_SPLASH=t} \
|
||||
LIBDIR=%_libdir CFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE"
|
||||
make %{?_with_shell:WITH_SHELL=t} %{?_with_splash:WITH_SPLASH=t}
|
||||
|
||||
%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
|
||||
|
||||
%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
|
||||
- do not show %name build date on tty1, closes \#12491
|
||||
|
||||
|
111
stage1.c
111
stage1.c
@ -47,10 +47,6 @@
|
||||
#include "mount.h"
|
||||
#include "insmod.h"
|
||||
|
||||
#ifdef ENABLE_PCMCIA
|
||||
#include "pcmcia/pcmcia.h"
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_CDROM
|
||||
#include "cdrom.h"
|
||||
#endif
|
||||
@ -180,65 +176,6 @@ static void spawn_splash(void)
|
||||
#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)
|
||||
return;
|
||||
|
||||
my_insmod("floppy", ANY_DRIVER_TYPE, NULL);
|
||||
my_insmod("floppy", NULL);
|
||||
|
||||
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.");
|
||||
@ -298,27 +235,6 @@ static void expert_third_party_modules(void)
|
||||
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)
|
||||
{
|
||||
enum return_type ret;
|
||||
char * pcmcia_adapter = NULL;
|
||||
char buf[128];
|
||||
|
||||
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();
|
||||
log_message("welcome to the %s install (alt-stage1, built " __DATE__ " " __TIME__")", version);
|
||||
process_cmdline();
|
||||
@ -427,19 +332,8 @@ int main(int argc, char **argv, char **env)
|
||||
spawn_splash();
|
||||
prepare_progress();
|
||||
update_splash();
|
||||
init_modules_insmoding();
|
||||
snprintf(buf, sizeof(buf), "Welcome to %s", version);
|
||||
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();
|
||||
|
||||
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");
|
||||
|
||||
/* all went good */
|
||||
if (interactive_pid != 0)
|
||||
kill(interactive_pid, 9);
|
||||
|
||||
if (shell_pid != 0)
|
||||
kill(shell_pid, 9);
|
||||
|
||||
|
10
tools.c
10
tools.c
@ -30,9 +30,9 @@
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <bzlib.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/poll.h>
|
||||
|
||||
#include "stage1.h"
|
||||
#include "log.h"
|
||||
#include "mount.h"
|
||||
@ -520,12 +520,12 @@ int string_array_length(char ** a)
|
||||
|
||||
int do_losetup(char * device, char * target)
|
||||
{
|
||||
int loopfd, targfd;
|
||||
int i, loopfd, targfd;
|
||||
struct loop_info loopInfo;
|
||||
|
||||
my_insmod("loop", ANY_DRIVER_TYPE, NULL);
|
||||
|
||||
loopfd = open( device, O_RDONLY );
|
||||
my_insmod("loop", NULL);
|
||||
/* wait for udev's dust settles down */
|
||||
for (i=3; i && (loopfd = open(device, O_RDONLY)) < 0; --i, sleep(1));
|
||||
if ( loopfd < 0 )
|
||||
{
|
||||
log_message( "losetup: error opening %s: %s", device, strerror(errno) );
|
||||
|
Loading…
Reference in New Issue
Block a user