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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.