From f4d0cbba874d45d1e31ebca5ef63df9fc4b6a4ec Mon Sep 17 00:00:00 2001 From: Guillaume Cottenceau Date: Thu, 18 Dec 2003 16:00:51 +0000 Subject: 2.6 kernel support --- kernel/check_mar.pl | 3 +- kernel/dependencies.pl | 3 +- kernel/update_kernel | 42 +++++++++++++++++++++------- mdk-stage1/modules.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++--- mdk-stage1/stage1.c | 11 +------- mdk-stage1/tools.c | 11 ++++++++ mdk-stage1/tools.h | 1 + 7 files changed, 118 insertions(+), 27 deletions(-) diff --git a/kernel/check_mar.pl b/kernel/check_mar.pl index aedbfdfe7..80c0cc86c 100755 --- a/kernel/check_mar.pl +++ b/kernel/check_mar.pl @@ -8,7 +8,6 @@ my $mar = '../mdk-stage1/mar/mar'; my %sanity_check = ( hd => [ qw(sym53c8xx), - if_(arch() !~ /x86_64/, 'initio'), if_(arch() !~ /ppc|x86_64/, 'advansys'), ], network => [ @@ -24,7 +23,7 @@ foreach (keys %sanity_check) { my $marfile = "all.modules/$main_version/${_}_modules.mar"; -e $marfile or die "ERROR: missing $marfile\n"; - my @l = map { /(\S+)\.o/ } `$mar -l $marfile`; + my @l = map { /(\S+)\.k?o/ } `$mar -l $marfile`; my @pbs = difference2($sanity_check{$_}, \@l); @pbs and die "ERROR: sanity check should prove that " . join(" ", @pbs) . " be part of $marfile\n"; diff --git a/kernel/dependencies.pl b/kernel/dependencies.pl index 10663b56b..e3be14212 100644 --- a/kernel/dependencies.pl +++ b/kernel/dependencies.pl @@ -3,10 +3,11 @@ use strict; use MDK::Common; use list_modules; +my $version = shift @ARGV; my $depfile = shift @ARGV; load_dependencies($depfile); print STDERR "Loaded dependencies from $depfile\n"; my @modules = uniq(map { dependencies_closure($_) } @ARGV); -print join " ", map { "$_.o" } @modules; +print join " ", map { $_ . ($version == 24 ? '.o' : '.ko') } @modules; print "\n"; diff --git a/kernel/update_kernel b/kernel/update_kernel index 5fad04dd6..6a5da3db4 100755 --- a/kernel/update_kernel +++ b/kernel/update_kernel @@ -23,32 +23,54 @@ function create_marfile() { $GIBASEDIR/mdk-stage1/mar/mar -c $marfile $* } +function kern_version() { + if echo $1 | grep -q ^2.4; then + version=24 + objects="*.o" + else + version=25 + objects="*.ko" + fi +} + function create_modules() { kernel_path=$1 kern=$2 echo "Updating modules in '`pwd`' for kernel '$kern'" - find $kernel_path/lib/modules/ -name "*.o" -exec cp -f {} . \; - /sbin/depmod -F $kernel_path/boot/System.map* -e *.o | perl -pe 's/\\\n//' \ - | perl -ne 's/\.o//g; s/[ \t]+/ /g; print if /: /' > modules.dep + kern_version $kern + find $kernel_path/lib/modules/ -name "$objects" -exec cp -f {} . \; + if [ $version -eq 24 ]; then + /sbin/depmod-24 -F $kernel_path/boot/System.map* -e *.o | perl -pe 's/\\\n//' \ + | perl -ne 's/\.o//g; s/[ \t]+/ /g; print if /: /' > modules.dep + else + cp $kernel_path/lib/modules/*/modules.dep . + perl -ni -e 's|/\S+/([^/]+)\.k?o|$1|g; print if /: /' modules.dep + fi perl -pi -e 's/((plip|ppa|imm): parport)/$1 parport_pc/' modules.dep - /sbin/modinfo -f '%{filename} %{description}\n' *.o | perl -lne 'print "$1\t$2" if /(.*?)\.o "(.*)"/' > modules.description + /sbin/modinfo-$version -f '%{filename} %{description}\n' $objects | perl -lne 'print "$1\t$2" if /(.*?)\.k?o "(.*)"/' > modules.description } function create_modules_mar() { - echo -n "stripping $kern: " - $GIBASEDIR/kernel/strip_modules *.o 2>/dev/null - echo "done" + kern_version $kern + + if [ $version -eq 24 ]; then + echo -n "stripping $kern: " + $GIBASEDIR/kernel/strip_modules *.o 2>/dev/null + echo "done" + else + echo "don't strip on 2.6 since it breaks modules" + fi if [ -z "$MOVE" ]; then echo -n "packdrake $kern: " - ls *.o | packdrake -b9s "modules.cz" 400000 + ls $objects | packdrake -b9s "modules.cz" 400000 echo "done" mv modules.cz ../modules.cz-$kern fi for i in network network_gigabit_usb network_gigabit network_usb cdrom hd hdcdrom_usb pcmcia all; do eval "modules=\$${i}_modules_raw" - modules_with_deps=`perl -I $GIBASEDIR/kernel $GIBASEDIR/kernel/dependencies.pl modules.dep $modules` + modules_with_deps=`perl -I $GIBASEDIR/kernel $GIBASEDIR/kernel/dependencies.pl $version modules.dep $modules` if [ -n "$MOVE" ]; then modules_with_deps="change_loop.o gzloop.o isofs.o zlib_inflate.o supermount.o $modules_with_deps"; fi eval "create_marfile ${i}_modules.mar $modules_with_deps" done @@ -80,7 +102,7 @@ if [ -n "$rpm" -a ! -e $ALL_KERNELS/$rpm ]; then else rpm2cpio $file | cpio -id fi - find -type f -name "*.o.gz" | xargs gunzip + find -type f -name "*.o.gz" -o -name "*.ko.gz" | xargs gunzip cd ../.. for dir in /tftpboot /var/lib/tftpboot; do diff --git a/mdk-stage1/modules.c b/mdk-stage1/modules.c index b3090fa18..6620c771d 100644 --- a/mdk-stage1/modules.c +++ b/mdk-stage1/modules.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "insmod.h" #include "stage1.h" #include "log.h" @@ -41,6 +42,48 @@ static struct module_deps_elem * modules_deps = NULL; static char * archive_name = "/modules/modules.mar"; int disable_modules = 0; +extern long init_module(void *, unsigned long, const char *); + + +static const char *moderror(int err) +{ + switch (err) { + case ENOEXEC: + return "Invalid module format"; + case ENOENT: + return "Unknown symbol in module"; + case ESRCH: + return "Module has wrong symbol version"; + case EINVAL: + return "Invalid parameters"; + default: + return strerror(err); + } +} + +static void *grab_file(const char *filename, unsigned long *size) +{ + unsigned int max = 16384; + int ret, fd; + void *buffer = malloc(max); + + fd = open(filename, O_RDONLY, 0); + if (fd < 0) + return NULL; + + *size = 0; + while ((ret = read(fd, buffer + *size, max - *size)) > 0) { + *size += ret; + if (*size == max) + buffer = realloc(buffer, max *= 2); + } + if (ret < 0) { + free(buffer); + buffer = NULL; + } + close(fd); + return buffer; +} /* unarchive and insmod given module * WARNING: module must not contain the trailing ".o" @@ -52,7 +95,10 @@ static enum insmod_return insmod_archived_file(const char * mod_name, char * opt int i, rc; strncpy(module_name, mod_name, sizeof(module_name)); - strcat(module_name, ".o"); + if (kernel_version() <= 4) + strcat(module_name, ".o"); + else + strcat(module_name, ".ko"); i = mar_extract_file(archive_name, module_name, "/tmp/"); if (i == 1) { log_message("file-not-found-in-archive %s (maybe you can try another boot floppy such as 'hdcdrom_usb.img' or 'network_gigabit_usb.img')", module_name); @@ -62,9 +108,26 @@ static enum insmod_return insmod_archived_file(const char * mod_name, char * opt return INSMOD_FAILED; strcat(final_name, mod_name); - strcat(final_name, ".o"); + if (kernel_version() <= 4) { + strcat(final_name, ".o"); + rc = insmod_call(final_name, options); + } else { + void *file; + unsigned long len; + + strcat(final_name, ".ko"); + file = grab_file(final_name, &len); + + if (!file) { + log_perror("\terror reading %s"); + return INSMOD_FAILED; + } + + rc = init_module(file, len, options ? options : ""); + if (rc) + log_message("\terror %s", moderror(errno)); + } - rc = insmod_call(final_name, options); unlink(final_name); /* sucking no space left on device */ if (rc) { log_message("\tfailed"); @@ -366,7 +429,10 @@ enum return_type ask_insmod(enum driver_type type) } if (results == RETURN_OK) { - choice[strlen(choice)-2] = '\0'; /* remove trailing .o */ + if (kernel_version() <= 4) + choice[strlen(choice)-2] = '\0'; /* remove trailing .o */ + else + choice[strlen(choice)-3] = '\0'; /* remove trailing .ko */ return insmod_with_options(choice, type); } else return results; diff --git a/mdk-stage1/stage1.c b/mdk-stage1/stage1.c index 526560122..4ade8eb64 100644 --- a/mdk-stage1/stage1.c +++ b/mdk-stage1/stage1.c @@ -274,16 +274,7 @@ static void expert_third_party_modules(void) #ifdef ENABLE_PCMCIA static void handle_pcmcia(char ** pcmcia_adapter) { - char buf[50]; - int fd = open("/proc/version", O_RDONLY); - int size; - if (fd == -1) - fatal_error("could not open /proc/version"); - size = read(fd, buf, sizeof(buf)); - buf[size-1] = '\0'; // -1 to eat the \n - close(fd); - buf[17] = '\0'; // enough to extract `2.2' - if (ptr_begins_static_str(buf+14, "2.2")) { + if (kernel_version() == 2) { stg1_error_message("We now use kernel pcmcia support and this won't work with a 2.2 kernel."); return; } diff --git a/mdk-stage1/tools.c b/mdk-stage1/tools.c index ea8450cef..5b2128fe9 100644 --- a/mdk-stage1/tools.c +++ b/mdk-stage1/tools.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "stage1.h" #include "log.h" #include "mount.h" @@ -465,6 +466,16 @@ int string_array_length(char ** a) return i; } +int kernel_version(void) +{ + struct utsname val; + if (uname(&val)) { + log_perror("uname failed"); + return -1; + } + return charstar_to_int(val.release + 2); +} + int scall_(int retval, char * msg, char * file, int line) { char tmp[5000]; diff --git a/mdk-stage1/tools.h b/mdk-stage1/tools.h index 851480d2d..d8892a1ed 100644 --- a/mdk-stage1/tools.h +++ b/mdk-stage1/tools.h @@ -42,6 +42,7 @@ void handle_env(char ** env); char ** grab_env(void); char ** list_directory(char * direct); int string_array_length(char ** a); +int kernel_version(void); int scall_(int retval, char * msg, char * file, int line); #define scall(retval, msg) scall_(retval, msg, __FILE__, __LINE__) -- cgit v1.2.1