diff -uprN -X /home/eric/dontdiff linux-2.6.5-nodsdt/drivers/acpi/Kconfig linux-2.6.5/drivers/acpi/Kconfig
--- linux-2.6.5-nodsdt/drivers/acpi/Kconfig	2004-04-16 22:36:29.000000000 +0200
+++ linux-2.6.5/drivers/acpi/Kconfig	2004-04-10 21:59:28.000000000 +0200
@@ -270,5 +270,19 @@ config X86_PM_TIMER
 	  kernel logs, and/or you are using a this on a notebook which
 	  does not yet have an HPET, you should say "Y" here.
 
+config ACPI_INITRD
+	bool "Read DSDT from initrd"
+	depends on ACPI && BLK_DEV_INITRD
+	default y
+	help
+	  The DSDT (Differentiated System Description Table) often needs to be
+	  overridden because of broken BIOS implementations. If you want to use
+	  a customized DSDT, please use the mkinitrd tool (mkinitrd package) to 
+	  attach the  DSDT to the initrd) or see http://gaugusch.at/kernel.shtml 
+	  for instructions on using an existing initrd with ACPI. If there is no 
+	  one found in the initrd, the DSDT from the BIOS is used. Even you do not 
+	  need a new one at the moment, you may want to use a better implemented 
+	  DSDT later. It is save to say yes here
+
 endmenu
 
diff -uprN -X /home/eric/dontdiff linux-2.6.5-nodsdt/drivers/acpi/osl.c linux-2.6.5/drivers/acpi/osl.c
--- linux-2.6.5-nodsdt/drivers/acpi/osl.c	2004-04-16 22:36:29.000000000 +0200
+++ linux-2.6.5/drivers/acpi/osl.c	2004-04-16 23:18:40.000000000 +0200
@@ -34,6 +34,7 @@
 #include <linux/interrupt.h>
 #include <linux/kmod.h>
 #include <linux/delay.h>
+#include <linux/initrd.h>
 #include <linux/workqueue.h>
 #include <linux/nmi.h>
 #include <acpi/acpi.h>
@@ -229,7 +230,13 @@ acpi_os_table_override (struct acpi_tabl
 	if (!existing_table || !new_table)
 		return AE_BAD_PARAMETER;
 
-	*new_table = NULL;
+#ifdef CONFIG_ACPI_INITRD
+	if (!memcmp(existing_table, "DSDT", 4) && (dsdt_start != NULL)) {
+		printk(KERN_INFO "ACPI: Using customized DSDT\n");
+		*new_table = (struct acpi_table_header*)dsdt_start;
+	} else 
+#endif
+		*new_table = NULL;
 	return AE_OK;
 }
 
diff -uprN -X /home/eric/dontdiff linux-2.6.5-nodsdt/drivers/acpi/tables/tbget.c linux-2.6.5/drivers/acpi/tables/tbget.c
--- linux-2.6.5-nodsdt/drivers/acpi/tables/tbget.c	2004-04-16 22:36:29.000000000 +0200
+++ linux-2.6.5/drivers/acpi/tables/tbget.c	2004-04-16 23:34:31.591144032 +0200
@@ -44,6 +44,8 @@
 
 #include <acpi/acpi.h>
 #include <acpi/actables.h>
+#include <linux/initrd.h>
+#include <linux/vmalloc.h>
 
 
 #define _COMPONENT          ACPI_TABLES
@@ -285,6 +287,12 @@ acpi_tb_table_override (
 		return_ACPI_STATUS (status);
 	}
 
+#ifdef CONFIG_ACPI_INITRD
+	if (dsdt_start) {
+		vfree(dsdt_start);
+		dsdt_start = NULL;
+	}
+#endif
 	/* Copy the table info */
 
 	ACPI_REPORT_INFO (("Table [%4.4s] replaced by host OS\n",
diff -uprN -X /home/eric/dontdiff linux-2.6.5-nodsdt/include/linux/initrd.h linux-2.6.5/include/linux/initrd.h
--- linux-2.6.5-nodsdt/include/linux/initrd.h	2004-04-16 22:36:29.000000000 +0200
+++ linux-2.6.5/include/linux/initrd.h	2004-04-10 21:59:28.000000000 +0200
@@ -15,6 +15,7 @@ extern int initrd_below_start_ok;
 
 /* free_initrd_mem always gets called with the next two as arguments.. */
 extern unsigned long initrd_start, initrd_end;
+extern unsigned char *dsdt_start;
 extern void free_initrd_mem(unsigned long, unsigned long);
 
 extern unsigned int real_root_dev;
diff -uprN -X /home/eric/dontdiff linux-2.6.5-nodsdt/init/initramfs.c linux-2.6.5/init/initramfs.c
--- linux-2.6.5-nodsdt/init/initramfs.c	2004-04-16 22:36:30.000000000 +0200
+++ linux-2.6.5/init/initramfs.c	2004-04-16 23:35:08.000000000 +0200
@@ -6,7 +6,11 @@
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/syscalls.h>
+#include <linux/vmalloc.h>
 
+#ifdef CONFIG_ACPI_INITRD
+unsigned char *dsdt_start;
+#endif
 static __initdata char *message;
 static void __init error(char *x)
 {
@@ -469,6 +473,13 @@ void __init populate_rootfs(void)
 {
 	char *err = unpack_to_rootfs(&__initramfs_start,
 			 &__initramfs_end - &__initramfs_start, 0);
+#ifdef CONFIG_ACPI_INITRD
+	unsigned char start_signature[] = "INITRDDSDT123DSDT123";
+	unsigned char end_signature[] =   "INITRDDSDT321DSDT321";
+	unsigned char *data = (unsigned char*) initrd_start;
+	unsigned char *dsdt_start_tmp = NULL;
+	unsigned char *initrd_end_tmp = NULL;
+#endif
 	if (err)
 		panic(err);
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -485,6 +496,46 @@ void __init populate_rootfs(void)
 			return;
 		}
 		printk("it isn't (%s); looks like an initrd\n", err);
+		
+#ifdef CONFIG_ACPI_INITRD
+		dsdt_start = NULL;
+		
+		printk(KERN_INFO "ACPI: Looking for DSDT in initrd ...");
+		 /* don't scan above end, do not modify initrd borders */
+		initrd_end_tmp = (unsigned char*) initrd_end - sizeof(end_signature);
+
+		if ((initrd_end_tmp - (unsigned char*)initrd_start) > 4 && 
+			!memcmp((unsigned char*)initrd_start, "DSDT", 4)) {
+			/* found DSDT at start of initrd */
+			dsdt_start_tmp = (unsigned char*)initrd_start; 
+		} else { /* searching for start signature in initrd */
+			for (; data < initrd_end_tmp; data++) {
+				if (!memcmp(data, start_signature, 
+						sizeof(start_signature) - 1)) {
+					dsdt_start_tmp = data + sizeof(start_signature) - 1;
+					printk(" found (at offset %u)!\n", 
+						dsdt_start_tmp - 
+						(unsigned char*)initrd_start);
+					break;
+				}
+			}
+		}
+		// check if head of dsdt is valid
+		if (dsdt_start_tmp != NULL && !memcmp(dsdt_start_tmp, "DSDT", 4)) {
+			// searching for end signature in initrd
+			for (data += sizeof(start_signature); 
+			     data <= initrd_end_tmp; data++) {  
+				if (!memcmp(data, end_signature,
+						sizeof(end_signature) - 1))
+					break;
+			}
+			printk (" found customized DSDT with %u bytes!\n", data - dsdt_start_tmp);
+			dsdt_start = vmalloc(data - dsdt_start_tmp + 1);
+			memcpy(dsdt_start, dsdt_start_tmp, data - dsdt_start_tmp);
+		} else
+			printk(" not found!\n");
+#endif 
+		
 		fd = sys_open("/initrd.image", O_WRONLY|O_CREAT, 700);
 		if (fd >= 0) {
 			sys_write(fd, (char *)initrd_start,
