diff mbox

[v1,3/9] board/intel/common: Add possibility for adding ACPI tables to the initrd

Message ID 1472133887-34746-4-git-send-email-andriy.shevchenko@linux.intel.com
State Changes Requested
Headers show

Commit Message

Andy Shevchenko Aug. 25, 2016, 2:04 p.m. UTC
Add script which takes ASL files as input, compiles them to AML bytecode,
and prepends the whole thing to the initrd archive. They are placed in
kernel/firmware/acpi directory where the kernel is able to find and use
them.

The script requires iasl host tool that would be provided by acpica package.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
---
 board/intel/common/README.rst                  | 19 +++++-
 board/intel/common/post-image.d/80-acpi-tables | 86 ++++++++++++++++++++++++++
 configs/intel_defconfig                        |  3 +
 3 files changed, 107 insertions(+), 1 deletion(-)
 create mode 100755 board/intel/common/post-image.d/80-acpi-tables

Comments

Thomas Petazzoni Aug. 25, 2016, 9:43 p.m. UTC | #1
Hello,

On Thu, 25 Aug 2016 17:04:41 +0300, Andy Shevchenko wrote:

>  in order to take advantage of these.
>  
> +BOARD_INTEL_ACPI_TABLES
> +	list of table names to built into the ``initrd``.

Please make this a Buildroot configuration option.

> +# Pick iASL.
> +# First try from buildroot and if not there then try from the host.
> +[ -x "$HOST_DIR/usr/bin/iasl" ] && iasl="$HOST_DIR/usr/bin/iasl" || iasl=$(which iasl)
> +
> +[ -x "$iasl" ] || {
> +	echo "You need to to have iASL compiler available. You can either enable"
> +	echo "BR2_PACKAGE_HOST_ACPICA or install it locally for your host."
> +	echo "Typically the package is called acpica-tools in major distros".
> +	exit 1
> +}
> +
> +# The name of the folder is the name of a board
> +board_name="${BOARD_DIR##*/}"
> +[ "$board_name" = "common" ] && {
> +	echo "Adding ACPI tables is always specific to a board!"
> +	echo "You are not supposed to use common as board here!"
> +	exit 1
> +}
> +
> +# Always prefix with the board name to avoid mistakes if the initrd is used
> +# with another board.
> +updated_initrd_name="${board_name}-acpi-rootfs.cpio"
> +updated_initrd="$BINARIES_DIR/$updated_initrd_name"
> +initrd="$(readlink -enq "$BINARIES_DIR/initrd")"
> +tmpamldir="$BINARIES_DIR/acpi-tables"
> +
> +# Make sure existing tables get cleared
> +rm -fr $tmpamldir
> +mkdir -p $tmpamldir/kernel/firmware/acpi
> +
> +for table in $ACPI_TABLES; do
> +	[ -f "$ACPI_DIR/$table" ] || continue
> +
> +	$iasl -p $tmpamldir/kernel/firmware/acpi/$table "$ACPI_DIR/$table" > /dev/null 2>&1
> +
> +	echo "ACPI: Compiled ASL from $(realpath --relative-to=$PWD $ACPI_DIR/$table)"
> +done
> +
> +# Exit if no tables were compiled
> +[ -n "$(find $tmpamldir -type f)" ] || {
> +	echo "ACPI: No tables were compiled"
> +	exit 0
> +}
> +
> +# Attach compiled tables to initrd
> +(
> +	cd $tmpamldir
> +	find kernel | cpio -H newc -o > $updated_initrd 2>/dev/null
> +	cat $initrd >> $updated_initrd
> +	ln -sf "$updated_initrd_name" "$BINARIES_DIR/initrd"
> +)
> +
> +echo "ACPI: Created initrd with updated ACPI tables in $(realpath --relative-to=$PWD $updated_initrd)"

And move all of this logic into Buildroot make code. I'm not sure yet
exactly where it fits. Maybe as an option of the host-acpica package ?
As an option in the "System configuration" menu ? Or, maybe better,
since those updated ACPI tables are consumed by the kernel, as a kernel
option ?

But clearly, something like that shouldn't be done in a post-image or
post-build script.

Best regards,

Thomas
Arnout Vandecappelle Aug. 26, 2016, 6:13 a.m. UTC | #2
On 25-08-16 16:04, Andy Shevchenko wrote:
> Add script which takes ASL files as input, compiles them to AML bytecode,
> and prepends the whole thing to the initrd archive. They are placed in
> kernel/firmware/acpi directory where the kernel is able to find and use
> them.

 Why is this a post-image script, and not just a post-build script that copies
everything in the right place and lets the cpio rootfs take care of generating
the cpio? AFAIK there is no particular requirement for this stuff to be at the
beginning of the cpio image, is there?

 Note: I don't agree with Thomas that there should be buildroot config for doing
this. It's simple enough to do in a post-build script, which is more flexible.

[snip]
> +# Pick iASL.
> +# First try from buildroot and if not there then try from the host.
> +[ -x "$HOST_DIR/usr/bin/iasl" ] && iasl="$HOST_DIR/usr/bin/iasl" || iasl=$(which iasl)

 You can skip the HOST_DIR part, because HOST_DIR/usr/bin is at the beginning of
PATH so that one will be picked up.

> +
> +[ -x "$iasl" ] || {
> +	echo "You need to to have iASL compiler available. You can either enable"
> +	echo "BR2_PACKAGE_HOST_ACPICA or install it locally for your host."
> +	echo "Typically the package is called acpica-tools in major distros".
> +	exit 1
> +}
> +
> +# The name of the folder is the name of a board
> +board_name="${BOARD_DIR##*/}"
> +[ "$board_name" = "common" ] && {
> +	echo "Adding ACPI tables is always specific to a board!"
> +	echo "You are not supposed to use common as board here!"
> +	exit 1
> +}
> +
> +# Always prefix with the board name to avoid mistakes if the initrd is used
> +# with another board.
> +updated_initrd_name="${board_name}-acpi-rootfs.cpio"
> +updated_initrd="$BINARIES_DIR/$updated_initrd_name"
> +initrd="$(readlink -enq "$BINARIES_DIR/initrd")"
> +tmpamldir="$BINARIES_DIR/acpi-tables"

 Better use BUILD_DIR for temporary stuff. Also, since you seem to want to
support several boards in a single output tree, append board_name to the
directory name.


 Regards,
 Arnout

> +
> +# Make sure existing tables get cleared
> +rm -fr $tmpamldir
> +mkdir -p $tmpamldir/kernel/firmware/acpi
> +
> +for table in $ACPI_TABLES; do
> +	[ -f "$ACPI_DIR/$table" ] || continue
> +
> +	$iasl -p $tmpamldir/kernel/firmware/acpi/$table "$ACPI_DIR/$table" > /dev/null 2>&1
> +
> +	echo "ACPI: Compiled ASL from $(realpath --relative-to=$PWD $ACPI_DIR/$table)"
> +done
> +
> +# Exit if no tables were compiled
> +[ -n "$(find $tmpamldir -type f)" ] || {
> +	echo "ACPI: No tables were compiled"
> +	exit 0
> +}
> +
> +# Attach compiled tables to initrd
> +(
> +	cd $tmpamldir
> +	find kernel | cpio -H newc -o > $updated_initrd 2>/dev/null
> +	cat $initrd >> $updated_initrd
> +	ln -sf "$updated_initrd_name" "$BINARIES_DIR/initrd"
> +)
> +
> +echo "ACPI: Created initrd with updated ACPI tables in $(realpath --relative-to=$PWD $updated_initrd)"
> diff --git a/configs/intel_defconfig b/configs/intel_defconfig
> index 8aff9e1..24167fc 100644
> --- a/configs/intel_defconfig
> +++ b/configs/intel_defconfig
> @@ -17,6 +17,9 @@ BR2_ROOTFS_POST_BUILD_SCRIPT="board/intel/common/post-build.sh"
>  BR2_ROOTFS_POST_IMAGE_SCRIPT="board/intel/common/post-image.sh"
>  BR2_ROOTFS_POST_SCRIPT_ARGS=""
>  
> +# Host tools
> +BR2_PACKAGE_HOST_ACPICA=y
> +
>  # Busybox utilities (target)
>  BR2_PACKAGE_BUSYBOX_WATCHDOG=y
>  
>
Thomas Petazzoni Aug. 26, 2016, 8:39 a.m. UTC | #3
Hello,

On Fri, 26 Aug 2016 08:13:54 +0200, Arnout Vandecappelle wrote:

>  Note: I don't agree with Thomas that there should be buildroot config for doing
> this. It's simple enough to do in a post-build script, which is more flexible.

Depends on what gets done. And just like our linux.mk package allows to
build DTBs, it could allow building ACPI table, which is something
several x86 platforms might need.

What I *really* dislike in the proposal is the additional magic
environment variables, and there's specifically one to list the ACPI
tables to build.

Best regards,

Thomas
Thomas Petazzoni Aug. 26, 2016, 9:30 a.m. UTC | #4
Hello,

On Fri, 26 Aug 2016 12:04:54 +0300, Mika Westerberg wrote:

> > On 25-08-16 16:04, Andy Shevchenko wrote:  
> > > Add script which takes ASL files as input, compiles them to AML bytecode,
> > > and prepends the whole thing to the initrd archive. They are placed in
> > > kernel/firmware/acpi directory where the kernel is able to find and use
> > > them.  
> > 
> >  Why is this a post-image script, and not just a post-build script that copies
> > everything in the right place and lets the cpio rootfs take care of generating
> > the cpio? AFAIK there is no particular requirement for this stuff to be at the
> > beginning of the cpio image, is there?  
> 
> Actually there is - the kernel looks only from the first uncompressed
> cpio archive for these additional AML files.

Still not clear: Arnout doesn't suggest to generate multiple cpio
archives, but rather to simply have the AML files within the cpio
archive in the first place.

The Buildroot process looks like this:

 1. Build all packages
 2. Run post-build scripts
 3. Create filesystem images (including cpio one)
 4. Run post-image scripts

Right now, if I understand correctly, in step (4), you're generating an
additional initrd with just the AML files. Is this correct?

What about instead having things done in step (2): install the AML
files at the appropriate places in $(TARGET_DIR) so that they
automatically end up in the rootfs.cpio generated by Buildroot?

In this case, there's a single initrd, which contains both the root
filesystem itself and the AML files.

Best regards,

Thomas
Thomas Petazzoni Aug. 26, 2016, 1:28 p.m. UTC | #5
Hello,

On Fri, 26 Aug 2016 12:39:01 +0300, Mika Westerberg wrote:

> > What about instead having things done in step (2): install the AML
> > files at the appropriate places in $(TARGET_DIR) so that they
> > automatically end up in the rootfs.cpio generated by Buildroot?  
> 
> That would work but it them means that you cannot compress the resulting
> cpio archive. The kernel loader only looks for the first uncompressed
> one.

Ah, *that* is a good reason for having a separate initrd. In fact, I
was not even aware we could pass multiple initrd and that they were
merged together. That's good to know.

Back to your problem, then I guess it makes a lot of sense to have a
separate initrd, so that the biggest part of the initrd (the root
filesystem itself) can remain compressed.

I'm still on the opinion that a package should do all of this: download
the .aml files from some upstream project, compile them with acpica and
generate an uncompressed initrd image. Possibly this package can have
options such as a platform name to only build/install a subset of
the .aml files (and by default it builds all of them). Something along
the lines of (completely untested) :

config BR2_PACKAGE_INTEL_ACPI_TABLE_ADDONS
	bool "intel-acpi-table-addons"
	help
	  ....

	  http://....

if BR2_PACKAGE_INTEL_ACPI_TABLE_ADDONS_PLATFORMS
	string "platform list"
	help
	  Space-separated list of platforms for which the additional
	  ACPI tables should be built and installed. If left empty, all
	  ACPI tables will be built and installed.

endif

in the .mk file:

INTEL_ACPI_TABLE_ADDONS_VERSION = ...
INTEL_ACPI_TABLE_ADDONS_SITE = ...
INTEL_ACPI_TABLE_ADDONS_INSTALL_TARGET = NO
INTEL_ACPI_TABLE_ADDONS_INSTALL_IMAGES = NO
INTEL_ACPI_TABLE_ADDONS_DEPENDENCIES = host-acpica

INTEL_ACPI_TABLE_ADDONS_PLATFORMS = $(call qstrip,$(BR2_PACKAGE_INTEL_ACPI_TABLE_ADDONS_PLATFORMS))
ifeq ($(INTEL_ACPI_TABLE_ADDONS_PLATFORMS),)
INTEL_ACPI_TABLE_ADDONS_PLATFORMS = list of all platforms
endif

define INTEL_ACPI_TABLE_ADDONS_BUILD_CMDS
	$(foreach plat,$(INTEL_ACPI_TABLE_ADDONS_PLATFORMS),\
		$(HOST_DIR)/usr/bin/iasl -o $(@D)/... ....)
	... generate initrd in $(@D)
endef

define INTEL_ACPI_TABLE_ADDONS_INSTALL_IMAGE_CMDS
	... copy initrd from $(@D) to $(BINARIES_DIR) ...
endef

Best regards,

Thomas
Arnout Vandecappelle Aug. 26, 2016, 4:30 p.m. UTC | #6
On 26-08-16 11:39, Mika Westerberg wrote:
> On Fri, Aug 26, 2016 at 11:30:22AM +0200, Thomas Petazzoni wrote:
[snip]
>> Still not clear: Arnout doesn't suggest to generate multiple cpio
>> archives, but rather to simply have the AML files within the cpio
>> archive in the first place.
>>
>> The Buildroot process looks like this:
>>
>>  1. Build all packages
>>  2. Run post-build scripts
>>  3. Create filesystem images (including cpio one)
>>  4. Run post-image scripts
>>
>> Right now, if I understand correctly, in step (4), you're generating an
>> additional initrd with just the AML files. Is this correct?
> 
> Yes, that's correct.
> 
>> What about instead having things done in step (2): install the AML
>> files at the appropriate places in $(TARGET_DIR) so that they
>> automatically end up in the rootfs.cpio generated by Buildroot?
> 
> That would work but it them means that you cannot compress the resulting
> cpio archive. The kernel loader only looks for the first uncompressed
> one.

 That is rather stupid of the kernel :-) I guess it's because this acpi stuff is
needed in early boot while normally the initrd is only unpacked at the end... I
didn't even know that the kernel supported having multiple cpio archives in the
initrd, and even with different compression!

 Is it still possible to use an ext3 as a rootfs rather than an initrd? I.e.,
use a cpio archive with just the acpi stuff but have the real rootfs (including
/sbin/init) on SD card. We generally have a writeable and persistent rootfs in
the defconfigs because it's more convenient for experimenting.

 If this possibility exists, then I think it would make sense to add a package
(in the bootloader menu maybe?) that generates this cpio archive, like Thomas
suggested. Appending the two archives, however, is still something for a
post-image script I think.


 Regards,
 Arnout
Arnout Vandecappelle Aug. 29, 2016, 7:45 a.m. UTC | #7
On 29-08-16 08:55, Mika Westerberg wrote:
> On Fri, Aug 26, 2016 at 06:30:47PM +0200, Arnout Vandecappelle wrote:
>>
[snip]
>>  Is it still possible to use an ext3 as a rootfs rather than an initrd? I.e.,
>> use a cpio archive with just the acpi stuff but have the real rootfs (including
>> /sbin/init) on SD card. We generally have a writeable and persistent rootfs in
>> the defconfigs because it's more convenient for experimenting.
> 
> Sure we can use ext3 or whatever. Only thing that requires initrd is the
> AML stuff and we can generate that separately. That said the system we
> use here for kernel development only uses initrd (because that does not
> require any kind of disk to be present in the system under development).

 Well, you'll need _some_ kind of storage for the boot loader, no? Unless you
use PXE, but in that case you'll probably want to use NFS-root.

 PXE boot is however a bit more complicated to set up (you have to run a DHCP
server, probably on a private network, which means a second interface on your PC
or setting up VLAN in your switch), so we prefer to stick with disk-based (i.e.,
SD card) boot. Cfr. for instance the existing Minnowboard configs.

 So I would say: create the cpio archive from some package (possibly the package
containing the actual definitions, like Thomas suggested), and create
board-specific defconfigs that build SD card images.

 Regards,
 Arnout

> 
>>  If this possibility exists, then I think it would make sense to add a package
>> (in the bootloader menu maybe?) that generates this cpio archive, like Thomas
>> suggested. Appending the two archives, however, is still something for a
>> post-image script I think.
> 
> OK.
>
Arnout Vandecappelle Aug. 29, 2016, 9:08 a.m. UTC | #8
On 29-08-16 09:58, Mika Westerberg wrote:
> On Mon, Aug 29, 2016 at 09:45:27AM +0200, Arnout Vandecappelle wrote:
>>
>>
>> On 29-08-16 08:55, Mika Westerberg wrote:
>>> On Fri, Aug 26, 2016 at 06:30:47PM +0200, Arnout Vandecappelle wrote:
>>>>
>> [snip]
>>>>  Is it still possible to use an ext3 as a rootfs rather than an initrd? I.e.,
>>>> use a cpio archive with just the acpi stuff but have the real rootfs (including
>>>> /sbin/init) on SD card. We generally have a writeable and persistent rootfs in
>>>> the defconfigs because it's more convenient for experimenting.
>>>
>>> Sure we can use ext3 or whatever. Only thing that requires initrd is the
>>> AML stuff and we can generate that separately. That said the system we
>>> use here for kernel development only uses initrd (because that does not
>>> require any kind of disk to be present in the system under development).
>>
>>  Well, you'll need _some_ kind of storage for the boot loader, no? Unless you
>> use PXE, but in that case you'll probably want to use NFS-root.
> 
> Right, we boot the system off USB stick which holds kernel+initrd and we
> use that initrd as our rootfs (which is suitable for most cases). That
> thing then fetches the actual kernel+initrd over tftp and kexecs them.

 A very useful setup - I may use that approach in my own future development as
well. But not suitable for a buildroot defconfig :-).

 It also explains why you had KEXEC=y in your defconfig.

 Regards,
 Arnout

> 
>>  PXE boot is however a bit more complicated to set up (you have to run a DHCP
>> server, probably on a private network, which means a second interface on your PC
>> or setting up VLAN in your switch), so we prefer to stick with disk-based (i.e.,
>> SD card) boot. Cfr. for instance the existing Minnowboard configs.
> 
> Yes I know and PXE does not work on most development systems anyway.
> That's why we use the above setup :)
>
diff mbox

Patch

diff --git a/board/intel/common/README.rst b/board/intel/common/README.rst
index e427067..f7f677e 100644
--- a/board/intel/common/README.rst
+++ b/board/intel/common/README.rst
@@ -52,6 +52,9 @@  like::
 
 in order to take advantage of these.
 
+BOARD_INTEL_ACPI_TABLES
+	list of table names to built into the ``initrd``.
+
 BOARD_INTEL_CUSTOM_CMDLINE
 	provides a custom appendix to the command line.
 
@@ -68,6 +71,20 @@  By default ``ttyS0`` is used as a default cosole for both kernel and userspace.
 The **BR2_TARGET_GENERIC_GETTY_PORT** variable could be used to alterate this
 setting.
 
+Adding custom ACPI SSDT tables
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can add additional ACPI tables to the ``initrd`` (think of device tree
+overlays) if you need to have some special devices for example. The ASL files
+should be stored in board specific directories as they vary from one board to
+another. Below we add SPI test device for Intel `Joule`_ board::
+
+	% make KERNEL_SRC=~/linux BR2_TARGET_GENERIC_GETTY_PORT=ttyS2		\
+				  BOARD_INTEL_DIR=board/intel/joule		\
+				  BOARD_INTEL_ACPI_TABLES=spidev.asl
+
+The resulting image is called ``output/images/joule-acpi-rootfs.cpio``.
+
 Supported boards
 ~~~~~~~~~~~~~~~~
 
@@ -85,7 +102,7 @@  Examples
 
 	% make KERNEL_SRC=~/linux BR2_TARGET_GENERIC_GETTY_PORT=ttyS1
 
-- Joule (Broxton), Edison (Merrifield)::
+- _`Joule` (Broxton), Edison (Merrifield)::
 
 	% make KERNEL_SRC=~/linux BR2_TARGET_GENERIC_GETTY_PORT=ttyS2
 
diff --git a/board/intel/common/post-image.d/80-acpi-tables b/board/intel/common/post-image.d/80-acpi-tables
new file mode 100755
index 0000000..c9495d8
--- /dev/null
+++ b/board/intel/common/post-image.d/80-acpi-tables
@@ -0,0 +1,86 @@ 
+#!/bin/sh -e
+
+#
+# Copyright (c) 2016 Intel Corp.
+#
+
+#
+# Environment:
+#
+# BOARD_INTEL_ACPI_TABLES	- ASL files to build separated by spaces
+#
+# BOARD_INTEL_DIR		- Directory holding board specific
+# 				  configuration. Should contain directory
+# 				  called "acpi" which holds the ASL tables.
+#
+# For example following variables compile two ACPI SSDTs into updated
+# initrd image called $BINARIES_DIR/joule-acpi-rootfs.cpio.
+#
+# BOARD_INTEL_DIR="board/intel/joule"
+# BOARD_INTEL_ACPI_TABLES="at25.asl spidev.asl"
+#
+
+PROG_NAME="${0##*/}"
+PROG_DIR="${0%/*}"
+
+. $PROG_DIR/../libshell-intel
+
+ACPI_DIR="$(intel_folder_lookup "acpi")"
+ACPI_TABLES="$BOARD_INTEL_ACPI_TABLES"
+
+[ -d "$ACPI_DIR" ] || exit 0
+[ -z "$ACPI_TABLES" ] && exit 0
+
+# Pick iASL.
+# First try from buildroot and if not there then try from the host.
+[ -x "$HOST_DIR/usr/bin/iasl" ] && iasl="$HOST_DIR/usr/bin/iasl" || iasl=$(which iasl)
+
+[ -x "$iasl" ] || {
+	echo "You need to to have iASL compiler available. You can either enable"
+	echo "BR2_PACKAGE_HOST_ACPICA or install it locally for your host."
+	echo "Typically the package is called acpica-tools in major distros".
+	exit 1
+}
+
+# The name of the folder is the name of a board
+board_name="${BOARD_DIR##*/}"
+[ "$board_name" = "common" ] && {
+	echo "Adding ACPI tables is always specific to a board!"
+	echo "You are not supposed to use common as board here!"
+	exit 1
+}
+
+# Always prefix with the board name to avoid mistakes if the initrd is used
+# with another board.
+updated_initrd_name="${board_name}-acpi-rootfs.cpio"
+updated_initrd="$BINARIES_DIR/$updated_initrd_name"
+initrd="$(readlink -enq "$BINARIES_DIR/initrd")"
+tmpamldir="$BINARIES_DIR/acpi-tables"
+
+# Make sure existing tables get cleared
+rm -fr $tmpamldir
+mkdir -p $tmpamldir/kernel/firmware/acpi
+
+for table in $ACPI_TABLES; do
+	[ -f "$ACPI_DIR/$table" ] || continue
+
+	$iasl -p $tmpamldir/kernel/firmware/acpi/$table "$ACPI_DIR/$table" > /dev/null 2>&1
+
+	echo "ACPI: Compiled ASL from $(realpath --relative-to=$PWD $ACPI_DIR/$table)"
+done
+
+# Exit if no tables were compiled
+[ -n "$(find $tmpamldir -type f)" ] || {
+	echo "ACPI: No tables were compiled"
+	exit 0
+}
+
+# Attach compiled tables to initrd
+(
+	cd $tmpamldir
+	find kernel | cpio -H newc -o > $updated_initrd 2>/dev/null
+	cat $initrd >> $updated_initrd
+	ln -sf "$updated_initrd_name" "$BINARIES_DIR/initrd"
+)
+
+echo "ACPI: Created initrd with updated ACPI tables in $(realpath --relative-to=$PWD $updated_initrd)"
diff --git a/configs/intel_defconfig b/configs/intel_defconfig
index 8aff9e1..24167fc 100644
--- a/configs/intel_defconfig
+++ b/configs/intel_defconfig
@@ -17,6 +17,9 @@  BR2_ROOTFS_POST_BUILD_SCRIPT="board/intel/common/post-build.sh"
 BR2_ROOTFS_POST_IMAGE_SCRIPT="board/intel/common/post-image.sh"
 BR2_ROOTFS_POST_SCRIPT_ARGS=""
 
+# Host tools
+BR2_PACKAGE_HOST_ACPICA=y
+
 # Busybox utilities (target)
 BR2_PACKAGE_BUSYBOX_WATCHDOG=y