Magellan Linux

Contents of /trunk/kernel26-magellan/patches-2.6.21-r4/0157-2.6.21-acpi-dsdt-initrd-0.8.4.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 222 - (show annotations) (download)
Tue Jun 12 08:03:28 2007 UTC (16 years, 10 months ago) by niro
File size: 11079 byte(s)
files for 2.6.21-magellan-r4

1 diff -urpN -X linux-2.6.21/Documentation/dontdiff linux-2.6.21-rc4.bak/Documentation/dsdt-initrd.txt linux-2.6.21/Documentation/dsdt-initrd.txt
2 --- linux-2.6.21-rc4.bak/Documentation/dsdt-initrd.txt 1970-01-01 01:00:00.000000000 +0100
3 +++ linux-2.6.21/Documentation/dsdt-initrd.txt 2007-03-03 23:06:58.000000000 +0100
4 @@ -0,0 +1,98 @@
5 +ACPI Custom DSDT read from initramfs
6 +
7 +2003 by Markuss Gaugusch < dsdt at gaugusch dot org >
8 +Special thanks go to Thomas Renninger from SuSE, who updated the patch for
9 +2.6.0 and later modified it to read inside initramfs
10 +2004 - 2007 maintained by Eric Piel < eric dot piel at tremplin-utc dot net >
11 +
12 +This option is intended for people who would like to hack their DSDT and don't want
13 +to recompile their kernel after every change. It can also be useful to distros
14 +which offers pre-compiled kernels and want to allow their users to use a
15 +modified DSDT. In the Kernel config, enable the initial RAM filesystem support
16 +(in Device Drivers|Block Devices) and enable ACPI_CUSTOM_DSDT_INITRD at the ACPI
17 +options (General Setup|ACPI Support|Read custom DSDT from initrd).
18 +
19 +A custom DSDT (Differentiated System Description Table) is useful when your
20 +computer uses ACPI but problems occur due to broken implementation. Typically,
21 +your computer works but there are some troubles with the hardware detection or
22 +the power management. You can check that troubles come from errors in the DSDT by
23 +activating the ACPI debug option and reading the logs. This table is provided
24 +by the BIOS, therefore it might be a good idea to check for BIOS update on your
25 +vendor website before going any further. Errors are often caused by vendors
26 +testing their hardware only with Windows or because there is code which is
27 +executed only on a specific OS with a specific version and Linux hasn't been
28 +considered during the development.
29 +
30 +Before you run away from customising your DSDT, you should note that already
31 +corrected tables are available for a fair amount of computers on this web-page:
32 +http://acpi.sf.net/dsdt . If you are part of the unluckies who cannot find
33 +their hardware in this database, you can modify your DSDT by yourself. This
34 +process is less painful than it sounds. Download the Intel ASL
35 +compiler/decompiler at http://www.intel.com/technology/IAPC/acpi/downloads.htm .
36 +As root, you then have to dump your DSDT and decompile it. By using the
37 +compiler messages as well as the kernel ACPI debug messages and the reference book
38 +(available at the Intel website and also at http://www.acpi.info), it is quite
39 +easy to obtain a fully working table.
40 +
41 +Once your new DSDT is ready you'll have to add it to an initrd so that the
42 +kernel can read the table at the very beginning of the boot. As the file has
43 +to be accessed very early during the boot process the initrd has to be an
44 +initramfs. The file is contained into the initramfs under the name /DSDT.aml .
45 +To obtain such an initrd, you might have to modify your mkinitrd script or you
46 +can add it later to the initrd with the script appended to this document. The
47 +command will look like:
48 +initrd-add-dsdt initrd.img my-dsdt.aml
49 +
50 +In case you don't use any initrd, the possibilities you have are to either start
51 +using one (try mkinitrd or yaird), or use the "Include Custom DSDT" configure
52 +option to directly include your DSDT inside the kernel.
53 +
54 +The message "Looking for DSDT in initramfs..." will tell you if the DSDT was
55 +found or not. If you need to update your DSDT, generate a new initrd and
56 +perform the steps above. Don't forget that with Lilo, you'll have to re-run it.
57 +
58 +
59 +======================= Here starts initrd-add-dsdt ===============================
60 +#!/bin/bash
61 +# Adds a DSDT file to the initrd (if it's an initramfs)
62 +# first argument is the name of archive
63 +# second argurment is the name of the file to add
64 +# The file will be copied as /DSDT.aml
65 +
66 +# 20060126: fix "Premature end of file" with some old cpio (Roland Robic)
67 +# 20060205: this time it should really work
68 +
69 +# check the arguments
70 +if [ $# -ne 2 ]; then
71 + program_name=$(basename $0)
72 + echo "\
73 +$program_name: too few arguments
74 +Usage: $program_name initrd-name.img DSDT-to-add.aml
75 +Adds a DSDT file to an initrd (in initramfs format)
76 +
77 + initrd-name.img: filename of the initrd in initramfs format
78 + DSDT-to-add.aml: filename of the DSDT file to add
79 + " 1>&2
80 + exit 1
81 +fi
82 +
83 +# we should check it's an initramfs
84 +
85 +tempcpio=$(mktemp -d)
86 +# cleanup on exit, hangup, interrupt, quit, termination
87 +trap 'rm -rf $tempcpio' 0 1 2 3 15
88 +
89 +# extract the archive
90 +gunzip -c "$1" > "$tempcpio"/initramfs.cpio || exit 1
91 +
92 +# copy the DSDT file at the root of the directory so that we can call it "/DSDT.aml"
93 +cp -f "$2" "$tempcpio"/DSDT.aml
94 +
95 +# add the file
96 +cd "$tempcpio"
97 +(echo DSDT.aml | cpio --quiet -H newc -o -A -O "$tempcpio"/initramfs.cpio) || exit 1
98 +cd "$OLDPWD"
99 +
100 +# re-compress the archive
101 +gzip -c "$tempcpio"/initramfs.cpio > "$1"
102 +
103 diff -urpN -X linux-2.6.21/Documentation/dontdiff linux-2.6.21-rc4.bak/drivers/acpi/Kconfig linux-2.6.21/drivers/acpi/Kconfig
104 --- linux-2.6.21-rc4.bak/drivers/acpi/Kconfig 2007-03-18 12:58:03.000000000 +0100
105 +++ linux-2.6.21/drivers/acpi/Kconfig 2007-03-17 01:28:53.000000000 +0100
106 @@ -298,6 +298,23 @@ config ACPI_CUSTOM_DSDT_FILE
107 Enter the full path name to the file which includes the AmlCode
108 declaration.
109
110 +config ACPI_CUSTOM_DSDT_INITRD
111 + bool "Read Custom DSDT from initramfs"
112 + depends on BLK_DEV_INITRD
113 + default y
114 + help
115 + The DSDT (Differentiated System Description Table) often needs to be
116 + overridden because of broken BIOS implementations. If this feature is
117 + activated you will be able to provide a customized DSDT by adding it
118 + to your initramfs. For now you need to use a special mkinitrd tool.
119 + For more details see <file:Documentation/dsdt-initrd.txt> or
120 + <http://gaugusch.at/kernel.shtml>. If there is no table found, it
121 + will fallback to the custom DSDT in-kernel (if activated) or to the
122 + DSDT from the BIOS.
123 +
124 + Even if you do not need a new one at the moment, you may want to use a
125 + better implemented DSDT later. It is safe to say Y here.
126 +
127 config ACPI_BLACKLIST_YEAR
128 int "Disable ACPI for systems before Jan 1st this year" if X86_32
129 default 0
130 diff -urpN -X linux-2.6.21/Documentation/dontdiff linux-2.6.21-rc4.bak/drivers/acpi/osl.c linux-2.6.21/drivers/acpi/osl.c
131 --- linux-2.6.21-rc4.bak/drivers/acpi/osl.c 2007-03-18 12:55:13.000000000 +0100
132 +++ linux-2.6.21/drivers/acpi/osl.c 2007-03-17 10:26:06.000000000 +0100
133 @@ -256,6 +256,67 @@ acpi_os_predefined_override(const struct
134 return AE_OK;
135 }
136
137 +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
138 +struct acpi_table_header * acpi_find_dsdt_initrd(void)
139 +{
140 + struct file *firmware_file;
141 + mm_segment_t oldfs;
142 + unsigned long len, len2;
143 + struct acpi_table_header *dsdt_buffer, *ret = NULL;
144 + struct kstat stat;
145 + /* maybe this could be an argument on the cmd line, but let's keep it simple for now */
146 + char *ramfs_dsdt_name = "/DSDT.aml";
147 +
148 + printk(KERN_INFO PREFIX "Looking for DSDT in initramfs... ");
149 +
150 + /*
151 + * Never do this at home, only the user-space is allowed to open a file.
152 + * The clean way would be to use the firmware loader. But this code must be run
153 + * before there is any userspace available. So we need a static/init firmware
154 + * infrastructure, which doesn't exist yet...
155 + */
156 + if (vfs_stat(ramfs_dsdt_name, &stat) < 0) {
157 + printk("error, file %s not found.\n", ramfs_dsdt_name);
158 + return ret;
159 + }
160 +
161 + len = stat.size;
162 + /* check especially against empty files */
163 + if (len <= 4) {
164 + printk("error file is too small, only %lu bytes.\n", len);
165 + return ret;
166 + }
167 +
168 + firmware_file = filp_open(ramfs_dsdt_name, O_RDONLY, 0);
169 + if (IS_ERR(firmware_file)) {
170 + printk("error, could not open file %s.\n", ramfs_dsdt_name);
171 + return ret;
172 + }
173 +
174 + dsdt_buffer = ACPI_ALLOCATE(len);
175 + if (!dsdt_buffer) {
176 + printk("error when allocating %lu bytes of memory.\n", len);
177 + goto err;
178 + }
179 +
180 + oldfs = get_fs();
181 + set_fs(KERNEL_DS);
182 + len2 = vfs_read(firmware_file, (char __user *)dsdt_buffer, len, &firmware_file->f_pos);
183 + set_fs(oldfs);
184 + if (len2 < len) {
185 + printk("error trying to read %lu bytes from %s.\n", len, ramfs_dsdt_name);
186 + ACPI_FREE(dsdt_buffer);
187 + goto err;
188 + }
189 +
190 + printk("successfully read %lu bytes from %s.\n", len, ramfs_dsdt_name);
191 + ret = dsdt_buffer;
192 +err:
193 + filp_close(firmware_file, NULL);
194 + return ret;
195 +}
196 +#endif
197 +
198 acpi_status
199 acpi_os_table_override(struct acpi_table_header * existing_table,
200 struct acpi_table_header ** new_table)
201 @@ -263,13 +324,18 @@ acpi_os_table_override(struct acpi_table
202 if (!existing_table || !new_table)
203 return AE_BAD_PARAMETER;
204
205 + *new_table = NULL;
206 +
207 #ifdef CONFIG_ACPI_CUSTOM_DSDT
208 if (strncmp(existing_table->signature, "DSDT", 4) == 0)
209 *new_table = (struct acpi_table_header *)AmlCode;
210 - else
211 - *new_table = NULL;
212 -#else
213 - *new_table = NULL;
214 +#endif
215 +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
216 + if (strncmp(existing_table->signature, "DSDT", 4) == 0) {
217 + struct acpi_table_header* initrd_table = acpi_find_dsdt_initrd();
218 + if (initrd_table)
219 + *new_table = initrd_table;
220 + }
221 #endif
222 return AE_OK;
223 }
224 diff -urpN -X linux-2.6.21/Documentation/dontdiff linux-2.6.21-rc4.bak/init/initramfs.c linux-2.6.21/init/initramfs.c
225 --- linux-2.6.21-rc4.bak/init/initramfs.c 2007-03-18 12:56:47.000000000 +0100
226 +++ linux-2.6.21/init/initramfs.c 2007-03-03 23:07:05.000000000 +0100
227 @@ -541,6 +541,26 @@ skip:
228
229 #endif
230
231 +/* Tries to read the initramfs if it's already there, for ACPI Table Overiding */
232 +void __init early_populate_rootfs(void)
233 +{
234 + char *err = unpack_to_rootfs(__initramfs_start,
235 + __initramfs_end - __initramfs_start, 0);
236 + if (err)
237 + return;
238 +#ifdef CONFIG_BLK_DEV_INITRD
239 + if (initrd_start) {
240 + printk(KERN_INFO "Early unpacking initramfs...");
241 + err = unpack_to_rootfs((char *)initrd_start,
242 + initrd_end - initrd_start, 0);
243 + if (err)
244 + return;
245 + printk(" done\n");
246 + }
247 +#endif
248 + return;
249 +}
250 +
251 static int __init populate_rootfs(void)
252 {
253 char *err = unpack_to_rootfs(__initramfs_start,
254 diff -urpN -X linux-2.6.21/Documentation/dontdiff linux-2.6.21-rc4.bak/init/main.c linux-2.6.21/init/main.c
255 --- linux-2.6.21-rc4.bak/init/main.c 2007-03-18 12:56:47.000000000 +0100
256 +++ linux-2.6.21/init/main.c 2007-03-03 23:07:05.000000000 +0100
257 @@ -97,8 +97,14 @@ extern void free_initmem(void);
258 extern void prepare_namespace(void);
259 #ifdef CONFIG_ACPI
260 extern void acpi_early_init(void);
261 +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
262 +extern void early_populate_rootfs(void);
263 +#endif
264 #else
265 static inline void acpi_early_init(void) { }
266 +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
267 +static inline void early_populate_rootfs(void) { }
268 +#endif
269 #endif
270 #ifndef CONFIG_DEBUG_RODATA
271 static inline void mark_rodata_ro(void) { }
272 @@ -635,6 +637,9 @@ asmlinkage void __init start_kernel(void
273
274 check_bugs();
275
276 + #ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD
277 + early_populate_rootfs(); /* For DSDT override from initramfs */
278 + #endif
279 acpi_early_init(); /* before LAPIC and SMP init */
280
281 /* Do the rest non-__init'ed, we're now alive */