Magellan Linux

Annotation of /trunk/kernel26-xen/patches-2.6.25-r1/0157-2.6.25-acpi-dsdt-initrd-0.9a.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 606 - (hide annotations) (download)
Thu May 22 23:13:13 2008 UTC (16 years ago) by niro
File size: 9961 byte(s)
-ver bump to 2.6.25-magellan-r1:
- linux-2.6.25.4
- fbcondecor-0.9.4
- squashfs-3.3
- unionfs-2.3.3
- tuxonice-3.0-rc7
- linux-phc-0.3.0
- acpi-dstd-0.9a
- reiser4
- xen-3.2.0
. ipw3945-1.2.2

1 niro 606 From de31945e20bc0bd255d0264c5d97a6b24906b30a Mon Sep 17 00:00:00 2001
2     From: Eric Piel <piel@localhost.(none)>
3     Date: Wed, 19 Mar 2008 23:00:04 +0100
4     Subject: [PATCH 1/1] ACPI: initramfs DSDT override support
5    
6     Permits to load of DSDT (the main ACPI table) from initramfs. In case this
7     option is selected, the initramfs is parsed at ACPI initialization (very early
8     boot time) to look for a file DSDT.aml . This aims at allowing users to
9     override the DSDT without recompiling the kernel. This is done by adding a new
10     feature to the initramfs parser so that one specific file can be directly
11     copied into memory.
12    
13     This is derived from the patch v0.8 from http://gaugusch.at/kernel.shtml but
14     with kernel inclusion in mind: some clean-up's in the documentation, default
15     set to No, a kernel parameter to disable it at runtime, and most important, a
16     different approach for reading the initramfs which avoids using the filesystem
17     infrastructure.
18    
19     It also contains a fix for compilation on non-ACPI platforms provided by Rene Rebe.
20    
21     Signed-off-by: Eric Piel <eric.piel@tremplin-utc.net>
22     Signed-off-by: Thomas Renninger <trenn@suse.de>
23     Signed-off-by: Len Brown <len.brown@intel.com>
24     ---
25     Documentation/acpi/dsdt-override.txt | 12 ++++-
26     Documentation/acpi/initramfs-add-dsdt.sh | 43 +++++++++++++++++
27     Documentation/kernel-parameters.txt | 3 +
28     drivers/acpi/Kconfig | 11 ++++
29     drivers/acpi/osl.c | 24 ++++++++++
30     init/initramfs.c | 76 ++++++++++++++++++++++++++++++
31     6 files changed, 167 insertions(+), 2 deletions(-)
32     create mode 100644 Documentation/acpi/initramfs-add-dsdt.sh
33    
34     diff --git a/Documentation/acpi/dsdt-override.txt b/Documentation/acpi/dsdt-override.txt
35     index febbb1b..5008f25 100644
36     --- a/Documentation/acpi/dsdt-override.txt
37     +++ b/Documentation/acpi/dsdt-override.txt
38     @@ -1,7 +1,15 @@
39     -Linux supports a method of overriding the BIOS DSDT:
40     +Linux supports two methods of overriding the BIOS DSDT:
41    
42     CONFIG_ACPI_CUSTOM_DSDT builds the image into the kernel.
43    
44     -When to use this method is described in detail on the
45     +CONFIG_ACPI_CUSTOM_DSDT_INITRD adds the image to the initrd.
46     +
47     +When to use these methods is described in detail on the
48     Linux/ACPI home page:
49     http://www.lesswatts.org/projects/acpi/overridingDSDT.php
50     +
51     +Note that if both options are used, the DSDT supplied
52     +by the INITRD method takes precedence.
53     +
54     +Documentation/initramfs-add-dsdt.sh is provided for convenience
55     +for use with the CONFIG_ACPI_CUSTOM_DSDT_INITRD method.
56     diff --git a/Documentation/acpi/initramfs-add-dsdt.sh b/Documentation/acpi/initramfs-add-dsdt.sh
57     new file mode 100644
58     index 0000000..17ef6e8
59     --- /dev/null
60     +++ b/Documentation/acpi/initramfs-add-dsdt.sh
61     @@ -0,0 +1,43 @@
62     +#!/bin/bash
63     +# Adds a DSDT file to the initrd (if it's an initramfs)
64     +# first argument is the name of archive
65     +# second argument is the name of the file to add
66     +# The file will be copied as /DSDT.aml
67     +
68     +# 20060126: fix "Premature end of file" with some old cpio (Roland Robic)
69     +# 20060205: this time it should really work
70     +
71     +# check the arguments
72     +if [ $# -ne 2 ]; then
73     + program_name=$(basename $0)
74     + echo "\
75     +$program_name: too few arguments
76     +Usage: $program_name initrd-name.img DSDT-to-add.aml
77     +Adds a DSDT file to an initrd (in initramfs format)
78     +
79     + initrd-name.img: filename of the initrd in initramfs format
80     + DSDT-to-add.aml: filename of the DSDT file to add
81     + " 1>&2
82     + exit 1
83     +fi
84     +
85     +# we should check it's an initramfs
86     +
87     +tempcpio=$(mktemp -d)
88     +# cleanup on exit, hangup, interrupt, quit, termination
89     +trap 'rm -rf $tempcpio' 0 1 2 3 15
90     +
91     +# extract the archive
92     +gunzip -c "$1" > "$tempcpio"/initramfs.cpio || exit 1
93     +
94     +# copy the DSDT file at the root of the directory so that we can call it "/DSDT.aml"
95     +cp -f "$2" "$tempcpio"/DSDT.aml
96     +
97     +# add the file
98     +cd "$tempcpio"
99     +(echo DSDT.aml | cpio --quiet -H newc -o -A -O "$tempcpio"/initramfs.cpio) || exit 1
100     +cd "$OLDPWD"
101     +
102     +# re-compress the archive
103     +gzip -c "$tempcpio"/initramfs.cpio > "$1"
104     +
105     diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
106     index 622f784..49318b9 100644
107     --- a/Documentation/kernel-parameters.txt
108     +++ b/Documentation/kernel-parameters.txt
109     @@ -177,6 +177,9 @@ and is between 256 and 4096 characters. It is defined in the file
110    
111     acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT
112    
113     + acpi_no_initrd_override [KNL,ACPI]
114     + Disable loading custom ACPI tables from the initramfs
115     +
116     acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS
117     Format: To spoof as Windows 98: ="Microsoft Windows"
118    
119     diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
120     index b4f5e85..fbcaa06 100644
121     --- a/drivers/acpi/Kconfig
122     +++ b/drivers/acpi/Kconfig
123     @@ -300,6 +300,17 @@ config ACPI_CUSTOM_DSDT
124     bool
125     default ACPI_CUSTOM_DSDT_FILE != ""
126    
127     +config ACPI_CUSTOM_DSDT_INITRD
128     + bool "Read Custom DSDT from initramfs"
129     + depends on BLK_DEV_INITRD
130     + default n
131     + help
132     + This option supports a custom DSDT by optionally loading it from initrd.
133     + See Documentation/acpi/dsdt-override.txt
134     +
135     + If you are not using this feature now, but may use it later,
136     + it is safe to say Y here.
137     +
138     config ACPI_BLACKLIST_YEAR
139     int "Disable ACPI for systems before Jan 1st this year" if X86_32
140     default 0
141     diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
142     index a697fb6..8fa630f 100644
143     --- a/drivers/acpi/osl.c
144     +++ b/drivers/acpi/osl.c
145     @@ -91,6 +91,11 @@ static DEFINE_SPINLOCK(acpi_res_lock);
146     #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
147     static char osi_additional_string[OSI_STRING_LENGTH_MAX];
148    
149     +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
150     +static int acpi_no_initrd_override;
151     +extern struct acpi_table_header *acpi_find_dsdt_initrd(void);
152     +#endif
153     +
154     /*
155     * "Ode to _OSI(Linux)"
156     *
157     @@ -333,6 +338,16 @@ acpi_os_table_override(struct acpi_table_header * existing_table,
158     if (strncmp(existing_table->signature, "DSDT", 4) == 0)
159     *new_table = (struct acpi_table_header *)AmlCode;
160     #endif
161     +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
162     + if ((strncmp(existing_table->signature, "DSDT", 4) == 0) &&
163     + !acpi_no_initrd_override) {
164     + struct acpi_table_header *initrd_table;
165     +
166     + initrd_table = acpi_find_dsdt_initrd();
167     + if (initrd_table)
168     + *new_table = initrd_table;
169     + }
170     +#endif
171     if (*new_table != NULL) {
172     printk(KERN_WARNING PREFIX "Override [%4.4s-%8.8s], "
173     "this is unsafe: tainting kernel\n",
174     @@ -343,6 +358,15 @@ acpi_os_table_override(struct acpi_table_header * existing_table,
175     return AE_OK;
176     }
177    
178     +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
179     +static int __init acpi_no_initrd_override_setup(char *s)
180     +{
181     + acpi_no_initrd_override = 1;
182     + return 1;
183     +}
184     +__setup("acpi_no_initrd_override", acpi_no_initrd_override_setup);
185     +#endif
186     +
187     static irqreturn_t acpi_irq(int irq, void *dev_id)
188     {
189     u32 handled;
190     diff --git a/init/initramfs.c b/init/initramfs.c
191     index d53fee8..495380c 100644
192     --- a/init/initramfs.c
193     +++ b/init/initramfs.c
194     @@ -6,6 +6,9 @@
195     #include <linux/delay.h>
196     #include <linux/string.h>
197     #include <linux/syscalls.h>
198     +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
199     +#include <acpi/acpi.h>
200     +#endif
201    
202     static __initdata char *message;
203     static void __init error(char *x)
204     @@ -90,6 +91,12 @@ static __initdata unsigned long body_len, name_len;
205     static __initdata uid_t uid;
206     static __initdata gid_t gid;
207     static __initdata unsigned rdev;
208     +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
209     +static __initdata char *file_looked_for;
210     +static __initdata struct acpi_table_header *file_mem;
211     +#else
212     +const char *file_looked_for = NULL;
213     +#endif
214    
215     static void __init parse_header(char *s)
216     {
217     @@ -123,6 +130,7 @@ static __initdata enum state {
218     SkipIt,
219     GotName,
220     CopyFile,
221     + CopyFileMem,
222     GotSymlink,
223     Reset
224     } state, next_state;
225     @@ -267,6 +275,9 @@ static int __init do_name(void)
226     free_hash();
227     return 0;
228     }
229     + if (file_looked_for && S_ISREG(mode) &&
230     + (strcmp(collected, file_looked_for) == 0))
231     + state = CopyFileMem;
232     if (dry_run)
233     return 0;
234     clean_path(collected, mode);
235     @@ -299,6 +310,40 @@ static int __init do_name(void)
236     return 0;
237     }
238    
239     +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
240     +static int __init do_copy_mem(void)
241     +{
242     + static void *file_current; /* current position in the memory */
243     + if (file_mem == NULL) {
244     + if (body_len < 4) { /* check especially against empty files */
245     + error("file is less than 4 bytes");
246     + return 1;
247     + }
248     + file_mem = kmalloc(body_len, GFP_ATOMIC);
249     + if (!file_mem) {
250     + error("failed to allocate enough memory");
251     + return 1;
252     + }
253     + file_current = file_mem;
254     + }
255     + if (count >= body_len) {
256     + memcpy(file_current, victim, body_len);
257     + eat(body_len);
258     + file_looked_for = NULL; /* don't find files with same name */
259     + state = SkipIt;
260     + return 0;
261     + } else {
262     + memcpy(file_current, victim, count);
263     + file_current += count;
264     + body_len -= count;
265     + eat(count);
266     + return 1;
267     + }
268     +}
269     +#else
270     +#define do_copy_mem NULL
271     +#endif
272     +
273     static int __init do_copy(void)
274     {
275     if (count >= body_len) {
276     @@ -333,6 +378,7 @@ static __initdata int (*actions[])(void) = {
277     [SkipIt] = do_skip,
278     [GotName] = do_name,
279     [CopyFile] = do_copy,
280     + [CopyFileMem] = do_copy_mem,
281     [GotSymlink] = do_symlink,
282     [Reset] = do_reset,
283     };
284     @@ -578,3 +624,31 @@ static int __init populate_rootfs(void)
285     return 0;
286     }
287     rootfs_initcall(populate_rootfs);
288     +
289     +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
290     +struct acpi_table_header *acpi_find_dsdt_initrd(void)
291     +{
292     + char *err, *ramfs_dsdt_name = "DSDT.aml";
293     +
294     + printk(KERN_INFO "ACPI: Checking initramfs for custom DSDT\n");
295     + file_mem = NULL;
296     + file_looked_for = ramfs_dsdt_name;
297     + err = unpack_to_rootfs((char *)initrd_start,
298     + initrd_end - initrd_start, 1);
299     + file_looked_for = NULL;
300     +
301     + if (err) {
302     + /*
303     + * Even if reading the DSDT file was successful,
304     + * we give up if the initramfs cannot be entirely read.
305     + */
306     + kfree(file_mem);
307     + printk(KERN_ERR "ACPI: Aborded because %s.\n", err);
308     + return NULL;
309     + }
310     + if (file_mem)
311     + printk(KERN_INFO "ACPI: Found DSDT in %s.\n", ramfs_dsdt_name);
312     +
313     + return file_mem;
314     +}
315     +#endif
316     --
317     1.5.4.3
318