diff -U 3 -H -d -r -N -- linux-2.6.8.1/drivers/acpi/Kconfig linux-2.6.8.1_acpipatch/drivers/acpi/Kconfig
--- linux-2.6.8.1/drivers/acpi/Kconfig	2004-08-14 12:56:24.000000000 +0200
+++ linux-2.6.8.1_acpipatch/drivers/acpi/Kconfig	2004-10-03 13:35:56.000000000 +0200
@@ -269,6 +269,21 @@
 	  So, if you see messages like 'Losing too many ticks!' in the
 	  kernel logs, and/or you are using 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 -U 3 -H -d -r -N -- linux-2.6.8.1/drivers/acpi/osl.c linux-2.6.8.1_acpipatch/drivers/acpi/osl.c
--- linux-2.6.8.1/drivers/acpi/osl.c	2004-08-14 12:55:59.000000000 +0200
+++ linux-2.6.8.1_acpipatch/drivers/acpi/osl.c	2004-10-03 13:38:55.000000000 +0200
@@ -34,12 +34,14 @@
 #include <linux/interrupt.h>
 #include <linux/kmod.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 #include <linux/workqueue.h>
 #include <linux/nmi.h>
 #include <acpi/acpi.h>
 #include <asm/io.h>
 #include <acpi/acpi_bus.h>
 #include <asm/uaccess.h>
+#include <linux/vmalloc.h>
 
 #include <linux/efi.h>
 
@@ -232,10 +234,30 @@
 acpi_os_table_override (struct acpi_table_header *existing_table,
 			struct acpi_table_header **new_table)
 {
+#ifdef CONFIG_ACPI_INITRD
+	extern char* dsdt_start;
+#endif
 	if (!existing_table || !new_table)
 		return AE_BAD_PARAMETER;
 
+#ifdef CONFIG_ACPI_INITRD
+	if (memcmp(existing_table, "DSDT", 4)) {
+		*new_table = NULL;
+		return AE_OK;
+	}
+	// dsdt_start has been kmalloced in /init/initram.c
+	// where should it be freed ?!? 
+	if (dsdt_start != NULL) {
+		printk(KERN_INFO "ACPI: Using customized DSDT\n");
+		*new_table = (struct acpi_table_header*)dsdt_start;
+		return AE_OK;
+	} else {
+        	*new_table = NULL;
+		return AE_OK;
+	}
+#else
 	*new_table = NULL;
+#endif
 	return AE_OK;
 }
 
diff -U 3 -H -d -r -N -- linux-2.6.8.1/drivers/acpi/tables/tbget.c linux-2.6.8.1_acpipatch/drivers/acpi/tables/tbget.c
--- linux-2.6.8.1/drivers/acpi/tables/tbget.c	2004-08-14 12:55:35.000000000 +0200
+++ linux-2.6.8.1_acpipatch/drivers/acpi/tables/tbget.c	2004-10-03 13:40:55.000000000 +0200
@@ -45,6 +45,9 @@
 #include <acpi/acpi.h>
 #include <acpi/actables.h>
 
+#ifdef CONFIG_ACPI_INITRD
+     extern unsigned char *dsdt_start;
+#endif
 
 #define _COMPONENT          ACPI_TABLES
 	 ACPI_MODULE_NAME    ("tbget")
@@ -286,6 +289,12 @@
 	}
 
 	/* Copy the table info */
+#ifdef CONFIG_ACPI_INITRD
+	if (dsdt_start) {
+		vfree(dsdt_start);
+		dsdt_start = NULL;
+	}
+#endif
 
 	ACPI_REPORT_INFO (("Table [%4.4s] replaced by host OS\n",
 		table_info->pointer->signature));
diff -U 3 -H -d -r -N -- linux-2.6.8.1/include/linux/initrd.h linux-2.6.8.1_acpipatch/include/linux/initrd.h
--- linux-2.6.8.1/include/linux/initrd.h	2004-08-14 12:56:22.000000000 +0200
+++ linux-2.6.8.1_acpipatch/include/linux/initrd.h	2004-10-03 13:27:08.000000000 +0200
@@ -15,6 +15,7 @@
 
 /* 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 -U 3 -H -d -r -N -- linux-2.6.8.1/init/initramfs.c linux-2.6.8.1_acpipatch/init/initramfs.c
--- linux-2.6.8.1/init/initramfs.c	2004-08-14 12:54:48.000000000 +0200
+++ linux-2.6.8.1_acpipatch/init/initramfs.c	2004-10-03 13:33:28.000000000 +0200
@@ -6,6 +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 +474,13 @@
 {
 	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 +497,55 @@
 			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=(unsigned char*)initrd_start; 
+				data < (unsigned char*)initrd_end_tmp ; ++data) {
+				
+				if (!memcmp(data, start_signature, 
+					sizeof(start_signature)-1)) {
+					printk(" found (at offset %u)!\n", 
+						data+sizeof(start_signature)-
+						(unsigned char*)initrd_start - 1);
+					dsdt_start_tmp = data + sizeof(start_signature) - 1;
+					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(end_signature); 
+				data <= (unsigned char*)initrd_end; data++){  
+				if (!memcmp(data, end_signature, 
+					sizeof(end_signature)-1)){
+					break;
+				}
+			}
+			printk (" found customized DSDT with %u bytes!\n", data-dsdt_start_tmp);
+			// DSDT could be about 10-200kb, maybe more? 
+			// could kmalloc be used ?
+			// am I allowed to use vmalloc ?
+			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,
