Annotation of /trunk/kernel26-alx/patches-2.6.24-r2/0157-2.6.24-acpi-dsdt-initrd-0.8.4.patch
Parent Directory | Revision Log
Revision 652 -
(hide annotations)
(download)
Sun Jun 22 12:19:22 2008 UTC (16 years, 3 months ago) by niro
File size: 11079 byte(s)
Sun Jun 22 12:19:22 2008 UTC (16 years, 3 months ago) by niro
File size: 11079 byte(s)
2.6.24-alx-r2: -added patch to strip all debugging symbols resulting in a much smaller kernel -enabled this option in Kconfig
1 | niro | 652 | 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 */ |