summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Cottenceau <gc@mandriva.com>2001-07-03 20:08:18 +0000
committerGuillaume Cottenceau <gc@mandriva.com>2001-07-03 20:08:18 +0000
commita08cfceb71abf287fc2856fab1bbe6f4e5e7ba5b (patch)
tree48a7a9fe4ea17addaabfccf5306aa25bff9e05bb
parented31e129c0036ae2d8c4b530c56733ce1d244f94 (diff)
downloaddrakx-a08cfceb71abf287fc2856fab1bbe6f4e5e7ba5b.tar
drakx-a08cfceb71abf287fc2856fab1bbe6f4e5e7ba5b.tar.gz
drakx-a08cfceb71abf287fc2856fab1bbe6f4e5e7ba5b.tar.bz2
drakx-a08cfceb71abf287fc2856fab1bbe6f4e5e7ba5b.tar.xz
drakx-a08cfceb71abf287fc2856fab1bbe6f4e5e7ba5b.zip
add support for install from USB Network Adapters
-rw-r--r--Makefile4
-rwxr-xr-xmake_boot_img5
-rw-r--r--mdk-stage1/.cvsignore1
-rw-r--r--mdk-stage1/Makefile26
-rw-r--r--mdk-stage1/probing.c144
-rw-r--r--mdk-stage1/probing.h2
-rw-r--r--mdk-stage1/usb-resource/.cvsignore1
-rw-r--r--mdk-stage1/usb-resource/Makefile25
-rwxr-xr-xmdk-stage1/usb-resource/update-usb-ids.pl73
-rw-r--r--perl-install/modules.pm8
-rwxr-xr-xupdate_kernel6
11 files changed, 264 insertions, 31 deletions
diff --git a/Makefile b/Makefile
index 31fdc1b74..153c8ddc9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
ARCH := $(patsubst i%86,i386,$(shell uname -m))
ARCH := $(patsubst sparc%,sparc,$(ARCH))
-RELEASE_BOOT_IMG = cdrom.img hd.img network.img
+RELEASE_BOOT_IMG = cdrom.img hd.img network.img usbnet.img
ifeq (i386,$(ARCH))
RELEASE_BOOT_IMG += blank.img pcmcia.img other.img
endif
@@ -19,7 +19,7 @@ FRELEASE_BOOT_IMG = $(BOOT_IMG:%=images/%)
FBOOT_IMG = $(BOOT_IMG:%=images/%)
FBOOT_RDZ = $(FBOOT_IMG:%.img=%.rdz)
-BINS = mdk-stage1/init mdk-stage1/stage1-full mdk-stage1/stage1-cdrom mdk-stage1/stage1-network
+BINS = mdk-stage1/init mdk-stage1/stage1-full mdk-stage1/stage1-cdrom mdk-stage1/stage1-network mdk-stage/stage1-usbnet
ifeq (ppc,$(ARCH))
BINS = mdk-stage1/init mdk-stage1/stage1-full
endif
diff --git a/make_boot_img b/make_boot_img
index 520f10680..6afa19df9 100755
--- a/make_boot_img
+++ b/make_boot_img
@@ -1,6 +1,6 @@
#!/usr/bin/perl
-@ARGV >= 2 or die "usage: $0 <image> all|other|cdrom|hd|network|blank|pcmcia|live|tftp|tftprd\n";
+@ARGV >= 2 or die "usage: $0 <image> all|other|cdrom|hd|network|usbnet|blank|pcmcia|live|tftp|tftprd\n";
use Config;
Config->import;
@@ -33,6 +33,7 @@ $install = $ {{
tftprd => "stage1-full",
pcmcia => "stage1-full",
network => "stage1-network",
+ usbnet => "stage1-usbnet",
cdrom => "stage1-cdrom",
hd => "stage1-disk",
live64 => "stage1-full",
@@ -79,7 +80,7 @@ sub initrd {
install_stripped("$instdir/init", "$mnt/sbin");
install_stripped("$instdir/$install", "$mnt/sbin/stage1");
- if ($type eq "network" || $type eq "all" || $type eq "other" || $type eq "blank") {
+ if ($type eq "network" || $type eq "usbnet" || $type eq "all" || $type eq "other" || $type eq "blank") {
install_stripped("$instdir/ppp/pppd-bin", "$mnt/sbin/pppd");
install_stripped("$instdir/rp-pppoe/pppoe-bin", "$mnt/sbin/pppoe");
_ "$sudo cp -a /dev/ppp $mnt/dev";
diff --git a/mdk-stage1/.cvsignore b/mdk-stage1/.cvsignore
index c2cd01c54..36f56f6b5 100644
--- a/mdk-stage1/.cvsignore
+++ b/mdk-stage1/.cvsignore
@@ -8,3 +8,4 @@ debug.log
*.rdz*
mkinitrd_helper.tar.bz2
hack_*
+stage1-usbnet
diff --git a/mdk-stage1/Makefile b/mdk-stage1/Makefile
index a27d829a9..52a7fe792 100644
--- a/mdk-stage1/Makefile
+++ b/mdk-stage1/Makefile
@@ -43,7 +43,7 @@ top_dir = .
include $(top_dir)/Makefile.common
-DEFS = -DVERSION=\"$(VERSION)\" #-DSPAWN_SHELL
+DEFS = -DVERSION=\"$(VERSION)\" -DSPAWN_SHELL
COMPILE = $(CC) $(DEFS) $(CFLAGS)
@@ -122,6 +122,9 @@ STAGE1OBJS-NETWORK = $(subst .c,-NETWORK.o,$(STAGE1SRC) $(NETWORKSRC))
NETWORK_DEFS = -DDISABLE_CDROM -DDISABLE_DISK
+STAGE1OBJS-USBNET = $(subst .c,-USBNET.o,$(STAGE1SRC) $(NETWORKSRC))
+
+
STAGE1OBJS-FULL = $(subst .c,-FULL.o,$(STAGE1SRC) $(CDROMSRC) $(DISKSRC) $(NETWORKSRC))
@@ -141,13 +144,13 @@ endif
BINS = init stage1-full
ifeq (i386, $(ARCH))
-BINS += stage1-cdrom stage1-disk stage1-network
+BINS += stage1-cdrom stage1-disk stage1-network stage1-usbnet
endif
ifneq (ia64, $(ARCH))
DIRS = dietlibc
endif
-DIRS += mar pci-resource bzlib $(INSMOD) slang newt ppp/pppd rp-pppoe/src
+DIRS += mar pci-resource usb-resource bzlib $(INSMOD) slang newt ppp/pppd rp-pppoe/src
ifeq (i386,$(ARCH))
DIRS += pcmcia
endif
@@ -161,6 +164,9 @@ PCMCIA_DEFS = -DENABLE_PCMCIA
endif
+USBNET_DEFS_GEN = -DENABLE_USB -DENABLE_USBNET
+USBNET_DEFS = $(USBNET_DEFS_GEN) -DDISABLE_PCINET
+
all: dirs $(BINS)
dirs:
@@ -184,6 +190,10 @@ stage1-network: $(STAGE1OBJS-NETWORK) $(STAGE1_OWN_LIBS) $(STAGE1_NETWORK_LIBS)
$(CC) $(LDFLAGS_STAGE1) -o $@ $^
$(STRIPCMD) $@
+stage1-usbnet: $(STAGE1OBJS-USBNET) $(STAGE1_OWN_LIBS) $(STAGE1_NETWORK_LIBS) $(FRONTEND_LINK) $(STAGE1_LIBC)
+ $(CC) $(LDFLAGS_STAGE1) -o $@ $^
+ $(STRIPCMD) $@
+
stage1-full: $(STAGE1OBJS-FULL) $(STAGE1_OWN_LIBS) $(STAGE1_NETWORK_LIBS) $(FRONTEND_LINK) $(PCMCIA_LIB) $(STAGE1_LIBC)
$(CC) $(LDFLAGS_STAGE1) -o $@ $^
$(STRIPCMD) $@
@@ -201,8 +211,11 @@ $(STAGE1OBJS-DISK): %-DISK.o: %.c
$(STAGE1OBJS-NETWORK): %-NETWORK.o: %.c
$(COMPILE) $(INCLUDES) $(NETWORK_DEFS) -c $< -o $@
+$(STAGE1OBJS-USBNET): %-USBNET.o: %.c
+ $(COMPILE) $(INCLUDES) $(NETWORK_DEFS) $(USBNET_DEFS) -c $< -o $@
+
$(STAGE1OBJS-FULL): %-FULL.o: %.c
- $(COMPILE) $(INCLUDES) $(PCMCIA_DEFS) -c $< -o $@
+ $(COMPILE) $(INCLUDES) $(USBNET_DEFS_GEN) $(PCMCIA_DEFS) -c $< -o $@
.c.o:
$(COMPILE) $(INCLUDES) -c $<
@@ -238,3 +251,8 @@ endif
*-DISK.o: %-DISK.o: %.o
*-NETWORK.o: %-NETWORK.o: %.o
+
+*-USBNET.o: %-USBNET.o: %.o
+
+*-FULL.o: %-FULL.o: %.o
+
diff --git a/mdk-stage1/probing.c b/mdk-stage1/probing.c
index dc8340ea8..420f863d2 100644
--- a/mdk-stage1/probing.c
+++ b/mdk-stage1/probing.c
@@ -22,7 +22,7 @@
/*
* This contains stuff related to probing:
- * (1) any (actually SCSI and NET only) devices (autoprobe for PCI)
+ * (1) any (actually only SCSI, NET, USB Controllers) devices (autoprobe for PCI and USB)
* (2) IDE media
* (3) SCSI media
* (4) ETH devices
@@ -39,12 +39,16 @@
#include <sys/socket.h>
#include <net/if.h>
#include <sys/ioctl.h>
+#include <sys/mount.h>
#include "stage1.h"
#include "log.h"
#include "frontend.h"
#include "modules.h"
#include "pci-resource/pci-ids.h"
+#ifdef ENABLE_USB
+#include "usb-resource/usb-ids.h"
+#endif
#include "probing.h"
@@ -61,9 +65,14 @@ struct media_info {
static void warning_insmod_failed(enum insmod_return r)
{
- if (r != INSMOD_OK
- && !(IS_AUTOMATIC && r == INSMOD_FAILED_FILE_NOT_FOUND))
- stg1_error_message("Warning, installation of driver failed. (please include msg from <Alt-F3> for bugreports)");
+ 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
@@ -116,37 +125,47 @@ char * get_net_intf_description(char * intf_name)
static void probe_that_type(enum driver_type type)
{
- if (IS_EXPERT)
+ if (IS_EXPERT) {
ask_insmod(type);
- else {
- /* ---- PCI probe */
+ return;
+ }
+
+
+ /* ---- PCI probe ---------------------------------------------- */
+ {
FILE * f;
int len = 0;
char buf[200];
struct pci_module_map * pcidb = NULL;
- f = fopen("/proc/bus/pci/devices", "rb");
-
- if (!f) {
- log_message("PCI: could not open proc file");
- return;
- }
-
switch (type) {
- case SCSI_ADAPTERS:
#ifndef DISABLE_MEDIAS
+ case SCSI_ADAPTERS:
pcidb = scsi_pci_ids;
len = scsi_num_ids;
-#endif
break;
- case NETWORK_DEVICES:
+#endif
#ifndef DISABLE_NETWORK
+#ifndef DISABLE_PCINET
+ case NETWORK_DEVICES:
pcidb = eth_pci_ids;
len = eth_num_ids;
+ break;
+#endif
#endif
+#ifdef ENABLE_USB
+ case USB_CONTROLLERS:
+ pcidb = usb_pci_ids;
+ len = usb_num_ids;
break;
+#endif
default:
- return;
+ goto end_pci_probe;
+ }
+
+ if (!(f = fopen("/proc/bus/pci/devices", "rb"))) {
+ log_message("PCI: could not open proc file");
+ goto end_pci_probe;
}
while (1) {
@@ -186,12 +205,96 @@ static void probe_that_type(enum driver_type type)
net_discovered_interface(NULL);
}
#endif
+#ifdef ENABLE_USB
+ if (type == USB_CONTROLLERS) {
+ stg1_info_message("About to load driver for usb controller `%s'.", pcidb[i].module);
+ warning_insmod_failed(my_insmod(pcidb[i].module, USB_CONTROLLERS, NULL));
+ }
+#endif
}
}
}
+ fclose(f);
+ end_pci_probe:
+ }
+
+#ifdef ENABLE_USB
+ /* ---- USB probe ---------------------------------------------- */
+ {
+ static int already_probed_usb_controllers = 0;
+ static int already_mounted_usbdev = 0;
+
+ FILE * f;
+ int len = 0;
+ char buf[200];
+ struct usb_module_map * usbdb = NULL;
+
+ switch (type) {
+#ifdef ENABLE_USBNET
+ case NETWORK_DEVICES:
+ usbdb = usbnet_usb_ids;
+ len = usbnet_usb_num_ids;
+ break;
+#endif
+ default:
+ goto end_usb_probe;
+ }
+
+ 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", "usbdevfs", 0, NULL)) {
+ log_message("USB: couldn't mount /proc/bus/usb");
+ goto end_usb_probe;
+ }
+ wait_message("Waiting for USB stuff to show up.");
+ sleep(2); /* sucking background work */
+ remove_wait_message();
+ }
+
+ if (!(f = fopen("/proc/bus/usb/devices", "rb"))) {
+ log_message("USB: could not open proc file");
+ goto end_usb_probe;
+ }
+
+ while (1) {
+ int i, vendor, id;
+
+ if (!fgets(buf, sizeof(buf), f)) break;
+
+ if (strstr(buf, "Keyboard")) {
+ my_insmod("usbkbd", ANY_DRIVER_TYPE, NULL);
+ my_insmod("keybdev", ANY_DRIVER_TYPE, NULL);
+ }
+
+ if (sscanf(buf, "P: Vendor=%x ProdID=%x", &vendor, &id) != 2)
+ continue;
+
+ for (i = 0; i < len; i++) {
+ if (usbdb[i].vendor == vendor && usbdb[i].id == id) {
+ log_message("USB: device %04x %04x is \"%s\" (%s)", vendor, id, usbdb[i].name, usbdb[i].module);
+#ifdef ENABLE_USBNET
+ if (type == NETWORK_DEVICES) {
+ stg1_info_message("About to load driver for usb network device:\n \n%s", usbdb[i].name);
+ prepare_intf_descr(usbdb[i].name);
+ warning_insmod_failed(my_insmod(usbdb[i].module, NETWORK_DEVICES, NULL));
+ if (intf_descr_for_discover) /* for modules providing more than one net intf */
+ net_discovered_interface(NULL);
+ }
+#endif
+
+ }
+ }
+ }
fclose(f);
+ end_usb_probe:
}
+#endif
}
@@ -470,10 +573,13 @@ int net_device_available(char * device) {
char ** get_net_devices(void)
{
char * devices[] = {
- "eth0", "eth1", "eth2", "eth3",
+ "eth0", "eth1", "eth2", "eth3", "eth4", "eth5",
"tr0",
"plip0", "plip1", "plip2",
"fddi0",
+#ifdef ENABLE_USBNET
+ "usb0", "usb1", "usb2", "usb3",
+#endif
NULL
};
char ** ptr = devices;
diff --git a/mdk-stage1/probing.h b/mdk-stage1/probing.h
index ea618b7b1..d2bf1e567 100644
--- a/mdk-stage1/probing.h
+++ b/mdk-stage1/probing.h
@@ -24,7 +24,7 @@
enum media_type { CDROM, DISK, FLOPPY, TAPE, UNKNOWN_MEDIA };
-enum driver_type { SCSI_ADAPTERS, NETWORK_DEVICES, ANY_DRIVER_TYPE };
+enum driver_type { SCSI_ADAPTERS, NETWORK_DEVICES, USB_CONTROLLERS, ANY_DRIVER_TYPE };
void get_medias(enum media_type media, char *** names, char *** models);
char ** get_net_devices(void);
diff --git a/mdk-stage1/usb-resource/.cvsignore b/mdk-stage1/usb-resource/.cvsignore
new file mode 100644
index 000000000..a7d0cfa9a
--- /dev/null
+++ b/mdk-stage1/usb-resource/.cvsignore
@@ -0,0 +1 @@
+usb-ids.h
diff --git a/mdk-stage1/usb-resource/Makefile b/mdk-stage1/usb-resource/Makefile
new file mode 100644
index 000000000..eb80ce6da
--- /dev/null
+++ b/mdk-stage1/usb-resource/Makefile
@@ -0,0 +1,25 @@
+ #******************************************************************************
+ #
+ # $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.
+ #
+ #*****************************************************************************
+
+
+all: usb-ids.h
+
+usb-ids.h: /usr/share/ldetect-lst/usbtable update-usb-ids.pl
+ perl update-usb-ids.pl > $@ || rm -f $@
+
+clean:
+ rm -f usb-ids.h
diff --git a/mdk-stage1/usb-resource/update-usb-ids.pl b/mdk-stage1/usb-resource/update-usb-ids.pl
new file mode 100755
index 000000000..b7184bade
--- /dev/null
+++ b/mdk-stage1/usb-resource/update-usb-ids.pl
@@ -0,0 +1,73 @@
+#!/usr/bin/perl
+
+
+sub cat_ { local *F; open F, $_[0] or $_[1] ? die "cat of file $_[0] failed: $!\n" : return; my @l = <F>; wantarray ? @l : join '', @l }
+
+
+-x "../mar/mar" or die "\t*FAILED* Sorry, need ../mar/mar binary\n";
+
+
+my @usbtable_tmp = cat_("/usr/share/ldetect-lst/usbtable");
+my @usbtable;
+foreach (@usbtable_tmp) {
+ next if /\s*#/;
+ /\s*(\S+)\s+(\S+)\s+"(\S+)"\s+"([^"]*)"/ or next;
+ push @usbtable, { 'vendor' => $1, 'id' => $2, 'module' => $3, 'description' => $4 };
+}
+
+
+print '
+struct usb_module_map {
+ unsigned short vendor; /* vendor */
+ unsigned short id; /* device */
+ const char *name; /* human readable name */
+ const char *module; /* module to load */
+};
+';
+
+print "#ifdef ENABLE_USB
+struct pci_module_map usb_pci_ids[] = {
+
+";
+
+require '/usr/bin/merge2pcitable.pl';
+my $drivers = read_pcitable("/usr/share/ldetect-lst/pcitable");
+
+while (my ($k, $v) = each %$drivers) {
+ $v->[0] =~ /^usb-/ or next;
+ $k =~ /^(....)(....)/;
+ printf qq|\t{ 0x%s, 0x%s, "", "%s" },\n|,
+ $1, $2, $v->[0];
+}
+
+print "};
+int usb_num_ids=sizeof(usb_pci_ids)/sizeof(struct pci_module_map);
+#endif
+";
+
+
+my @t = ('usbnet');
+
+
+foreach $type (@t) {
+ my $modulez;
+ foreach (glob("../../all.modules/*/${type}_modules.mar")) {
+ -f $_ or die "\t*FAILED* Sorry, need $_ mar file\n";
+ push @$modulez, (`../mar/mar -l $_`);
+ }
+
+ print "#ifdef ENABLE_".uc($type)."
+struct usb_module_map ${type}_usb_ids[] = {
+";
+ foreach my $usbentry (@usbtable) {
+ grep(/^\t$usbentry->{'module'}\.o\s/, @$modulez) or next;
+ printf qq|\t{ %s, %s, ( "%s" ), ( "%s" ) },\n|,
+ $usbentry->{'vendor'}, $usbentry->{'id'}, $usbentry->{'description'}, $usbentry->{'module'};
+ }
+
+ print "};
+int ${type}_usb_num_ids=sizeof(${type}_usb_ids)/sizeof(struct usb_module_map);
+#endif
+";
+
+}
diff --git a/perl-install/modules.pm b/perl-install/modules.pm
index 6b8495da7..402c06402 100644
--- a/perl-install/modules.pm
+++ b/perl-install/modules.pm
@@ -114,12 +114,16 @@ if_(arch() !~ /alpha/ && arch() !~ /sparc/,
"parport_pc" => "parport_pc",
"sunrpc" => "sunrpc",
"pci-scan" => "pci-scan",
- "usbcore" => "usbcore",
"ppp" => "Point to Point driver",
"ppp_generic" => "Point to Point generic driver",
"ppp_async" => "ppp_async",
"slhc" => "slhc",
}],
+[ 'usbnet', {
+ "pegasus" => "pegasus",
+ "kaweth" => "kaweth",
+ "usbnet" => "usbnet",
+}],
[ 'isdn', {
"hisax" => "hisax",
"hysdn" => "hysdn",
@@ -366,6 +370,7 @@ if_(arch() !~ /^sparc/,
),
}],
[ 'usb', {
+ "usbcore" => "usbcore",
"usb-uhci" => "USB Controller (uhci)",
"usb-ohci" => "USB Controller (ohci)",
"usb-ohci-hcd" => "USB (ohci-hcd)",
@@ -414,7 +419,6 @@ BusLogic seagate fdomain g_NCR5380 tmscsim
my @skip_modules_on_stage1 = (
qw(sktr tmspci ibmtr abyss), # alt token ring
qw(old_tulip rtl8139), # doesn't exist in 2.4
- qw(kaweth pegasus), # usb net
if_(arch() =~ /alpha|ppc/, qw(sb1000)),
"apa1480_cb",
"imm",
diff --git a/update_kernel b/update_kernel
index f8bdb555e..8547de0c6 100755
--- a/update_kernel
+++ b/update_kernel
@@ -38,6 +38,7 @@ function create_modules() {
create_marfile cdrom_modules.mar $CDROM_MODULES $GENERIC_MODULES
create_marfile hd_modules.mar $HD_MODULES $GENERIC_MODULES
create_marfile pcmcia_modules.mar $PCMCIA_MODULES $PCMCIA_COREMODULES $GENERIC_MODULES
+ create_marfile usbnet_modules.mar $USBNET_MODULES $GENERIC_MODULES
create_marfile other_modules.mar $BIG_MODULES $GENERIC_MODULES
create_marfile all_modules.mar $ALL_MODULES $GENERIC_MODULES
rm -f $ALL_MODULES $PCMCIA_COREMODULES $NOT_USEFULL_IN_STAGE1 # leave in the directory non-install1 used modules
@@ -61,12 +62,15 @@ f "disk" ; DISK_DRIVERS=$v
f "net" ; NETWORK_DRIVERS=$v
f "scsi cdrom" ; CD_DRIVERS=$v
f "pcmcia net_raw cdrom_raw scsi_raw disk_raw" ; PCMCIA_DRIVERS=$v
+f "usb" ; USB_DRIVERS=$v
+f "usbnet net_raw" ; USBNET_DRIVERS=$v
f "big net_raw cdrom_raw scsi_raw disk_raw" ; BIG_DRIVERS=$v
-f "pcmcia net cdrom scsi disk keepbig" ; ALL_DRIVERS=$v
+f "pcmcia net usb usbnet cdrom scsi disk keepbig" ; ALL_DRIVERS=$v
[ $ARCH == "i386" ] && DOSMODULES="vfat.o fat.o"
echo "done."
NETWORK_MODULES=" $NETWORK_DRIVERS"
+USBNET_MODULES=" $USB_DRIVERS $USBNET_DRIVERS usbkbd.o keybdev.o input.o"
CDROM_MODULES=" $CD_DRIVERS"
HD_MODULES=" $DOSMODULES $SCSI_DRIVERS $DISK_DRIVERS loop.o isofs.o reiserfs.o"
[ "$ARCH" == "ppc" ] && HD_MODULES="$HDMODULES hfs.o"