From: Thomas Renninger <mail-smMupaH/RwJM7kwft8N7nw@public.gmane.org>
To: ML ACPI-devel
<acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>,
Markus Gaugusch <markus-z+rTbpWsRgbk7+2FdBfRIA@public.gmane.org>,
Hannes Reinecke <hare-l3A5Bk7waGM@public.gmane.org>,
eric-z+rTbpWsRgbk7+2FdBfRIA@public.gmane.org
Subject: [PATCH] [2/2 DSDT via initrd or initramfs] read DSDT from initramfs then try initrd
Date: Sun, 27 Feb 2005 20:45:40 +0100 [thread overview]
Message-ID: <42222364.4040409@renninger.de> (raw)
[-- Attachment #1: Type: text/plain, Size: 431 bytes --]
Markus, could you add this one to your collection of "override DSDT via
initrd" patches on http://gaugusch.at/kernel.shtml, please?
An mkinitrd working for the patch can be found here:
ftp.suse.com/pub/people/trenn/mkinitrd
use:
mkinitrd -k vmlinuz-version -i initrd-version -a /etc/DSDT.aml
for initramfs or
add the -R option to build up an initrd.
One time tested.
Comments appreciated.
Thomas
-> linux-2.6.11-rc5
[-- Attachment #2: acpi_dsdt_initrd_initramfs --]
[-- Type: text/plain, Size: 5493 bytes --]
Subject: Read DSDT from initrd or initramfs
From: Thomas Renninger <trenn-l3A5Bk7waGM@public.gmane.org>
Searches and reads in the root of initramfs a DSDT.aml file.
If not found the initrd is scanned for a DSDT signature
("INITRDDSDT123DSDT123"). Once a DSDT in the initramfs or
initrd is found the DSDT provided by BIOS is replaced.
--- x/drivers/acpi/Kconfig.orig 2005-02-24 17:40:47.000000000 +0100
+++ y/drivers/acpi/Kconfig 2005-02-26 16:54:32.718077026 +0100
@@ -343,4 +343,17 @@
This is the ACPI generic container driver which supports
ACPI0004, PNP0A05 and PNP0A06 devices
+config ACPI_INITRD
+ bool "Read DSDT from initrd or initramfs"
+ depends on ACPI && BLK_DEV_INITRD && !ACPI_CUSTOM_DSDT
+ default n
+ 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 initramfs
+ (see http://gaugusch.at/kernel.shtml for details)
+ If there is no DSDT found in the initrd, the DSDT from the BIOS is
+ used. It is save to say yes here.
+
endmenu
--- x/drivers/acpi/tables/tbget.c.orig 2005-02-24 17:40:32.000000000 +0100
+++ y/drivers/acpi/tables/tbget.c 2005-02-26 16:54:32.718077026 +0100
@@ -45,7 +45,6 @@
#include <acpi/acpi.h>
#include <acpi/actables.h>
-
#define _COMPONENT ACPI_TABLES
ACPI_MODULE_NAME ("tbget")
@@ -287,12 +286,17 @@
acpi_format_exception (status)));
return_ACPI_STATUS (status);
}
-
+
/* Copy the table info */
ACPI_REPORT_INFO (("Table [%4.4s] replaced by host OS\n",
table_info->pointer->signature));
+#ifdef CONFIG_ACPI_INITRD
+ if (new_table)
+ ACPI_MEM_FREE(new_table);
+#endif
+
return_ACPI_STATUS (AE_OK);
}
--- x/drivers/acpi/osl.c.orig 2005-02-24 17:40:55.000000000 +0100
+++ y/drivers/acpi/osl.c 2005-02-26 18:21:06.032348487 +0100
@@ -44,7 +44,10 @@
#include <asm/uaccess.h>
#include <linux/efi.h>
-
+#ifdef CONFIG_ACPI_INITRD
+#include<linux/syscalls.h>
+#include <linux/initrd.h>
+#endif
#define _COMPONENT ACPI_OS_SERVICES
ACPI_MODULE_NAME ("osl")
@@ -246,25 +249,105 @@
return AE_OK;
}
-acpi_status
-acpi_os_table_override (struct acpi_table_header *existing_table,
- struct acpi_table_header **new_table)
-{
- if (!existing_table || !new_table)
- return AE_BAD_PARAMETER;
+#ifdef CONFIG_ACPI_INITRD
+static char *
+acpi_find_dsdt_initrd(void)
+{
+ static const char signature[] = "INITRDDSDT123DSDT123";
+ char *dsdt_start = NULL;
+ char *dsdt_buffer = NULL;
+ unsigned long len = 0, len2 = 0;
+ int fd;
+ char ramfs_dsdt_name[10] = "/DSDT.aml";
+ struct kstat stat;
+
+ /* try to get dsdt from tail of initrd */
+ if ((fd = sys_open(ramfs_dsdt_name, O_RDONLY, 0)) < 0) {
+ if (initrd_start) {
+ char *data = (char *)initrd_start;
+
+ printk(KERN_INFO PREFIX "Looking for DSDT in initrd...");
+
+ /* Search for the start signature */
+ while (data < (char *)initrd_end - sizeof(signature) - 4) {
+ if (!memcmp(data, signature, sizeof(signature))) {
+ data += sizeof(signature);
+ if (!memcmp(data, "DSDT", 4))
+ dsdt_start = data;
+ break;
+ }
+ data++;
+ }
-#ifdef CONFIG_ACPI_CUSTOM_DSDT
- if (strncmp(existing_table->signature, "DSDT", 4) == 0)
- *new_table = (struct acpi_table_header*)AmlCode;
- else
+ if (dsdt_start){
+ printk(PREFIX " found at offset %zu",
+ dsdt_start - (char *)initrd_start);
+ len = (char*) initrd_end - dsdt_start;
+ printk(", size: %zu bytes\n", len);
+ dsdt_buffer = ACPI_MEM_ALLOCATE(len + 1);
+ memcpy(dsdt_buffer, dsdt_start, len);
+ *(dsdt_buffer + len + 1)= '\0';
+ }
+ else
+ printk(" not found!\n");
+ }
+ }
+ /* get dsdt from initramfs */
+ else{
+ printk(KERN_INFO PREFIX "Looking for DSDT in initramfs...");
+ if (vfs_stat(ramfs_dsdt_name, &stat) < 0){
+ printk ("error getting stats for file %s\n", ramfs_dsdt_name);
+ return NULL;
+ }
+
+ len = stat.size;
+ dsdt_buffer = ACPI_MEM_ALLOCATE(len + 1);
+ if (!dsdt_buffer) {
+ printk("Could not allocate %lu bytes of memory\n", len);
+ return NULL;
+ }
+ printk (" found %s ...", ramfs_dsdt_name);
+
+ len2 = sys_read (fd, (char __user *) dsdt_buffer, len);
+ if (len2 < len ){
+ printk(PREFIX "\nError trying to read %lu bytes from %s\n",
+ len, ramfs_dsdt_name);
+ ACPI_MEM_FREE (dsdt_buffer);
+ dsdt_buffer = NULL;
+ }
+ else{
+ printk(" successfully read %lu bytes from %s\n",
+ len, ramfs_dsdt_name);
+ *(dsdt_buffer + len + 1) = '\0';
+ }
+ }
+ if (!dsdt_buffer)
+ printk(" not found!\n");
+ return dsdt_buffer;
+}
+#endif
+
+acpi_status
+ acpi_os_table_override (struct acpi_table_header *existing_table,
+ struct acpi_table_header **new_table)
+ {
+ if (!existing_table || !new_table)
+ return AE_BAD_PARAMETER;
+
*new_table = NULL;
-#else
- *new_table = NULL;
+ if (strncmp(existing_table->signature, "DSDT", 4) == 0) {
+#ifdef CONFIG_ACPI_CUSTOM_DSDT
+ *new_table = (struct acpi_table_header*)AmlCode;
+#elif defined(CONFIG_ACPI_INITRD)
+ *new_table = (struct acpi_table_header*)acpi_find_dsdt_initrd();
#endif
+ if (*new_table)
+ printk(KERN_INFO PREFIX "Using customized DSDT\n");
+ }
return AE_OK;
-}
-
-static irqreturn_t
+ }
+
+ static irqreturn_t
acpi_irq(int irq, void *dev_id, struct pt_regs *regs)
{
return (*acpi_irq_handler)(acpi_irq_context) ? IRQ_HANDLED : IRQ_NONE;
reply other threads:[~2005-02-27 19:45 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=42222364.4040409@renninger.de \
--to=mail-smmupah/rwjm7kwft8n7nw@public.gmane.org \
--cc=acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=eric-z+rTbpWsRgbk7+2FdBfRIA@public.gmane.org \
--cc=hare-l3A5Bk7waGM@public.gmane.org \
--cc=markus-z+rTbpWsRgbk7+2FdBfRIA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox