Loading Documentation/acpi/dsdt-override.txt 0 → 100644 +15 −0 Original line number Diff line number Diff line Linux supports two methods of overriding the BIOS DSDT: CONFIG_ACPI_CUSTOM_DSDT builds the image into the kernel. CONFIG_ACPI_CUSTOM_DSDT_INITRD adds the image to the initrd. When to use these methods is described in detail on the Linux/ACPI home page: http://www.lesswatts.org/projects/acpi/overridingDSDT.php Note that if both options are used, the DSDT supplied by the INITRD method takes precedence. Documentation/initramfs-add-dsdt.sh is provided for convenience for use with the CONFIG_ACPI_CUSTOM_DSDT_INITRD method. Documentation/acpi/initramfs-add-dsdt.sh 0 → 100755 +43 −0 Original line number Diff line number Diff line #!/bin/bash # Adds a DSDT file to the initrd (if it's an initramfs) # first argument is the name of archive # second argument is the name of the file to add # The file will be copied as /DSDT.aml # 20060126: fix "Premature end of file" with some old cpio (Roland Robic) # 20060205: this time it should really work # check the arguments if [ $# -ne 2 ]; then program_name=$(basename $0) echo "\ $program_name: too few arguments Usage: $program_name initrd-name.img DSDT-to-add.aml Adds a DSDT file to an initrd (in initramfs format) initrd-name.img: filename of the initrd in initramfs format DSDT-to-add.aml: filename of the DSDT file to add " 1>&2 exit 1 fi # we should check it's an initramfs tempcpio=$(mktemp -d) # cleanup on exit, hangup, interrupt, quit, termination trap 'rm -rf $tempcpio' 0 1 2 3 15 # extract the archive gunzip -c "$1" > "$tempcpio"/initramfs.cpio || exit 1 # copy the DSDT file at the root of the directory so that we can call it "/DSDT.aml" cp -f "$2" "$tempcpio"/DSDT.aml # add the file cd "$tempcpio" (echo DSDT.aml | cpio --quiet -H newc -o -A -O "$tempcpio"/initramfs.cpio) || exit 1 cd "$OLDPWD" # re-compress the archive gzip -c "$tempcpio"/initramfs.cpio > "$1" Documentation/kernel-parameters.txt +3 −0 Original line number Diff line number Diff line Loading @@ -177,6 +177,9 @@ and is between 256 and 4096 characters. It is defined in the file acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT acpi_no_initrd_override [KNL,ACPI] Disable loading custom ACPI tables from the initramfs acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS Format: To spoof as Windows 98: ="Microsoft Windows" Loading drivers/acpi/Kconfig +15 −2 Original line number Diff line number Diff line Loading @@ -276,8 +276,10 @@ config ACPI_CUSTOM_DSDT depends on !STANDALONE default n help This option is to load a custom ACPI DSDT If you don't know what that is, say N. This option supports a custom DSDT by linking it into the kernel. See Documentation/acpi/dsdt-override.txt If unsure, say N. config ACPI_CUSTOM_DSDT_FILE string "Custom DSDT Table file to include" Loading @@ -287,6 +289,17 @@ config ACPI_CUSTOM_DSDT_FILE Enter the full path name to the file which includes the AmlCode declaration. config ACPI_CUSTOM_DSDT_INITRD bool "Read Custom DSDT from initramfs" depends on BLK_DEV_INITRD default n help This option supports a custom DSDT by optionally loading it from initrd. See Documentation/acpi/dsdt-override.txt If you are not using this feature now, but may use it later, it is safe to say Y here. config ACPI_BLACKLIST_YEAR int "Disable ACPI for systems before Jan 1st this year" if X86_32 default 0 Loading drivers/acpi/osl.c +93 −4 Original line number Diff line number Diff line Loading @@ -91,6 +91,10 @@ static DEFINE_SPINLOCK(acpi_res_lock); #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ static char osi_additional_string[OSI_STRING_LENGTH_MAX]; #ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD static int acpi_no_initrd_override; #endif /* * "Ode to _OSI(Linux)" * Loading Loading @@ -329,6 +333,67 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val, return AE_OK; } #ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD struct acpi_table_header *acpi_find_dsdt_initrd(void) { struct file *firmware_file; mm_segment_t oldfs; unsigned long len, len2; struct acpi_table_header *dsdt_buffer, *ret = NULL; struct kstat stat; char *ramfs_dsdt_name = "/DSDT.aml"; printk(KERN_INFO PREFIX "Checking initramfs for custom DSDT"); /* * Never do this at home, only the user-space is allowed to open a file. * The clean way would be to use the firmware loader. * But this code must be run before there is any userspace available. * A static/init firmware infrastructure doesn't exist yet... */ if (vfs_stat(ramfs_dsdt_name, &stat) < 0) return ret; len = stat.size; /* check especially against empty files */ if (len <= 4) { printk(KERN_ERR PREFIX "Failed: DSDT only %lu bytes.\n", len); return ret; } firmware_file = filp_open(ramfs_dsdt_name, O_RDONLY, 0); if (IS_ERR(firmware_file)) { printk(KERN_ERR PREFIX "Failed to open %s.\n", ramfs_dsdt_name); return ret; } dsdt_buffer = kmalloc(len, GFP_ATOMIC); if (!dsdt_buffer) { printk(KERN_ERR PREFIX "Failed to allocate %lu bytes.\n", len); goto err; } oldfs = get_fs(); set_fs(KERNEL_DS); len2 = vfs_read(firmware_file, (char __user *)dsdt_buffer, len, &firmware_file->f_pos); set_fs(oldfs); if (len2 < len) { printk(KERN_ERR PREFIX "Failed to read %lu bytes from %s.\n", len, ramfs_dsdt_name); ACPI_FREE(dsdt_buffer); goto err; } printk(KERN_INFO PREFIX "Found %lu byte DSDT in %s.\n", len, ramfs_dsdt_name); ret = dsdt_buffer; err: filp_close(firmware_file, NULL); return ret; } #endif acpi_status acpi_os_table_override(struct acpi_table_header * existing_table, struct acpi_table_header ** new_table) Loading @@ -336,17 +401,41 @@ acpi_os_table_override(struct acpi_table_header * existing_table, if (!existing_table || !new_table) return AE_BAD_PARAMETER; *new_table = NULL; #ifdef CONFIG_ACPI_CUSTOM_DSDT if (strncmp(existing_table->signature, "DSDT", 4) == 0) *new_table = (struct acpi_table_header *)AmlCode; else *new_table = NULL; #else *new_table = NULL; #endif #ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD if ((strncmp(existing_table->signature, "DSDT", 4) == 0) && !acpi_no_initrd_override) { struct acpi_table_header *initrd_table; initrd_table = acpi_find_dsdt_initrd(); if (initrd_table) *new_table = initrd_table; } #endif if (*new_table != NULL) { printk(KERN_WARNING PREFIX "Override [%4.4s-%8.8s], " "this is unsafe: tainting kernel\n", existing_table->signature, existing_table->oem_table_id); add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); } return AE_OK; } #ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD int __init acpi_no_initrd_override_setup(char *s) { acpi_no_initrd_override = 1; return 1; } __setup("acpi_no_initrd_override", acpi_no_initrd_override_setup); #endif static irqreturn_t acpi_irq(int irq, void *dev_id) { u32 handled; Loading Loading
Documentation/acpi/dsdt-override.txt 0 → 100644 +15 −0 Original line number Diff line number Diff line Linux supports two methods of overriding the BIOS DSDT: CONFIG_ACPI_CUSTOM_DSDT builds the image into the kernel. CONFIG_ACPI_CUSTOM_DSDT_INITRD adds the image to the initrd. When to use these methods is described in detail on the Linux/ACPI home page: http://www.lesswatts.org/projects/acpi/overridingDSDT.php Note that if both options are used, the DSDT supplied by the INITRD method takes precedence. Documentation/initramfs-add-dsdt.sh is provided for convenience for use with the CONFIG_ACPI_CUSTOM_DSDT_INITRD method.
Documentation/acpi/initramfs-add-dsdt.sh 0 → 100755 +43 −0 Original line number Diff line number Diff line #!/bin/bash # Adds a DSDT file to the initrd (if it's an initramfs) # first argument is the name of archive # second argument is the name of the file to add # The file will be copied as /DSDT.aml # 20060126: fix "Premature end of file" with some old cpio (Roland Robic) # 20060205: this time it should really work # check the arguments if [ $# -ne 2 ]; then program_name=$(basename $0) echo "\ $program_name: too few arguments Usage: $program_name initrd-name.img DSDT-to-add.aml Adds a DSDT file to an initrd (in initramfs format) initrd-name.img: filename of the initrd in initramfs format DSDT-to-add.aml: filename of the DSDT file to add " 1>&2 exit 1 fi # we should check it's an initramfs tempcpio=$(mktemp -d) # cleanup on exit, hangup, interrupt, quit, termination trap 'rm -rf $tempcpio' 0 1 2 3 15 # extract the archive gunzip -c "$1" > "$tempcpio"/initramfs.cpio || exit 1 # copy the DSDT file at the root of the directory so that we can call it "/DSDT.aml" cp -f "$2" "$tempcpio"/DSDT.aml # add the file cd "$tempcpio" (echo DSDT.aml | cpio --quiet -H newc -o -A -O "$tempcpio"/initramfs.cpio) || exit 1 cd "$OLDPWD" # re-compress the archive gzip -c "$tempcpio"/initramfs.cpio > "$1"
Documentation/kernel-parameters.txt +3 −0 Original line number Diff line number Diff line Loading @@ -177,6 +177,9 @@ and is between 256 and 4096 characters. It is defined in the file acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT acpi_no_initrd_override [KNL,ACPI] Disable loading custom ACPI tables from the initramfs acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS Format: To spoof as Windows 98: ="Microsoft Windows" Loading
drivers/acpi/Kconfig +15 −2 Original line number Diff line number Diff line Loading @@ -276,8 +276,10 @@ config ACPI_CUSTOM_DSDT depends on !STANDALONE default n help This option is to load a custom ACPI DSDT If you don't know what that is, say N. This option supports a custom DSDT by linking it into the kernel. See Documentation/acpi/dsdt-override.txt If unsure, say N. config ACPI_CUSTOM_DSDT_FILE string "Custom DSDT Table file to include" Loading @@ -287,6 +289,17 @@ config ACPI_CUSTOM_DSDT_FILE Enter the full path name to the file which includes the AmlCode declaration. config ACPI_CUSTOM_DSDT_INITRD bool "Read Custom DSDT from initramfs" depends on BLK_DEV_INITRD default n help This option supports a custom DSDT by optionally loading it from initrd. See Documentation/acpi/dsdt-override.txt If you are not using this feature now, but may use it later, it is safe to say Y here. config ACPI_BLACKLIST_YEAR int "Disable ACPI for systems before Jan 1st this year" if X86_32 default 0 Loading
drivers/acpi/osl.c +93 −4 Original line number Diff line number Diff line Loading @@ -91,6 +91,10 @@ static DEFINE_SPINLOCK(acpi_res_lock); #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ static char osi_additional_string[OSI_STRING_LENGTH_MAX]; #ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD static int acpi_no_initrd_override; #endif /* * "Ode to _OSI(Linux)" * Loading Loading @@ -329,6 +333,67 @@ acpi_os_predefined_override(const struct acpi_predefined_names *init_val, return AE_OK; } #ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD struct acpi_table_header *acpi_find_dsdt_initrd(void) { struct file *firmware_file; mm_segment_t oldfs; unsigned long len, len2; struct acpi_table_header *dsdt_buffer, *ret = NULL; struct kstat stat; char *ramfs_dsdt_name = "/DSDT.aml"; printk(KERN_INFO PREFIX "Checking initramfs for custom DSDT"); /* * Never do this at home, only the user-space is allowed to open a file. * The clean way would be to use the firmware loader. * But this code must be run before there is any userspace available. * A static/init firmware infrastructure doesn't exist yet... */ if (vfs_stat(ramfs_dsdt_name, &stat) < 0) return ret; len = stat.size; /* check especially against empty files */ if (len <= 4) { printk(KERN_ERR PREFIX "Failed: DSDT only %lu bytes.\n", len); return ret; } firmware_file = filp_open(ramfs_dsdt_name, O_RDONLY, 0); if (IS_ERR(firmware_file)) { printk(KERN_ERR PREFIX "Failed to open %s.\n", ramfs_dsdt_name); return ret; } dsdt_buffer = kmalloc(len, GFP_ATOMIC); if (!dsdt_buffer) { printk(KERN_ERR PREFIX "Failed to allocate %lu bytes.\n", len); goto err; } oldfs = get_fs(); set_fs(KERNEL_DS); len2 = vfs_read(firmware_file, (char __user *)dsdt_buffer, len, &firmware_file->f_pos); set_fs(oldfs); if (len2 < len) { printk(KERN_ERR PREFIX "Failed to read %lu bytes from %s.\n", len, ramfs_dsdt_name); ACPI_FREE(dsdt_buffer); goto err; } printk(KERN_INFO PREFIX "Found %lu byte DSDT in %s.\n", len, ramfs_dsdt_name); ret = dsdt_buffer; err: filp_close(firmware_file, NULL); return ret; } #endif acpi_status acpi_os_table_override(struct acpi_table_header * existing_table, struct acpi_table_header ** new_table) Loading @@ -336,17 +401,41 @@ acpi_os_table_override(struct acpi_table_header * existing_table, if (!existing_table || !new_table) return AE_BAD_PARAMETER; *new_table = NULL; #ifdef CONFIG_ACPI_CUSTOM_DSDT if (strncmp(existing_table->signature, "DSDT", 4) == 0) *new_table = (struct acpi_table_header *)AmlCode; else *new_table = NULL; #else *new_table = NULL; #endif #ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD if ((strncmp(existing_table->signature, "DSDT", 4) == 0) && !acpi_no_initrd_override) { struct acpi_table_header *initrd_table; initrd_table = acpi_find_dsdt_initrd(); if (initrd_table) *new_table = initrd_table; } #endif if (*new_table != NULL) { printk(KERN_WARNING PREFIX "Override [%4.4s-%8.8s], " "this is unsafe: tainting kernel\n", existing_table->signature, existing_table->oem_table_id); add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); } return AE_OK; } #ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD int __init acpi_no_initrd_override_setup(char *s) { acpi_no_initrd_override = 1; return 1; } __setup("acpi_no_initrd_override", acpi_no_initrd_override_setup); #endif static irqreturn_t acpi_irq(int irq, void *dev_id) { u32 handled; Loading