diff options
-rw-r--r-- | mdk-stage1/Makefile | 14 | ||||
-rw-r--r-- | mdk-stage1/cdrom.c | 12 | ||||
-rw-r--r-- | mdk-stage1/disk.c | 11 | ||||
-rw-r--r-- | mdk-stage1/frontend.h | 3 | ||||
-rw-r--r-- | mdk-stage1/init.c | 34 | ||||
-rw-r--r-- | mdk-stage1/minilibc.c | 15 | ||||
-rw-r--r-- | mdk-stage1/minilibc.h | 1 | ||||
-rw-r--r-- | mdk-stage1/modules.c | 71 | ||||
-rw-r--r-- | mdk-stage1/modules.h | 5 | ||||
-rw-r--r-- | mdk-stage1/mount.c | 11 | ||||
-rw-r--r-- | mdk-stage1/network.c | 2 | ||||
-rw-r--r-- | mdk-stage1/newt-frontend.c | 20 | ||||
-rw-r--r-- | mdk-stage1/pci-resource/Makefile | 26 | ||||
-rwxr-xr-x | mdk-stage1/pci-resource/update-pci-ids.pl | 41 | ||||
-rw-r--r-- | mdk-stage1/probing.c | 102 | ||||
-rw-r--r-- | mdk-stage1/probing.h | 3 | ||||
-rw-r--r-- | mdk-stage1/stage1-data/stage1-with-sash.tar.bz2 | bin | 345007 -> 345069 bytes | |||
-rw-r--r-- | mdk-stage1/stage1.c | 17 | ||||
-rw-r--r-- | mdk-stage1/stdio-frontend.c | 63 | ||||
-rw-r--r-- | mdk-stage1/tools.c | 22 |
20 files changed, 362 insertions, 111 deletions
diff --git a/mdk-stage1/Makefile b/mdk-stage1/Makefile index 1ce2e3eba..1bf95ada9 100644 --- a/mdk-stage1/Makefile +++ b/mdk-stage1/Makefile @@ -40,15 +40,21 @@ INITSRC = minilibc.c init.c INITOBJS = $(subst .c,.o,$(INITSRC)) - #- frontend + #- frontends NEWT_FRONTEND_SRC = newt-frontend.c NEWT_FRONTEND_LIBS = /usr/lib/libnewt.a /usr/lib/libslang.a STDIO_FRONTEND_SRC = stdio-frontend.c STDIO_FRONTEND_LIBS = -FRONTEND_OBJS = $(subst .c,.o,$(STDIO_FRONTEND_SRC)) -FRONTEND_LIBS = $(STDIO_FRONTEND_LIBS) +WSLIB_FRONTEND_SRC = wslib-frontend.c +WSLIB_FRONTEND_LIBS = /usr/lib/libwslib.a + + #- default frontend is newt +F = NEWT + +FRONTEND_OBJS = $(subst .c,.o,$($(F)_FRONTEND_SRC)) +FRONTEND_LIBS = $($(F)_FRONTEND_LIBS) #- stage1 itself (minus stage1.c) @@ -94,7 +100,7 @@ BINS = init stage1-network #BINS += stage1-all #endif -DIRS = mar insmod-busybox +DIRS = mar insmod-busybox pci-resource all: dirs $(BINS) diff --git a/mdk-stage1/cdrom.c b/mdk-stage1/cdrom.c index 7a43e8ccc..901d4ac5c 100644 --- a/mdk-stage1/cdrom.c +++ b/mdk-stage1/cdrom.c @@ -49,7 +49,7 @@ static enum return_type try_with_device(char *dev_name) return results; } - if (access("/tmp/image/Mandrake", R_OK)) { + if (access("/tmp/image/Mandrake/mdkinst", R_OK)) { enum return_type results; umount("/tmp/image"); results = ask_yes_no("That CDROM disc does not seem to be a Linux-Mandrake Installation CDROM.\nRetry with another disc?"); @@ -78,10 +78,8 @@ enum return_type cdrom_prepare(void) my_insmod("ide-cd"); my_insmod("sr_mod"); - my_insmod("isofs"); - medias = get_medias(CDROM, QUERY_NAME); - medias_models = get_medias(CDROM, QUERY_MODEL); + get_medias(CDROM, &medias, &medias_models); ptr = medias; while (ptr && *ptr) { @@ -91,7 +89,7 @@ enum return_type cdrom_prepare(void) if (count == 0) { error_message("No CDROM device found."); - i = ask_scsi_insmod(); + i = ask_insmod(SCSI_ADAPTERS); if (i == RETURN_BACK) return RETURN_BACK; return cdrom_prepare(); @@ -101,7 +99,7 @@ enum return_type cdrom_prepare(void) results = try_with_device(*medias); if (results == RETURN_OK) return RETURN_OK; - i = ask_scsi_insmod(); + i = ask_insmod(SCSI_ADAPTERS); if (i == RETURN_BACK) return RETURN_BACK; return cdrom_prepare(); @@ -115,7 +113,7 @@ enum return_type cdrom_prepare(void) results = try_with_device(choice); if (results == RETURN_OK) return RETURN_OK; - i = ask_scsi_insmod(); + i = ask_insmod(SCSI_ADAPTERS); if (i == RETURN_BACK) return RETURN_BACK; return cdrom_prepare(); diff --git a/mdk-stage1/disk.c b/mdk-stage1/disk.c index 58658fc3c..e324f0bee 100644 --- a/mdk-stage1/disk.c +++ b/mdk-stage1/disk.c @@ -48,18 +48,17 @@ enum return_type disk_prepare(void) my_insmod("vfat"); my_insmod("reiserfs"); - medias = get_medias(DISK, QUERY_NAME); + get_medias(DISK, &medias, &medias_models); ptr = medias; while (ptr && *ptr) { - log_message("found DISK %s", *ptr); count++; ptr++; } if (count == 0) { error_message("No DISK drive found."); - i = ask_scsi_insmod(); + i = ask_insmod(SCSI_ADAPTERS); if (i == RETURN_BACK) return RETURN_BACK; return disk_prepare(); @@ -69,14 +68,12 @@ enum return_type disk_prepare(void) results = try_with_device(*medias); if (results == RETURN_OK) return RETURN_OK; - i = ask_scsi_insmod(); + i = ask_insmod(SCSI_ADAPTERS); if (i == RETURN_BACK) return RETURN_BACK; return disk_prepare(); } - medias_models = get_medias(DISK, QUERY_MODEL); - results = ask_from_list_comments("Please choose the DISK drive to use for the installation.", medias, medias_models, &choice); if (results != RETURN_OK) @@ -85,7 +82,7 @@ enum return_type disk_prepare(void) results = try_with_device(choice); if (results == RETURN_OK) return RETURN_OK; - i = ask_scsi_insmod(); + i = ask_insmod(SCSI_ADAPTERS); if (i == RETURN_BACK) return RETURN_BACK; return disk_prepare(); diff --git a/mdk-stage1/frontend.h b/mdk-stage1/frontend.h index ae125fa27..9e8f1974e 100644 --- a/mdk-stage1/frontend.h +++ b/mdk-stage1/frontend.h @@ -24,7 +24,8 @@ void init_frontend(void); void finish_frontend(void); -void error_message(char *msg); /* blocking */ +void error_message(char *msg, ...); /* blocking */ +void info_message(char *msg, ...); /* blocking */ void wait_message(char *msg, ...); /* non-blocking */ void remove_wait_message(void); diff --git a/mdk-stage1/init.c b/mdk-stage1/init.c index 3783bc8c7..22a381e6e 100644 --- a/mdk-stage1/init.c +++ b/mdk-stage1/init.c @@ -54,6 +54,7 @@ char * env[] = { */ int testing; +int klog_pid; void fatal_error(char *msg) @@ -107,12 +108,11 @@ void doklog() return; } - if (fork()) { + if ((klog_pid = fork())) { /* parent */ close(in); close(out); close(log); - sleep(1); return; } @@ -364,6 +364,17 @@ void disable_swap(void) } } +int is_rescue() +{ + int fd, size; + char buf[512]; + if ((fd = open("/proc/cmdline", O_RDONLY, 0)) == -1) + fatal_error("could not open /proc/cmdline"); + size = read(fd, buf, sizeof(buf)); + buf[size-1] = 0; + close(fd); + return (strstr(buf, "rescue") != NULL); +} int main(int argc, char **argv) { @@ -372,7 +383,7 @@ int main(int argc, char **argv) int fd; int abnormal_termination = 0; int end_stage2 = 0; - + /* getpid() != 1 should work, by linuxrc tends to get a larger pid */ testing = (getpid() > 50); @@ -452,8 +463,8 @@ int main(int argc, char **argv) printf("execing: %s\n", child_argv[0]); execve(child_argv[0], child_argv, env); - - exit(0); + printf("error in exec of stage1 :-(\n"); + return 0; } while (!end_stage2) { @@ -468,12 +479,16 @@ int main(int argc, char **argv) printf("-- received signal %d", WTERMSIG(wait_status)); printf("\n"); abnormal_termination = 1; - } - else - printf("back to stage1-initializer control -- install exited normally\n"); + } else if (is_rescue()) { + kill(klog_pid, 9); + printf("exiting stage1-initializer -- giving hand to rescue\n"); + return 0; + } + + printf("back to stage1-initializer control -- install exited normally\n"); if (testing) - exit(0); + return 0; sync(); sync(); @@ -501,6 +516,5 @@ int main(int argc, char **argv) while (1); } - exit(0); return 0; } diff --git a/mdk-stage1/minilibc.c b/mdk-stage1/minilibc.c index c98d87e24..ac0ffe334 100644 --- a/mdk-stage1/minilibc.c +++ b/mdk-stage1/minilibc.c @@ -188,6 +188,21 @@ char * strchr(char * str, int ch) 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; +} + void print_int(int fd, int i) { char buf[10]; diff --git a/mdk-stage1/minilibc.h b/mdk-stage1/minilibc.h index e6743a854..8682ae3d2 100644 --- a/mdk-stage1/minilibc.h +++ b/mdk-stage1/minilibc.h @@ -134,6 +134,7 @@ 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(int fd, char * string); diff --git a/mdk-stage1/modules.c b/mdk-stage1/modules.c index 70bdc4a9f..1b3e91d84 100644 --- a/mdk-stage1/modules.c +++ b/mdk-stage1/modules.c @@ -30,18 +30,12 @@ static struct module_deps_elem * modules_deps = NULL; +static char * archive_name = "/modules/modules.mar"; +static struct mar_stream s = { 0, NULL, NULL }; -/* unarchive and insmod given module - * WARNING: module must not contain the trailing ".o" - */ -int insmod_archived_file(char * mod_name) -{ - char * archive_name = "/modules/modules.mar"; - char module_name[50]; - char final_name[50] = "/tmp/"; - static struct mar_stream s = { 0, NULL, NULL }; - int i; +static int ensure_archive_opened(void) +{ /* don't consume too much memory */ if (s.first_element == NULL) { if (mar_open_file(archive_name, &s) != 0) { @@ -49,6 +43,20 @@ int insmod_archived_file(char * mod_name) return -1; } } + return 0; +} + +/* unarchive and insmod given module + * WARNING: module must not contain the trailing ".o" + */ +static int insmod_archived_file(const char * mod_name) +{ + char module_name[50]; + char final_name[50] = "/tmp/"; + int i, rc; + + if (ensure_archive_opened() == -1) + return -1; strncpy(module_name, mod_name, sizeof(module_name)); strncat(module_name, ".o", sizeof(module_name)); @@ -63,7 +71,11 @@ int insmod_archived_file(char * mod_name) strncat(final_name, mod_name, sizeof(final_name)); strncat(final_name, ".o", sizeof(final_name)); - return insmod_call(final_name); + rc = insmod_call(final_name); + if (rc) + log_message("\tfailed."); + unlink(final_name); /* sucking no space left on device */ + return rc; } @@ -157,7 +169,7 @@ int load_modules_dependencies(void) } -int insmod_with_deps(char * mod_name) +static int insmod_with_deps(const char * mod_name) { struct module_deps_elem * dep; @@ -180,7 +192,7 @@ int insmod_with_deps(char * mod_name) } -int my_insmod(char * mod_name) +int my_insmod(const char * mod_name) { int i; log_message("have to insmod %s", mod_name); @@ -196,7 +208,36 @@ int my_insmod(char * mod_name) } -enum return_type ask_scsi_insmod(void) +enum return_type ask_insmod(enum driver_type type) { - return ask_yes_no("Try to load a SCSI module"); + char * mytype; + char msg[200]; + enum return_type results; + char * choice; + + if (type == SCSI_ADAPTERS) + mytype = "SCSI"; + else if (type == NETWORK_DEVICES) + mytype = "NET"; + else + return RETURN_ERROR; + + if (ensure_archive_opened() == -1) + return -1; + + snprintf(msg, sizeof(msg), "Which driver should I try to gain %s access?", mytype); + + results = ask_from_list(msg, mar_list_contents(&s), &choice); + + if (results == RETURN_OK) { + int rc; + choice[strlen(choice)-2] = '\0'; /* remove trailing .o */ + rc = my_insmod(choice); + if (rc) { + error_message("Insmod failed."); + return RETURN_ERROR; + } else + return RETURN_OK; + } else + return results; } diff --git a/mdk-stage1/modules.h b/mdk-stage1/modules.h index cf7eadebe..29914f5fc 100644 --- a/mdk-stage1/modules.h +++ b/mdk-stage1/modules.h @@ -16,11 +16,12 @@ #define _MODULES_H_ #include "stage1.h" +#include "probing.h" int load_modules_dependencies(void); -int my_insmod(char * mod_name); +int my_insmod(const char * mod_name); -enum return_type ask_scsi_insmod(void); +enum return_type ask_insmod(enum driver_type); struct module_deps_elem { diff --git a/mdk-stage1/mount.c b/mdk-stage1/mount.c index ef0c0f676..6de11b480 100644 --- a/mdk-stage1/mount.c +++ b/mdk-stage1/mount.c @@ -26,6 +26,7 @@ #include <sys/stat.h> #include <sys/types.h> #include "log.h" +#include "modules.h" #include "mount.h" @@ -130,11 +131,15 @@ int my_mount(char *dev, char *location, char *fs) flags = MS_MGC_VAL; - if (!strcmp(fs, "vfat")) + if (!strcmp(fs, "vfat")) { + my_insmod("vfat"); opts = "check=relaxed"; - - if (!strcmp(fs, "iso9660")) + } + + if (!strcmp(fs, "iso9660")) { + my_insmod("isofs"); flags |= MS_RDONLY; + } rc = mount(dev, location, fs, flags, opts); diff --git a/mdk-stage1/network.c b/mdk-stage1/network.c index e6d0c6c4e..021a8d26a 100644 --- a/mdk-stage1/network.c +++ b/mdk-stage1/network.c @@ -32,6 +32,8 @@ enum return_type nfs_prepare(void) { + pci_probing(NETWORK_DEVICES); + return RETURN_ERROR; } diff --git a/mdk-stage1/newt-frontend.c b/mdk-stage1/newt-frontend.c index fcaeabcb6..8a057f98e 100644 --- a/mdk-stage1/newt-frontend.c +++ b/mdk-stage1/newt-frontend.c @@ -44,7 +44,7 @@ void init_frontend(void) newtDrawRootText(0, 0, "Welcome to Linux-Mandrake (" VERSION ") " __DATE__ " " __TIME__); - newtPushHelpLine(" <Tab>/<Alt-Tab> between elements, <Space>/<Enter> selects"); + newtPushHelpLine(" <Alt-F1> for here, <Alt-F3> to see the logs, <Alt-F4> for kernel msg"); } @@ -54,14 +54,25 @@ void finish_frontend(void) } -void error_message(char *msg) +void error_message(char *msg, ...) { - newtWinMessage("Error", "Ok", msg); + va_list args; + va_start(args, msg); + va_end(args); + newtWinMessagev("Error", "Ok", msg, args); +} + +void info_message(char *msg, ...) +{ + va_list args; + va_start(args, msg); + va_end(args); + newtWinMessagev("Notice", "Ok", msg, args); } void wait_message(char *msg, ...) { - int width = strlen(msg) + 12; + int width = 8; int height = 3; char * title = "Please wait..."; newtComponent t, f; @@ -77,6 +88,7 @@ void wait_message(char *msg, ...) if (buf) free(buf); buf = malloc(size); i = vsnprintf(buf, size, msg, args); + width += i; } while (i == size); va_end(args); diff --git a/mdk-stage1/pci-resource/Makefile b/mdk-stage1/pci-resource/Makefile new file mode 100644 index 000000000..ed16b6f67 --- /dev/null +++ b/mdk-stage1/pci-resource/Makefile @@ -0,0 +1,26 @@ + #****************************************************************************** + # + # $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 + # + #***************************************************************************** + + +pci-ids.h: ../../perl-install/pci_probing/pcitable + make -C ../../perl-install/pci_probing + perl update-pci-ids.pl > $@ + +clean: + rm -f pci-ids.h diff --git a/mdk-stage1/pci-resource/update-pci-ids.pl b/mdk-stage1/pci-resource/update-pci-ids.pl new file mode 100755 index 000000000..4aaa04b70 --- /dev/null +++ b/mdk-stage1/pci-resource/update-pci-ids.pl @@ -0,0 +1,41 @@ +#!/usr/bin/perl + +use lib "../../perl-install"; +use common qw(:common); +use pci_probing::pcitable; + +print ' +#define PCI_REVISION_ID 0x08 /* Revision ID */ + +struct pci_module_map { + unsigned short vendor; /* PCI vendor id */ + unsigned short device; /* PCI device id */ + const char *name; /* PCI human readable name */ + const char *module; /* module to load */ +}; + +'; + +my %t = (scsi => 'scsi', eth => 'net'); + +foreach (keys %t) { + print " +struct pci_module_map ${_}_pci_ids[] = { +"; + my %l; + foreach (glob("../../kernel*/lib/modules/*/$t{$_}/*.o")) { + m|([^/]*)\.o$|; + $l{$1} = 1; + } + while (my ($k, $v) = each %pci_probing::pcitable::ids) { + $l{$v->[1]} or next; + printf qq|\t{0x%04x , 0x%04x , ( "%s" ), ( "%s" )} ,\n|, + $k / 0x10000, $k % 0x10000, $v->[0], $v->[1]; + } + +print " +}; +int ${_}_num_ids=sizeof(${_}_pci_ids)/sizeof(struct pci_module_map); +" + +} diff --git a/mdk-stage1/probing.c b/mdk-stage1/probing.c index e252194ba..b41500314 100644 --- a/mdk-stage1/probing.c +++ b/mdk-stage1/probing.c @@ -38,19 +38,74 @@ #include "log.h" #include "frontend.h" #include "modules.h" +#include "pci-resource/pci-ids.h" #include "probing.h" -static void pci_probing(enum driver_type type) +void pci_probing(enum driver_type type) { - if (IS_EXPERT) { - error_message("You should be asked if you have some SCSI."); - } else { -/* wait_message("Installing SCSI module..."); - my_insmod("advansys"); - remove_wait_message(); -*/ } + if (IS_EXPERT) + ask_insmod(type); + else { + /* do it automatically */ + char * mytype; + FILE * f; + int len; + char buf[100]; + struct pci_module_map * pcidb; + + if (type == SCSI_ADAPTERS) + mytype = "SCSI"; + else if (type == NETWORK_DEVICES) + mytype = "NET"; + else + return; + + f = fopen("/proc/bus/pci/devices", "rb"); + + if (!f) { + log_message("PCI: could not open proc file"); + return; + } + + switch (type) { + case SCSI_ADAPTERS: + pcidb = scsi_pci_ids; + len = scsi_num_ids; + break; + case NETWORK_DEVICES: + pcidb = eth_pci_ids; + len = eth_num_ids; + break; + default: + return; + } + + while (1) { + int i, garb, vendor, device; + + if (!fgets(buf,100,f)) break; + + sscanf(buf, "%x %04x%04x", &garb, &vendor, &device); + + for (i = 0; i < len; i++) { + if (pcidb[i].vendor == vendor && pcidb[i].device == device) { + log_message("PCI: found suggestion for %s (%s)", pcidb[i].name, pcidb[i].module); + if (type == SCSI_ADAPTERS) { + /* insmod takes time, let's use the wait message */ + wait_message("Installing %s driver for %s", mytype, pcidb[i].name); + my_insmod(pcidb[i].module); + remove_wait_message(); + } else if (type == NETWORK_DEVICES) { + /* insmod is quick, let's use the info message */ + info_message("Found %s driver for %s", mytype, pcidb[i].name); + my_insmod(pcidb[i].module); + } + } + } + } + } } @@ -64,8 +119,10 @@ static void find_media(void) int count; int fd; - if (medias) - return; + if (!medias) + pci_probing(SCSI_ADAPTERS); + else + free(medias); /* that does not free the strings, by the way */ /* ----------------------------------------------- */ log_message("looking for ide media"); @@ -138,7 +195,6 @@ static void find_media(void) /* ----------------------------------------------- */ log_message("looking for scsi media"); - pci_probing(SCSI_ADAPTERS); fd = open("/proc/scsi/scsi", O_RDONLY); if (fd != -1) { @@ -268,11 +324,11 @@ static void find_media(void) /* Finds by media */ -char ** get_medias(enum media_type media, enum media_query_type qtype) +void get_medias(enum media_type media, char *** names, char *** models) { struct media_info * m; - char * tmp[50]; - char ** answer; + char * tmp_names[50]; + char * tmp_models[50]; int count; find_media(); @@ -282,19 +338,17 @@ char ** get_medias(enum media_type media, enum media_query_type qtype) count = 0; while (m && m->name) { if (m->type == media) { - if (qtype == QUERY_NAME) - tmp[count] = m->name; - else - tmp[count] = m->model; - count++; + tmp_names[count] = strdup(m->name); + tmp_models[count++] = strdup(m->model); } m++; } - tmp[count] = NULL; - count++; + tmp_names[count] = NULL; + tmp_models[count++] = NULL; - answer = (char **) malloc(sizeof(char *) * count); - memcpy(answer, tmp, sizeof(char *) * count); + *names = (char **) malloc(sizeof(char *) * count); + memcpy(*names, tmp_names, sizeof(char *) * count); - return answer; + *models = (char **) malloc(sizeof(char *) * count); + memcpy(*models, tmp_models, sizeof(char *) * count); } diff --git a/mdk-stage1/probing.h b/mdk-stage1/probing.h index 8fe43251e..4d29eabca 100644 --- a/mdk-stage1/probing.h +++ b/mdk-stage1/probing.h @@ -38,7 +38,8 @@ enum media_query_type { QUERY_NAME, QUERY_MODEL }; enum driver_type { SCSI_ADAPTERS, NETWORK_DEVICES }; -char ** get_medias(enum media_type media, enum media_query_type qtype); +void pci_probing(enum driver_type type); +void get_medias(enum media_type media, char *** names, char *** models); #endif diff --git a/mdk-stage1/stage1-data/stage1-with-sash.tar.bz2 b/mdk-stage1/stage1-data/stage1-with-sash.tar.bz2 Binary files differindex 5deeaa266..082976ffa 100644 --- a/mdk-stage1/stage1-data/stage1-with-sash.tar.bz2 +++ b/mdk-stage1/stage1-data/stage1-with-sash.tar.bz2 diff --git a/mdk-stage1/stage1.c b/mdk-stage1/stage1.c index 04cba80e7..b99435c59 100644 --- a/mdk-stage1/stage1.c +++ b/mdk-stage1/stage1.c @@ -56,11 +56,12 @@ void fatal_error(char *msg) } + /* spawns a shell on console #2 */ void spawn_shell(void) { - pid_t pid; int fd; + pid_t pid; char * shell_name = "/sbin/sash"; log_message("spawning a shell.."); @@ -94,6 +95,7 @@ void spawn_shell(void) } } + enum return_type method_select_and_prepare(void) { char * disk_install = "Hard disk"; @@ -180,8 +182,19 @@ int main(int argc, char **argv) fatal_error("symlink to /tmp/stage2 failed"); } + if (IS_RESCUE) { + int fd = open("/proc/sys/kernel/real-root-dev", O_RDWR); +#ifdef __sparc__ + write(fd, "0x1030000", sizeof("0x1030000")); /* ram3 or sparc */ +#else + write(fd, "0x103", sizeof("0x103")); /* ram3 */ +#endif + close(fd); + return 0; + } + if (IS_TESTING) - return 0; + return 0; argptr = stage2_args; *argptr++ = "/usr/bin/runinstall2"; diff --git a/mdk-stage1/stdio-frontend.c b/mdk-stage1/stdio-frontend.c index e702a79a7..bb6755176 100644 --- a/mdk-stage1/stdio-frontend.c +++ b/mdk-stage1/stdio-frontend.c @@ -48,37 +48,55 @@ void finish_frontend(void) { } -static char get_char_response(void) +static void get_any_response(void) { - unsigned char cmd1, cmd2; - + unsigned char t; fflush(stdout); - if (read(0, &cmd1, 1) > 0) { - fcntl(0, F_SETFL, O_NONBLOCK); - while (read(0, &cmd2, 1) > 0); - fcntl(0, F_SETFL, 0); - } + read(0, &t, 1); + fcntl(0, F_SETFL, O_NONBLOCK); + while (read(0, &t, 1) > 0); + fcntl(0, F_SETFL, 0); +} + +static int get_int_response(void) +{ + int i = 0; /* (0) tied to Cancel */ + fflush(stdout); + scanf(" %d", &i); + return i; +} - return cmd1; +static void blocking_msg(char *type, char *fmt, va_list args) +{ + printf(type); + vprintf(fmt, args); + get_any_response(); + printf("\n"); } +void error_message(char *msg, ...) +{ + va_list args; + va_start(args, msg); + va_end(args); + blocking_msg("> Error! ", msg, args); +} -void error_message(char *msg) +void info_message(char *msg, ...) { - printf("Error! %s", msg); - get_char_response(); - printf("\n"); + va_list args; + va_start(args, msg); + va_end(args); + blocking_msg("> Info! ", msg, args); } void wait_message(char *msg, ...) { va_list args; - printf("Please wait: "); va_start(args, msg); vprintf(msg, args); va_end(args); - fflush(stdout); } @@ -92,7 +110,6 @@ enum return_type ask_from_list_comments(char *msg, char ** elems, char ** elems_ { char ** sav_elems = elems; int i, j; - unsigned char answ; printf("> %s\n(0) Cancel\n", msg); i = 1; @@ -105,9 +122,7 @@ enum return_type ask_from_list_comments(char *msg, char ** elems, char ** elems_ printf("? "); - answ = get_char_response(); - - j = answ - '0'; + j = get_int_response(); if (j == 0) return RETURN_BACK; @@ -125,7 +140,6 @@ enum return_type ask_from_list(char *msg, char ** elems, char ** choice) { char ** sav_elems = elems; int i, j; - unsigned char answ; printf("> %s\n(0) Cancel\n", msg); i = 1; @@ -137,9 +151,7 @@ enum return_type ask_from_list(char *msg, char ** elems, char ** choice) printf("? "); - answ = get_char_response(); - - j = answ - '0'; + j = get_int_response(); if (j == 0) return RETURN_BACK; @@ -155,14 +167,11 @@ enum return_type ask_from_list(char *msg, char ** elems, char ** choice) enum return_type ask_yes_no(char *msg) { - unsigned char answ; int j; printf("> %s\n(0) Yes\n(1) No\n(2) Back\n? ", msg); - answ = get_char_response(); - - j = answ - '0'; + j = get_int_response(); if (j == 0) return RETURN_OK; diff --git a/mdk-stage1/tools.c b/mdk-stage1/tools.c index 71516b354..930c1027f 100644 --- a/mdk-stage1/tools.c +++ b/mdk-stage1/tools.c @@ -94,10 +94,18 @@ void process_cmdline(void) if (!strcmp(name, "cdrom")) set_param(MODE_CDROM); if (!strcmp(name, "special_stage2")) set_param(MODE_SPECIAL_STAGE2); } - tmp_params[p].name = NULL; + + if (IS_RESCUE) { + tmp_params[p].name = "special_stage2"; + tmp_params[p].value = "rescue"; + p++; + set_param(MODE_SPECIAL_STAGE2); + } - params = (struct cmdline_elem *) malloc(sizeof(struct cmdline_elem) * (p+1)); - memcpy(params, tmp_params, sizeof(struct cmdline_elem) * (p+1)); + tmp_params[p++].name = NULL; + + params = (struct cmdline_elem *) malloc(sizeof(struct cmdline_elem) * p); + memcpy(params, tmp_params, sizeof(struct cmdline_elem) * p); log_message("\tgot %d args", p); } @@ -184,7 +192,7 @@ enum return_type load_ramdisk(void) { char * img_name; gzFile st2; - char * ramdisk = "/dev/ram"; /* warning, verify that this file exists in the initrd (and actually is a ramdisk device file) */ + char * ramdisk = "/dev/ram3"; /* warning, verify that this file exists in the initrd (and actually is a ramdisk device file) */ int ram_fd; char buffer[4096]; char * stg2_name = get_param_valued("special_stage2"); @@ -194,6 +202,9 @@ enum return_type load_ramdisk(void) if (!stg2_name) stg2_name = "mdkinst"; + + if (IS_RESCUE) + stg2_name = "rescue"; img_name = malloc(strlen(begin_img) + strlen(stg2_name) + strlen(end_img) + 1); strcpy(img_name, begin_img); @@ -238,6 +249,9 @@ enum return_type load_ramdisk(void) gzclose(st2); close(ram_fd); + if (IS_RESCUE) + return RETURN_OK; /* fucksike, I lost several hours wondering why the kernel won't see the rescue if it is alreay mounted */ + if (my_mount(ramdisk, "/tmp/stage2", "ext2")) return RETURN_ERROR; |