diff -ruN linux-2.4.22.orig/Documentation/Configure.help linux-2.4.22/Documentation/Configure.help
--- linux-2.4.22.orig/Documentation/Configure.help	2003-08-25 13:44:39.000000000 +0200
+++ linux-2.4.22/Documentation/Configure.help	2003-08-31 20:19:47.000000000 +0200
@@ -19019,6 +19019,14 @@
   handles PnP messages.  All ACPI devices use its services, so using
   them requires saying Y here.
 
+ACPI DSDT in initrd
+CONFIG_ACPI_INITRD
+	The DSDT (Differentiated System Description Table) often needs to be 
+	overridden because of broken BIOS implementations. If you want to use
+	a customized DSDT, just copy it to /boot/initrd (which must be used as
+  initrd, of course). See http://gaugusch.at/kernel.shtml for instructions 
+  on using an existing initrd with ACPI. If unsure, say N here.
+
 ACPI System Driver
 CONFIG_ACPI_SYS
   This driver will enable your system to shut down using ACPI, and
diff -ruN linux-2.4.22.orig/drivers/acpi/Config.in linux-2.4.22/drivers/acpi/Config.in
--- linux-2.4.22.orig/drivers/acpi/Config.in	2003-08-25 13:44:40.000000000 +0200
+++ linux-2.4.22/drivers/acpi/Config.in	2003-08-31 20:19:47.000000000 +0200
@@ -14,6 +14,10 @@
       define_bool CONFIG_ACPI_HT_ONLY n
     fi
 
+        if [ "$CONFIG_BLK_DEV_INITRD" = "y" ]; then
+          bool         'Read DSDT from initrd' CONFIG_ACPI_INITRD
+        fi
+
     if [ "$CONFIG_ACPI_HT_ONLY" = "n" ]; then
       define_bool CONFIG_ACPI_BOOT		y
       define_bool CONFIG_ACPI_BUS		y
diff -ruN linux-2.4.22.orig/drivers/acpi/osl.c linux-2.4.22/drivers/acpi/osl.c
--- linux-2.4.22.orig/drivers/acpi/osl.c	2003-08-25 13:44:41.000000000 +0200
+++ linux-2.4.22/drivers/acpi/osl.c	2003-08-31 20:19:47.000000000 +0200
@@ -38,6 +38,8 @@
 #include <asm/io.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi.h>
+#include <linux/init.h>
+#include <linux/vmalloc.h>
 
 #ifdef CONFIG_ACPI_EFI
 #include <linux/efi.h>
@@ -224,14 +226,59 @@
 	return AE_OK;
 }
 
+
+#ifdef CONFIG_ACPI_INITRD
+unsigned char* get_dsdt_from_initrd(unsigned char *start, unsigned char *end)
+{
+	unsigned char *data;
+	unsigned char signature[] = "INITRDDSDT123DSDT123";
+
+	if (start == NULL)
+		return NULL;
+	printk(KERN_INFO "Looking for DSDT in initrd ...");
+	if (!memcmp(start, "DSDT", 4)) {
+		printk(" found at beginning!\n");
+		return start;
+	}
+	end-=sizeof(signature)+5; /* don't scan above end, signature+\0+DSDT */
+	for (data=start; data < end ; ++data) {
+		if (!memcmp(data, signature, sizeof(signature)-1)) {
+			if (!memcmp(data+sizeof(signature), "DSDT", 4)) {
+				printk(" found (at offset %u)!\n", data+sizeof(signature)-start);
+				return data+sizeof(signature);
+			}
+		}
+	}
+	printk(" not found!\n");
+
+	return NULL;
+}
+#endif
+
+
 acpi_status
 acpi_os_table_override (struct acpi_table_header *existing_table,
 			struct acpi_table_header **new_table)
 {
+#ifdef CONFIG_ACPI_INITRD
+	extern unsigned long initrd_start, initrd_end;
+	unsigned char* new_dsdt=NULL;
+
+#endif
 	if (!existing_table || !new_table)
 		return AE_BAD_PARAMETER;
 
+#ifdef CONFIG_ACPI_INITRD
+	if (strncmp(existing_table->signature, "DSDT", 4) == 0 &&
+		(new_dsdt=get_dsdt_from_initrd((unsigned char*)initrd_start, 
+			(unsigned char*)initrd_end)) != NULL)
+		*new_table = (struct acpi_table_header*)new_dsdt;
+	else
+		*new_table = NULL;
+#else
 	*new_table = NULL;
+#endif
+
 	return AE_OK;
 }
 

