mirror of
git://git.yoctoproject.org/meta-intel.git
synced 2025-07-05 05:04:45 +02:00
rmc: remove
It's not being maintained anymore and the scripts have not been kept in sync with upstream for quite some time. Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
This commit is contained in:
parent
7c469177e8
commit
c12c166592
4
README
4
README
|
@ -239,10 +239,6 @@ Other software
|
|||
the Intel power clamp driver.
|
||||
(https://01.org/linux-thermal-daemon/documentation/introduction-thermal-daemon)
|
||||
|
||||
* RMC - Runtime Machine Configuration, which allows the bootload to determine
|
||||
board and CPU information in order to set specific kernel command line
|
||||
information at startup.
|
||||
|
||||
The intel-common kernel package architecture
|
||||
--------------------------------------------
|
||||
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
# rmc-boot bbclass
|
||||
# Deploy central RMC database file to ESP
|
||||
|
||||
IMAGE_INSTALL_append = " rmc"
|
||||
RMC_BOOTLOADER ?= "systemd-boot"
|
||||
|
||||
inherit ${RMC_BOOTLOADER}
|
||||
|
||||
do_bootimg[depends] += "${MLPREFIX}rmc-db:do_deploy"
|
||||
|
||||
efi_populate_append() {
|
||||
if [ -f ${DEPLOY_DIR_IMAGE}/rmc.db ]; then
|
||||
install -m 0400 ${DEPLOY_DIR_IMAGE}/rmc.db ${DEST}/rmc.db
|
||||
else
|
||||
rm -f ${DEST}/rmc.db
|
||||
fi
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
# RMC database bbclass
|
||||
# provide functions to generate RMC database file on build host (native)
|
||||
|
||||
DEPENDS += "rmc-native"
|
||||
|
||||
# rmc_generate_db()
|
||||
# $1: a list of directories. Each directory holds directories for a group of
|
||||
# boards.
|
||||
# $2: path_name of rmc generates database file and records
|
||||
#
|
||||
# WARNING: content of directory of database file will be removed.
|
||||
#
|
||||
# Each board directory shall contain a fingerprint file (*.fp) at least, with
|
||||
# optional file blob(s) associated to the type of board. If a board directory
|
||||
# has no file blob, no record is created for that board.
|
||||
#
|
||||
# An example of two directories each of which contains two boards for RMC:
|
||||
# (All file and directory names are for illustration purpose.)
|
||||
#
|
||||
# dir_1/
|
||||
# board_1/
|
||||
# board_1_fingerprint.fp
|
||||
# file_1.blob
|
||||
# board_2/
|
||||
# board_2.fp
|
||||
# dir_2/
|
||||
# board_3/
|
||||
# b3.fp
|
||||
# file_1.blob
|
||||
# file_2.conf
|
||||
# board_4/
|
||||
# board_foo.fp
|
||||
# mylib.config
|
||||
#
|
||||
# To generate a RMC database "rmc.db" with data of all (actually 3) of boards in
|
||||
# a directory "deploy_dir":
|
||||
#
|
||||
# rmc_generate_db "dir_1 dir_2" "deploy_dir/rmc.db"
|
||||
#
|
||||
# The board_2 will be skipped. No record or any data for it is packed in
|
||||
# generated database because it only contains a fingerprint file.
|
||||
#
|
||||
|
||||
rmc_generate_db () {
|
||||
RMC_BOARD_DIRS=$1
|
||||
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo "rmc_generate_db(): Wrong number of arguments: $#"
|
||||
return 1
|
||||
fi
|
||||
|
||||
RMC_DB_DIR=$(dirname "$2")
|
||||
RMC_RECORDS=""
|
||||
|
||||
rm -rf ${RMC_DB_DIR}
|
||||
mkdir -p ${RMC_DB_DIR}
|
||||
|
||||
# generate rmc database
|
||||
for topdir in ${RMC_BOARD_DIRS}; do
|
||||
# For all board dirs in a topdir:
|
||||
CUR_BOARD_DIRS=$(find ${topdir}/* -type d)
|
||||
for board_dir in ${CUR_BOARD_DIRS}; do
|
||||
CUR_FINGERPRINT=$(find ${board_dir}/ -name "*.fp")
|
||||
|
||||
# disallow a board directory without any fingerprint file in it.
|
||||
if [ -z "${CUR_FINGERPRINT}" ]; then
|
||||
echo "Cannot find RMC fingerprint file in ${board_dir}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
CUR_FILES=$(find ${board_dir}/ -type f |grep -v '\.fp$' || true)
|
||||
|
||||
# allow a directory only with fingerprint file. Developer may
|
||||
# check in fingerprint for future use.
|
||||
if [ -z "${CUR_FILES}" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
for fp in ${CUR_FINGERPRINT}; do
|
||||
fullname=$(basename ${fp})
|
||||
CUR_TAG="${fullname%.*}"
|
||||
CUR_RECORD=${RMC_DB_DIR}/${CUR_TAG}.rec
|
||||
rmc -R -f ${fp} -b ${CUR_FILES} -o ${CUR_RECORD}
|
||||
RMC_RECORDS="${RMC_RECORDS} ${CUR_RECORD}"
|
||||
done
|
||||
done
|
||||
done
|
||||
|
||||
if [ ! -z "${RMC_RECORDS}" ]; then
|
||||
rmc -D ${RMC_RECORDS} -o "$2"
|
||||
fi
|
||||
}
|
|
@ -14,8 +14,6 @@ RECIPE_MAINTAINER_pn-linux-intel = "Anuj Mittal <anuj.mittal@intel.com>"
|
|||
RECIPE_MAINTAINER_pn-linux-intel-rt = "Anuj Mittal <anuj.mittal@intel.com>"
|
||||
RECIPE_MAINTAINER_pn-lms7 = "Anuj Mittal <anuj.mittal@intel.com>"
|
||||
RECIPE_MAINTAINER_pn-lms8 = "Anuj Mittal <anuj.mittal@intel.com>"
|
||||
RECIPE_MAINTAINER_pn-rmc = "Anuj Mittal <anuj.mittal@intel.com>"
|
||||
RECIPE_MAINTAINER_pn-rmc-db = "Anuj Mittal <anuj.mittal@intel.com>"
|
||||
RECIPE_MAINTAINER_pn-thermald = "Anuj Mittal <anuj.mittal@intel.com>"
|
||||
RECIPE_MAINTAINER_pn-va-intel = "Anuj Mittal <anuj.mittal@intel.com>"
|
||||
RECIPE_MAINTAINER_pn-xf86-video-ast = "Anuj Mittal <anuj.mittal@intel.com>"
|
||||
|
|
|
@ -34,5 +34,5 @@ SERIAL_CONSOLES = "115200;ttyS0 115200;ttyS1 115200;ttyPCH0"
|
|||
APPEND += "rootwait console=ttyS0,115200 console=ttyPCH0,115200 console=tty0"
|
||||
|
||||
IMAGE_FSTYPES += "wic"
|
||||
WKS_FILE ?= "${@bb.utils.contains_any("EFI_PROVIDER", "systemd-boot rmc-boot", "systemd-bootdisk-microcode.wks", "grub-bootdisk-microcode.wks", d)}"
|
||||
WKS_FILE ?= "${@bb.utils.contains_any("EFI_PROVIDER", "systemd-boot", "systemd-bootdisk-microcode.wks", "grub-bootdisk-microcode.wks", d)}"
|
||||
WKS_FILE_DEPENDS_append = " intel-microcode"
|
||||
|
|
|
@ -41,5 +41,5 @@ SERIAL_CONSOLES = "115200;ttyS0 115200;ttyS1 115200;ttyS2"
|
|||
APPEND += "rootwait console=ttyS0,115200 console=tty0"
|
||||
|
||||
IMAGE_FSTYPES += "wic"
|
||||
WKS_FILE ?= "${@bb.utils.contains_any("EFI_PROVIDER", "systemd-boot rmc-boot", "systemd-bootdisk-microcode.wks", "grub-bootdisk-microcode.wks", d)}"
|
||||
WKS_FILE ?= "${@bb.utils.contains_any("EFI_PROVIDER", "systemd-boot", "systemd-bootdisk-microcode.wks", "grub-bootdisk-microcode.wks", d)}"
|
||||
WKS_FILE_DEPENDS_append = " intel-microcode"
|
||||
|
|
|
@ -1,373 +0,0 @@
|
|||
Runtime Machine Configuration (RMC)
|
||||
--------------------------------------------------------------------------------
|
||||
Table of Contents
|
||||
|
||||
Introduction
|
||||
Usage
|
||||
Enable RMC Feature
|
||||
Examples
|
||||
Troubleshooting
|
||||
When you (don't) need RMC feature
|
||||
|
||||
|
||||
Introduction:
|
||||
--------------------------------------------------------------------------------
|
||||
RMC Project - a light-weight project provide developers a mechanism to keep
|
||||
their software implementation board-type agnostic, yet still able to customize
|
||||
software behavior according to the type of a running board at runtime. Recipes
|
||||
and bbclasses are available for other components to reuse to construct their own
|
||||
RMC database.
|
||||
|
||||
RMC Feature - An end-to-end solution based on RMC project to have a generic
|
||||
image capable to apply board-type-specific quirks and configurations for a board
|
||||
at runtime. It consists of a modified bootloader (systemd-boot), an updated EFI
|
||||
installer, recipes, bbclass and RMC project.
|
||||
|
||||
RMC feature supports special customizations cannot be covered by conventional
|
||||
auto-detection features based on probing a hardware module because they happen
|
||||
at a board or a product level. For example:
|
||||
- tty console for kernel log output in kernel cmdline
|
||||
- default audio route configuration
|
||||
- network configuration
|
||||
- UI layout
|
||||
- requirement to software driven by a mechanical design
|
||||
- or static configuration bits for a physical bus that doesn't support to
|
||||
identify devices or their presence at runtime
|
||||
|
||||
An image with the feature has ability to configure supported boards with data
|
||||
associated only to a type of board to get full functionality of the target at
|
||||
runtime, yet still with a single image.
|
||||
|
||||
Effect after installation is identical to what a conventional image specially
|
||||
customized for a type of board (depending on the way to deploy image).
|
||||
|
||||
Main functions of RMC Feature:
|
||||
|
||||
Show board-specific boot entries in boot menu and boot system with configuration
|
||||
(boot title, boot options, etc) in a selected boot entry.
|
||||
|
||||
Support a "global" kernel boot command line fragment which is effective for all
|
||||
boot entries.
|
||||
|
||||
Deploy file blobs and create directories specific to the type of running board.
|
||||
|
||||
Beside from this document, you can also find several built-in examples in
|
||||
common/recipes-bsp/rmc/boards/. Refer to "Examples" section.
|
||||
|
||||
You can also add new board types in your layer via a simple variable.
|
||||
|
||||
|
||||
|
||||
Usage
|
||||
--------------------------------------------------------------------------------
|
||||
Developers are suggested to organize all board-specific files in their own layer
|
||||
following this example, so that RMC recipes can pick up them correctly in build.
|
||||
|
||||
- my_top_dir/ Top directory of your board (Note 0)
|
||||
|- rmc-db.bbappend bbappend file to rmc-db recipe at a lower level
|
||||
|- rmc/
|
||||
|- target_board_1/ subdirectory of a board.
|
||||
| |- board1.fp fingerprint file must be provided (NOTE 1)
|
||||
| |- BOOTENTRY.CONFIG optional config file for boot entries. (NOTE 2)
|
||||
| |- INSTALLER.CONFIG optional config file for installer. (NOTE 3)
|
||||
| |- POSTINSTALL.sh optional script hook for installer (NOTE 4)
|
||||
| |- board_file_1 A file blob specific to the type of board
|
||||
| |- board_file_2 An another file specific to the type of board
|
||||
| |- ...more files
|
||||
|- target_board_2/ subdirectory of another board.
|
||||
|- board_2_v2.fp fingerprint file for board 2.
|
||||
|- BOOTENTRY.CONFIG
|
||||
|- INSTALLER.CONFIG
|
||||
|- board_file_1
|
||||
|- ...more files
|
||||
|
||||
Note 0:
|
||||
Developers are expected to use variable RMC_BOARD_DATA_DIRS to specify data of
|
||||
boards packed into RMC database file generated in a build. The default value of
|
||||
the variable in meta-intel specifies a group of boards. They work as examples
|
||||
and necessary quirks for these boards to function properly. Developers can
|
||||
override, append to the default boards with data of their own boards in the
|
||||
database file, or even disable the generation of the database file.
|
||||
|
||||
For example, in your local.conf file:
|
||||
|
||||
This line adds your boards along with the default boards into RMC database file,
|
||||
assuming you have a directory named "rmc" which has a subdirectory for each
|
||||
board:
|
||||
|
||||
RMC_BOARD_DATA_DIRS_append = " /path_of/rmc"
|
||||
|
||||
This line directs RMC to pack data of your boards only, without data of the
|
||||
default boards in meta-intel:
|
||||
|
||||
RMC_BOARD_DATA_DIRS = "/path_of/rmc"
|
||||
|
||||
And this line disables database generation:
|
||||
|
||||
RMC_BOARD_DATA_DIRS = ""
|
||||
|
||||
Please also refer to the "Example 1" in this document.
|
||||
|
||||
Subdirectory is not supported in a board's directory.
|
||||
|
||||
Note 1:
|
||||
Fingerprint files must be provided and with ".fp" at the end of their names.
|
||||
Fingerprint can be obtained by running RMC tool on your board. An easy way is to
|
||||
live-boot USB stick flashed with any image enabled this feature on your board,
|
||||
then run this command:
|
||||
|
||||
# rmc -F -o my_board.fp
|
||||
|
||||
Or you will need to build RMC tool for the architecture of your board, 32 or
|
||||
64 bit x86, from RMC project.
|
||||
|
||||
You can run RMC tool without any argument to get usage and examples.
|
||||
|
||||
DO NOT NAME ANY FILE ENDING WITH '.fp' IF IT IS NOT A RMC FINGERPRINT FILE.
|
||||
|
||||
If you do need a .fp file deployed onto target, please rename it in source and
|
||||
specify the real name of file on target in INSTALLER.CONFIG.
|
||||
|
||||
Note 2:
|
||||
At runtime, RMC bootloader tries to fetch this file specific to the board at run
|
||||
time, then tries to fetch each boot entry file specified in BOOTENTRY.CONFIG and
|
||||
show them in boot menu options. The format of this file is very simple. Each
|
||||
line is the name of a boot entry file:
|
||||
|
||||
boot.conf
|
||||
Install.conf
|
||||
myrmcboot.conf
|
||||
|
||||
Name of a boot entry file is defined by developer so it can be anything. But the
|
||||
name of config file is what RMC bootloader looks up in RMC database, so it must
|
||||
be named BOOTENTRY.CONFIG.
|
||||
|
||||
Bootloader skips loading entry conf files from disk once any entry is loaded
|
||||
from RMC database.
|
||||
|
||||
Note 3:
|
||||
At runtime, RMC installer tries to fetch INSTALLER.CONFIG file specific to the
|
||||
board, then tries to fetch each file specified in this config file, and then
|
||||
deploy the file onto target with its permissions, UID, GID and other attributes
|
||||
also specified in this config file if file for the board can be retrieved from
|
||||
RMC database. The format of this file is (# is for comment line)
|
||||
|
||||
# name:uid:gid:mode:path_on_target
|
||||
# to create a directory, add a “/” at the end of path_on_target:
|
||||
audio_policy:0:0:600:/etc/audio/
|
||||
audio_def_policy:0:0:600:/etc/audio/audio_policy
|
||||
|
||||
The above example creates /etc/audio directory first, then fetch a file named
|
||||
“audio_def_policy” from RMC database for the board, then copy it to /etc/audio/
|
||||
with a new name “audio_policy”.
|
||||
|
||||
If this config file is not provided, No data in RMC database is deployed to the
|
||||
target.
|
||||
|
||||
Some steps defined by developers could not be supported on a filesystem.
|
||||
Installer simply ignores any errors in RMC deployment stage.
|
||||
|
||||
The name of this config file is what installer looks up first, so it must be
|
||||
INSTALLER.CONFIG.
|
||||
|
||||
Note 4:
|
||||
At the end of RMC deployment during installation, RMC installer queries a script
|
||||
file POSTINSTALL.sh from RMC database file, and execute it when query is
|
||||
successful on the running board. This hook provides developers almost ultimate
|
||||
flexibility to retouch what have been deployed on the target. There are some
|
||||
steps still can override results from this hook for boot entries and KBOOTPARAM.
|
||||
|
||||
|
||||
|
||||
Enable RMC Feature
|
||||
--------------------------------------------------------------------------------
|
||||
To enable the RMC feature please add the following variables to your local.conf.
|
||||
|
||||
DISTRO_FEATURES_append = " rmc"
|
||||
EFI_PROVIDER = "rmc-boot"
|
||||
|
||||
The default EFI bootloader used with RMC is systemd-boot. To change the default
|
||||
bootloader please overwrite the RMC_BOOTLOADER variable in your local.conf
|
||||
|
||||
Note:
|
||||
Image could be still bootable if you only have either of two lines, but RMC
|
||||
feature could not be fully functional, depending on the availability of the
|
||||
database file, installer and the rmc tool.
|
||||
|
||||
Examples
|
||||
--------------------------------------------------------------------------------
|
||||
We checked in configuration data in common/recipes-bsp/rmc/boards/ for several
|
||||
boards, to help users to understand the RMC feature. These examples are also for
|
||||
validation. For any example you find not working as what this section depicts,
|
||||
it should be treated as a bug to be fixed.
|
||||
|
||||
To test this feature with examples, enable it and build an image first, then
|
||||
boot the built image on supported boards. Examples are always built in when the
|
||||
feature is enabled, except for the EXAMPLE 1.
|
||||
|
||||
EXAMPLE 1: Support a new board type:
|
||||
(1) enable the feature and do a build to get a live-boot image by adding these
|
||||
lines in conf/local.conf:
|
||||
DISTRO_FEATURES_append = " rmc"
|
||||
EFI_PROVIDER = "rmc-boot"
|
||||
|
||||
(2) flash the image to a USB stick and boot it on your board
|
||||
|
||||
(3) in super user mode, run "rmc -F -o my_board.fp"
|
||||
|
||||
(4) create directories in your host "mkdir -p my_top_dir/my_rmc/my_board"
|
||||
|
||||
(5) copy my_board.fp from target to my_top_dir/my_rmc/my_board/ on host
|
||||
|
||||
(6) create a file my_top_dir/my_rmc/my_board/KBOOTPARAM, put some fake
|
||||
and harmless options in a single line, say, "loglevel=7"
|
||||
|
||||
(7) create a file my_top_dir/rmc-db.bbappend, put this single line in it:
|
||||
RMC_BOARD_DATA_DIRS_append := " ${THISDIR}/my_rmc"
|
||||
From parent directory of my_top_dir, the tree should look like:
|
||||
my_top_dir/
|
||||
my_rmc/
|
||||
my_board/
|
||||
KBOOTPARAM
|
||||
my_board.fp
|
||||
rmc-db.bbappend
|
||||
Later, you can add more board directories in my_rmc directory.
|
||||
|
||||
(8) modify build configuration to add my_top_dir into build, for example, put
|
||||
this line in a bblayers.conf:
|
||||
BBFILES += "/full/path/of/my_top_dir/rmc-db.bbappend"
|
||||
|
||||
(9) build image again then boot it on your board
|
||||
|
||||
(10) Once you login to shell, new options should be effective, run this command
|
||||
"cat /proc/cmdline" to verify the result.
|
||||
|
||||
EXAMPLE 2: Board-specific boot entry
|
||||
MinnowBoard MAX and B3 version:
|
||||
common/recipes-bsp/rmc/boards/minnowmax
|
||||
common/recipes-bsp/rmc/boards/minnowmaxB3
|
||||
|
||||
We have found two identities (type of board) exist for the "same" Minnow Max
|
||||
hardware, so they have to be treated as two different types of hardware. The two
|
||||
examples show you a boot entry specific to a type of board. Titles shown in boot
|
||||
menu have different names according to the type of running board, "Minnow Max
|
||||
boot" or "Minnow Max B3 boot". in /proc/cmdline, "console=ttyS0,115200n8" shall
|
||||
be there. Kernel prints logs from 6-pin FTDI serial port on Minnow Max(s). This
|
||||
console setting is in board-specific entries, so you won't see it effective if
|
||||
you select default "boot" entry to boot the device.
|
||||
|
||||
EXAMPLE 3: Board-specific boot entry, global kernel cmdline and installer
|
||||
NUC Gen 6:
|
||||
common/recipes-bsp/rmc/boards/nucgen6
|
||||
This is a combo example with all supported configuration data for NUC Gen 6
|
||||
product. It shows two boot entries in bootloader menu when you boot image on NUC
|
||||
Gen 6 product, with "NUC Gen6" in entry titles. There shall no any "console=" in
|
||||
/proc/cmdline when you boot with either of two "NUC Gen6"entries. We designed it
|
||||
this way because there is no accessible tty port on NUC Gen 6 with housing. The
|
||||
post-install hook is also provided in this example.
|
||||
|
||||
This example also includes a global kernel cmdline fragment KBOOTPARAM. Content
|
||||
of KBOOTPARAM shall be at the end of /proc/cmdline no matter which boot entry
|
||||
you selected to boot NUC Gen6.
|
||||
|
||||
INSTALLER.CONFIG directs installer to create a directory and deploy a file in it
|
||||
when install the image on NUC Gen6.
|
||||
|
||||
Choose "NUC Gen6 install" boot entry to boot shall start installation. Once
|
||||
the device reboots after installation, we can verify the configurations.
|
||||
|
||||
The boot entry "NUC Gen6 boot" shall be shown in boot menu.
|
||||
|
||||
The content of KBOOTPARAM shall be in /proc/cmdline too.
|
||||
|
||||
A directory /etc/mylib/ is created and a file "mylib.conf" is there. The content
|
||||
of that file shall be what we put in mylib.conf in
|
||||
common/recipes-bsp/rmc/boards/nucgen6
|
||||
|
||||
POSTINSTALL.sh shows how we get rid of an error message caused by no serial
|
||||
console available on NUC Gen 6, without creating another static board
|
||||
configuration.
|
||||
|
||||
EXAMPLE 4: For validation only
|
||||
T100 (32bit):
|
||||
common/recipes-bsp/rmc/boards/T100-32bit
|
||||
This example is provided for validation on 32 bit X86 architecture. It doesn't
|
||||
provide any new function not mentioned in above examples.
|
||||
|
||||
Troubleshooting
|
||||
--------------------------------------------------------------------------------
|
||||
Issue: Cannot obtain RMC fingerprint for a board
|
||||
|
||||
RMC tool requires UEFI BIOS and SMBIOS support in firmware. It doesn't support
|
||||
other type of firmware, e.g. legacy BIOS. It also requires EFI driver enabled
|
||||
in Linux kernel.
|
||||
|
||||
Issue: Configuration for a board seems not effective at runtime.
|
||||
|
||||
Check if board is booted from the storage where the image or installation lives
|
||||
when you have multiple boot options in BIOS. On some old hardwares it is not
|
||||
that obvious as you assume. A build image can support boot from both of legacy
|
||||
and UEFI mode, but RMC only works with UEFI boot so far.
|
||||
|
||||
Make sure configuration files (BOOTENTRY.CONFIG, INSTALLER.CONFIG and,
|
||||
KBOOTPARAM ...) are properly named in the board directory.
|
||||
|
||||
Make sure configuration files have correct contents.
|
||||
|
||||
Some file attributes could not be supported by targeted file system. Installer
|
||||
cannot setup file blobs as you wish. It simply move to the next step if a step
|
||||
fails.
|
||||
|
||||
Kernel command line can be customized globally with KBOOTPARAM or just in a boot
|
||||
entry for the type of board. They have different effective scopes.
|
||||
|
||||
If no any board-specific configuration becomes effective on your board but it
|
||||
works on other boards of same product, you can run rmc tool to obtain
|
||||
fingerprint file on your board and compare it with fingerprint of a working
|
||||
board. It is possible they have different firmware versions and unluckily, some
|
||||
information for fingerprint changes between two versions. You can update BIOS
|
||||
on every board to the same BIOS version if it is feasible. Otherwise you have
|
||||
to treat them as two different type of boards. We could extend rmc design to
|
||||
allow multiple fingerprints in a board directory as a workaround.
|
||||
|
||||
Issue: RMC reports error because it cannot find fingerprint when building image.
|
||||
|
||||
Make sure you have a fingerprint file. Its name must be ended with '.fp'. You
|
||||
can put a fingerprint file in a board directory and provide data later.
|
||||
|
||||
Issue: Any problems the above troubleshooting cannot help
|
||||
|
||||
Please report it to us. Extra information like the type of your board or a dump
|
||||
file from dmidecode tool is helpful. We will investigate the problem and keep
|
||||
improving this feature.
|
||||
|
||||
|
||||
|
||||
|
||||
When you (don't) need RMC feature
|
||||
--------------------------------------------------------------------------------
|
||||
RMC feature is designed to as generic as possible, in order to support a large
|
||||
number of types of boards. And it shall be designed not to break things when it
|
||||
is disabled. These considerations help users to decide if they really need or
|
||||
enable it.
|
||||
|
||||
If you are satisfied with a dedicated build target and image for each board in
|
||||
your development cycle (source, build, validation, release, etc), you don't need
|
||||
this feature.
|
||||
|
||||
If you have a generic build for multiple type of boards and features supported
|
||||
by that build meet your needs to functionality on all of boards, you don't need
|
||||
to have this feature or you can disable it until you need to check in the first
|
||||
board's data, in order to apply a quirk or customization only for that board.
|
||||
|
||||
If you want this feature but have concerns to see more and more boards' finger-
|
||||
prints and data in a generic project, you can have another layer to hold all of
|
||||
board-specific data to split them from a generic layer at source level. Another
|
||||
suggestion is always seeking chances not to clone or copy a common configuration
|
||||
to each board's directory.
|
||||
|
||||
|
||||
|
||||
Thanks
|
||||
|
||||
Jianxun Zhang <jianxun.zhang@linux.intel.com>
|
|
@ -1 +0,0 @@
|
|||
console=ttyS0,115200
|
Binary file not shown.
|
@ -1,2 +0,0 @@
|
|||
boot.conf
|
||||
install.conf
|
|
@ -1,2 +0,0 @@
|
|||
efi_entry_dir:root:disk:770:/boot/loader/entries/
|
||||
boot.conf:root:disk:770:/boot/loader/entries/rmcboot.conf
|
|
@ -1,2 +0,0 @@
|
|||
# There is no tty device on this board.
|
||||
sed -i '/start_getty.\+ttyS.*/d' /tgt_root/etc/inittab
|
|
@ -1,4 +0,0 @@
|
|||
title NUC5i5RYB boot
|
||||
linux /vmlinuz
|
||||
initrd /initrd
|
||||
options LABEL=boot rootwait
|
|
@ -1,4 +0,0 @@
|
|||
title NUC5i5RYB install
|
||||
linux /vmlinuz
|
||||
initrd /initrd
|
||||
options LABEL=install-efi rootwait
|
Binary file not shown.
|
@ -1,2 +0,0 @@
|
|||
boot.conf
|
||||
install.conf
|
Binary file not shown.
|
@ -1,4 +0,0 @@
|
|||
title T100T(32bit) boot
|
||||
linux /vmlinuz
|
||||
initrd /initrd
|
||||
options LABEL=boot loglevel=8
|
|
@ -1,4 +0,0 @@
|
|||
title T100T(32bit) install
|
||||
linux /vmlinuz
|
||||
initrd /initrd
|
||||
options LABEL=install-efi
|
|
@ -1,2 +0,0 @@
|
|||
boot.conf
|
||||
install.conf
|
|
@ -1,3 +0,0 @@
|
|||
# Keep rmc Joule boot.conf instead of meta-intel default
|
||||
efi_entry_dir:root:disk:770:/boot/loader/entries/
|
||||
boot.conf:root:disk:770:/boot/loader/entries/boot.conf
|
|
@ -1 +0,0 @@
|
|||
video=efifb maxcpus=4 reboot=efi kmemleak=off console=tty0 console=ttyS2,115200
|
|
@ -1,2 +0,0 @@
|
|||
# Joule uses only S2 for serial, so remove S0
|
||||
sed -i '/start_getty.\+ttyS0/d' /tgt_root/etc/inittab
|
Binary file not shown.
Binary file not shown.
|
@ -1,4 +0,0 @@
|
|||
title Joule / Broxton-m
|
||||
linux /vmlinuz
|
||||
initrd /initrd
|
||||
options LABEL=boot
|
|
@ -1,4 +0,0 @@
|
|||
title Joule / Broxton-m Install
|
||||
linux /vmlinuz
|
||||
initrd /initrd
|
||||
options LABEL=install-efi rootwait
|
Binary file not shown.
|
@ -1,2 +0,0 @@
|
|||
boot.conf
|
||||
install.conf
|
|
@ -1,4 +0,0 @@
|
|||
title Minnow Max boot
|
||||
linux /vmlinuz
|
||||
initrd /initrd
|
||||
options LABEL=boot console=ttyS0,115200n8
|
|
@ -1,4 +0,0 @@
|
|||
title Minnow Max install
|
||||
linux /vmlinuz
|
||||
initrd /initrd
|
||||
options LABEL=install-efi console=ttyS0,115200n8
|
Binary file not shown.
|
@ -1,2 +0,0 @@
|
|||
boot.conf
|
||||
install.conf
|
|
@ -1,4 +0,0 @@
|
|||
title Minnow Max B3 boot
|
||||
linux /vmlinuz
|
||||
initrd /initrd
|
||||
options LABEL=boot console=ttyS0,115200n8
|
|
@ -1,4 +0,0 @@
|
|||
title Minnow Max B3 install
|
||||
linux /vmlinuz
|
||||
initrd /initrd
|
||||
options LABEL=install-efi console=ttyS0,115200n8
|
Binary file not shown.
|
@ -1,2 +0,0 @@
|
|||
boot.conf
|
||||
install.conf
|
|
@ -1,3 +0,0 @@
|
|||
# Keep rmc Mohonpeak boot.conf instead of meta-intel default
|
||||
efi_entry_dir:root:disk:770:/boot/loader/entries/
|
||||
boot.conf:root:disk:770:/boot/loader/entries/boot.conf
|
|
@ -1 +0,0 @@
|
|||
console=ttyS1,115200 console=tty1
|
|
@ -1,3 +0,0 @@
|
|||
# Mohonpeak uses only S1 for serial, so remove S0 and S2
|
||||
sed -i '/start_getty.\+ttyS0/d' /tgt_root/etc/inittab
|
||||
sed -i '/start_getty.\+ttyS2/d' /tgt_root/etc/inittab
|
|
@ -1,4 +0,0 @@
|
|||
title Mohon Peak boot
|
||||
linux /vmlinuz
|
||||
initrd /initrd
|
||||
options LABEL=boot
|
|
@ -1,4 +0,0 @@
|
|||
title Mohon Peak Install
|
||||
linux /vmlinuz
|
||||
initrd /initrd
|
||||
options LABEL=install-efi rootwait
|
Binary file not shown.
|
@ -1,2 +0,0 @@
|
|||
boot.conf
|
||||
install.conf
|
|
@ -1,6 +0,0 @@
|
|||
# This file specifies which file or dir RMC will install onto target.
|
||||
# Note the absolute path is referred from mount points in installation.
|
||||
efi_entry_dir:root:disk:770:/boot/loader/entries/
|
||||
boot.conf:root:disk:770:/boot/loader/entries/rmcboot.conf
|
||||
mylibdir:root:root:770:/tgt_root/etc/mylib/
|
||||
mylib.conf:root:root:660:/tgt_root/etc/mylib/mylib.conf
|
|
@ -1 +0,0 @@
|
|||
i915.preliminary_hw_support=1
|
|
@ -1,7 +0,0 @@
|
|||
# NUC Gen 6 specific retouch after RMC deployment
|
||||
|
||||
# The generated inittab from OE build causes error messages:
|
||||
# "auth.err getty[615]: tcgetattr: Input/output error"
|
||||
# in /var/log/messages because NUC Gen 6 doesn't have any
|
||||
# serial tty. We delete line(s) here on target.
|
||||
sed -i '/start_getty.\+ttyS.*/d' /tgt_root/etc/inittab
|
|
@ -1,4 +0,0 @@
|
|||
title NUC Gen6 boot
|
||||
linux /vmlinuz
|
||||
initrd /initrd
|
||||
options LABEL=boot
|
|
@ -1,4 +0,0 @@
|
|||
title NUC Gen6 install
|
||||
linux /vmlinuz
|
||||
initrd /initrd
|
||||
options LABEL=install-efi
|
|
@ -1,7 +0,0 @@
|
|||
# This is a demo conf file read by an imagined program or library
|
||||
# which reads this file at runtime to customize its behavior.
|
||||
# rmc will deploy it to the location specified in INSTALLER.CONFIG.
|
||||
|
||||
lib.info = "V1.0 for rmc demo"
|
||||
lib.board = "NUC gen 6"
|
||||
prog.ui.layout = "minimal"
|
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
console=ttyS0,115200
|
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
console=ttyS0,115200
|
Binary file not shown.
|
@ -1,62 +0,0 @@
|
|||
SUMMARY = "Central RMC Database"
|
||||
DESCRIPTION = "Generate a centralized RMC database for RMC feature. \
|
||||
Fingerprints and data for all boards supported are specified by variable \
|
||||
RMC_BOARD_DATA_DIRS which is a list of top directories that contains \
|
||||
subdirectories for boards. Developers can add their top directories by appending \
|
||||
them to this variable in a rmc-db.bbappend.Refer to rmc-db bbclass for more \
|
||||
information."
|
||||
|
||||
LICENSE = "MIT"
|
||||
|
||||
LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"
|
||||
|
||||
S = "${WORKDIR}"
|
||||
|
||||
inherit rmc-db
|
||||
|
||||
RMC_BOARD_DATA_DIRS ?= "${THISDIR}/boards/"
|
||||
RMC_DB_DIR = "${WORKDIR}/db"
|
||||
|
||||
FILES_${PN} = "/boot/rmc.db"
|
||||
|
||||
# Let sstate be aware of change in any added board directories
|
||||
do_generate_rmc_db[file-checksums] = "${@get_rmc_top_dirs_list(d)}"
|
||||
|
||||
# derived from get_lic_checksum_file_list(d) in base.bbclass in OE
|
||||
def get_rmc_top_dirs_list(d):
|
||||
dirlist = []
|
||||
dirs = d.getVar("RMC_BOARD_DATA_DIRS", True) or ''
|
||||
topdirs = dirs.split()
|
||||
for each in topdirs:
|
||||
dirlist.append(each + ":" + str(os.path.exists(each)))
|
||||
return " ".join(dirlist)
|
||||
|
||||
do_generate_rmc_db () {
|
||||
rmc_generate_db "${RMC_BOARD_DATA_DIRS}" "${RMC_DB_DIR}"/rmc.db
|
||||
}
|
||||
|
||||
addtask generate_rmc_db after do_compile
|
||||
|
||||
inherit deploy
|
||||
|
||||
do_deploy () {
|
||||
if [ -f ${RMC_DB_DIR}/rmc.db ]; then
|
||||
install -m 0400 ${RMC_DB_DIR}/rmc.db ${DEPLOYDIR}
|
||||
else
|
||||
rm -f ${DEPLOYDIR}/rmc.db
|
||||
echo "Warning: no RMC central database found, skip deployment."
|
||||
fi
|
||||
}
|
||||
|
||||
do_install () {
|
||||
install -d ${D}/boot
|
||||
if [ -f ${RMC_DB_DIR}/rmc.db ]; then
|
||||
install -m 0400 ${RMC_DB_DIR}/rmc.db ${D}/boot/
|
||||
else
|
||||
rm -f ${D}/rmc.db
|
||||
echo "Warning: no RMC central database found, skip installation."
|
||||
fi
|
||||
}
|
||||
do_install[depends] += "${PN}:do_generate_rmc_db"
|
||||
|
||||
addtask deploy after do_generate_rmc_db
|
|
@ -1,40 +0,0 @@
|
|||
SUMMARY = "RMC (Runtime Machine Configuration) EFI library"
|
||||
|
||||
DESCRIPTION = "The RMC EFI library adds RMC support to existing EFI bootloaders"
|
||||
|
||||
LICENSE = "MIT"
|
||||
|
||||
LIC_FILES_CHKSUM = "file://COPYING;md5=ade413c694d3aaefc9554b24a8814ee8"
|
||||
|
||||
SRC_URI = "git://git.yoctoproject.org/rmc"
|
||||
|
||||
SRCREV = "027ac76f642dcab1a9f237a00f03a3a714bd04b9"
|
||||
|
||||
S = "${WORKDIR}/git"
|
||||
|
||||
COMPATIBLE_HOST = "(x86_64.*|i.86.*)-linux*"
|
||||
|
||||
TARGET_CFLAGS +="-Wl,--hash-style=both"
|
||||
|
||||
EXTRA_OEMAKE = "RMC_INSTALL_PREFIX=${D}/${prefix} \
|
||||
RMC_INSTALL_LIB_PATH=${D}${libdir} \
|
||||
RMC_INSTALL_HEADER_PATH=${D}${includedir}/rmc"
|
||||
|
||||
SECURITY_CFLAGS_remove_class-target = "-fstack-protector-strong"
|
||||
SECURITY_CFLAGS_append_class-target = " -fno-stack-protector"
|
||||
|
||||
python () {
|
||||
ccargs = d.getVar('TUNE_CCARGS').split()
|
||||
if '-mx32' in ccargs:
|
||||
ccargs.remove('-mx32')
|
||||
ccargs.append('-m64')
|
||||
d.setVar('TUNE_CCARGS', ' '.join(ccargs))
|
||||
}
|
||||
|
||||
do_compile() {
|
||||
oe_runmake -f Makefile.efi
|
||||
}
|
||||
|
||||
do_install() {
|
||||
oe_runmake -f Makefile.efi install
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
SUMMARY = "RMC (Runtime Machine Configuration)"
|
||||
|
||||
DESCRIPTION = "RMC project provides a tool and libraries to identify types \
|
||||
of hardware boards and access any file-based data specific to the board's \
|
||||
type at runtime in a centralized way. Software (clients) can have a generic \
|
||||
logic to query board-specific data from RMC without knowing the type of board. \
|
||||
This make it possible to have a generic software work running on boards which \
|
||||
require any quirks or customizations at a board or product level. \
|
||||
"
|
||||
|
||||
LICENSE = "MIT"
|
||||
|
||||
LIC_FILES_CHKSUM = "file://COPYING;md5=ade413c694d3aaefc9554b24a8814ee8"
|
||||
|
||||
SRC_URI = "git://git.yoctoproject.org/rmc"
|
||||
|
||||
SRCREV = "027ac76f642dcab1a9f237a00f03a3a714bd04b9"
|
||||
|
||||
S = "${WORKDIR}/git"
|
||||
|
||||
COMPATIBLE_HOST = "(x86_64.*|i.86.*)-linux*"
|
||||
|
||||
TARGET_CFLAGS +="-Wl,--hash-style=both"
|
||||
|
||||
EXTRA_OEMAKE = "RMC_INSTALL_PREFIX=${D}/${prefix} \
|
||||
RMC_INSTALL_BIN_PATH=${D}${bindir} \
|
||||
RMC_INSTALL_LIB_PATH=${D}${libdir} \
|
||||
RMC_INSTALL_HEADER_PATH=${D}${includedir}/rmc"
|
||||
|
||||
SECURITY_CFLAGS_remove_class-target = "-fstack-protector-strong"
|
||||
SECURITY_CFLAGS_append_class-target = " -fno-stack-protector"
|
||||
|
||||
do_compile_class-target() {
|
||||
oe_runmake
|
||||
}
|
||||
|
||||
do_install() {
|
||||
oe_runmake install
|
||||
}
|
||||
|
||||
do_install_class-native() {
|
||||
install -d ${D}${STAGING_BINDIR_NATIVE}
|
||||
install -m 0755 ${S}/src/rmc ${D}${STAGING_BINDIR_NATIVE}
|
||||
}
|
||||
|
||||
BBCLASSEXTEND = "native"
|
|
@ -1,46 +0,0 @@
|
|||
From beb095f41d458b7d684c0cd6cac1749e2fc3f29b Mon Sep 17 00:00:00 2001
|
||||
From: California Sullivan <california.l.sullivan@intel.com>
|
||||
Date: Wed, 21 Mar 2018 13:01:26 -0700
|
||||
Subject: [PATCH 1/5] partially revert "sd-boot: stub: Obtain PE section
|
||||
offsets from RAM, not disk (#6250)"
|
||||
|
||||
Only revert the section for finding the root_dir, as RMC needs this to
|
||||
find its database file.
|
||||
|
||||
Upstream-Status: Inappropriate [upstream doesn't need the root_dir].
|
||||
|
||||
Signed-off-by: California Sullivan <california.l.sullivan@intel.com>
|
||||
---
|
||||
src/boot/efi/stub.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c
|
||||
index ff45cebd4..540ca5985 100644
|
||||
--- a/src/boot/efi/stub.c
|
||||
+++ b/src/boot/efi/stub.c
|
||||
@@ -30,6 +30,8 @@ static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE;
|
||||
|
||||
EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
EFI_LOADED_IMAGE *loaded_image;
|
||||
+ EFI_FILE *root_dir;
|
||||
+ CHAR16 *loaded_image_path;
|
||||
CHAR8 *b;
|
||||
UINTN size;
|
||||
BOOLEAN secure = FALSE;
|
||||
@@ -58,6 +60,13 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
return err;
|
||||
}
|
||||
|
||||
+ root_dir = LibOpenRoot(loaded_image->DeviceHandle);
|
||||
+ if (!root_dir) {
|
||||
+ Print(L"Unable to open root directory: %r ", err);
|
||||
+ uefi_call_wrapper(BS->Stall, 1, 3 * 1000 * 1000);
|
||||
+ return EFI_LOAD_ERROR;
|
||||
+ }
|
||||
+
|
||||
if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS) {
|
||||
if (*b > 0)
|
||||
secure = TRUE;
|
||||
--
|
||||
2.14.3
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
From af977853ab722194c4754e6693f430f50a42190f Mon Sep 17 00:00:00 2001
|
||||
From: California Sullivan <california.l.sullivan@intel.com>
|
||||
Date: Tue, 20 Mar 2018 10:08:14 -0700
|
||||
Subject: [PATCH 2/5] sd-boot: fix RMC compatibility with systemd-boot and
|
||||
meson
|
||||
|
||||
With autotools swapped out for meson a number of things need to be
|
||||
changed.
|
||||
|
||||
Upstream-Status: Pending
|
||||
|
||||
Signed-off-by: California Sullivan <california.l.sullivan@intel.com>
|
||||
---
|
||||
meson_options.txt | 2 ++
|
||||
src/boot/efi/meson.build | 4 +++-
|
||||
2 files changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/meson_options.txt b/meson_options.txt
|
||||
index 39822d6cd..d8a480401 100644
|
||||
--- a/meson_options.txt
|
||||
+++ b/meson_options.txt
|
||||
@@ -279,6 +279,8 @@ option('efi-ldsdir', type : 'string',
|
||||
description : 'path to the EFI lds directory')
|
||||
option('efi-includedir', type : 'string', value : '/usr/include/efi',
|
||||
description : 'path to the EFI header directory')
|
||||
+option('rmc-includedir', type : 'string', value : '/usr/include/rmc',
|
||||
+ description : 'path to the RMC header directory')
|
||||
option('tpm-pcrindex', type : 'string', value : '8',
|
||||
description : 'TPM PCR register number to use')
|
||||
|
||||
diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build
|
||||
index 9f9ec4911..266ff928f 100644
|
||||
--- a/src/boot/efi/meson.build
|
||||
+++ b/src/boot/efi/meson.build
|
||||
@@ -83,6 +83,7 @@ if have_gnu_efi
|
||||
efi_conf.set_quoted('EFI_MACHINE_TYPE_NAME', EFI_MACHINE_TYPE_NAME)
|
||||
efi_conf.set10('ENABLE_TPM', get_option('tpm'))
|
||||
efi_conf.set('SD_TPM_PCR', get_option('tpm-pcrindex'))
|
||||
+ efi_conf.set('RMC_EFI', 'true')
|
||||
|
||||
efi_config_h = configure_file(
|
||||
output : 'efi_config.h',
|
||||
@@ -121,6 +122,7 @@ if have_gnu_efi
|
||||
'-Wsign-compare',
|
||||
'-Wno-missing-field-initializers',
|
||||
'-isystem', efi_incdir,
|
||||
+ '-isystem', get_option('rmc-includedir'),
|
||||
'-isystem', join_paths(efi_incdir, gnu_efi_arch),
|
||||
'-include', efi_config_h]
|
||||
if efi_arch == 'x86_64'
|
||||
@@ -191,7 +193,7 @@ if have_gnu_efi
|
||||
output : tuple[0],
|
||||
command : efi_ld.split() + ['-o', '@OUTPUT@'] +
|
||||
efi_ldflags + tuple[2] +
|
||||
- ['-lefi', '-lgnuefi', libgcc_file_name])
|
||||
+ ['-lefi', '-lgnuefi', '-lrmcefi', libgcc_file_name])
|
||||
|
||||
test('no-undefined-symbols-' + tuple[0],
|
||||
no_undefined_symbols,
|
||||
--
|
||||
2.14.3
|
||||
|
|
@ -1,252 +0,0 @@
|
|||
From b780c67c780bae2f834d73017044680fabca4268 Mon Sep 17 00:00:00 2001
|
||||
From: Jianxun Zhang <jianxun.zhang@linux.intel.com>
|
||||
Date: Wed, 1 Jun 2016 16:32:22 -0700
|
||||
Subject: [PATCH 3/5] sd-boot: Load board-specific boot entries from RMC
|
||||
database
|
||||
|
||||
RMC provides a centralized database file on ESP. The DB contains
|
||||
fingerprints and any file blobs associated to physical boards.
|
||||
Callers can fetch board-specific data with fingerprint info
|
||||
collected from board at runtime if there is any record matched
|
||||
board's fingerprint.
|
||||
|
||||
To let bootloader know which file blob in RMC should be queried,
|
||||
a special config file BOOTENTRY.CONFIG is defined as:
|
||||
|
||||
boot.conf
|
||||
install.conf
|
||||
|
||||
Bootloader calls RMC APIs and other functions to perform these
|
||||
tasks before it shows boot menu to user:
|
||||
|
||||
(1) Load RMC database file from ESP
|
||||
(2) Collect fingerprint data from board
|
||||
(3) Query BOOTENTRY.CONFIG from RMC DB with fingerprint
|
||||
(4) Parse BOOTENTRY.CONFIG to know names of boot entry files
|
||||
(5) Query boot entry files one by one from RMC DB, and add
|
||||
them into sd-boot config data.
|
||||
|
||||
The final effect is that bootloader will show board-specific
|
||||
boot entries in boot menu to user. User then can choose one
|
||||
of them to boot system with the selected configuration.
|
||||
|
||||
If any of these steps fails, bootloader simply skips loading
|
||||
RMC configs or any entry file not successfully fetched from
|
||||
RMC DB. Once any entry is loaded successfully from RMC DB,
|
||||
bootloader skips loading any boot entries from ESP.
|
||||
|
||||
Upstream-Status: Pending
|
||||
|
||||
Signed-off-by: Jianxun Zhang <jianxun.zhang@linux.intel.com>
|
||||
Signed-off-by: California Sullivan <california.l.sullivan@intel.com>
|
||||
---
|
||||
src/boot/efi/boot.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 146 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
|
||||
index b9c7c8394..93cfaf193 100644
|
||||
--- a/src/boot/efi/boot.c
|
||||
+++ b/src/boot/efi/boot.c
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
+#include <rmc_api.h>
|
||||
|
||||
#include "console.h"
|
||||
#include "disk.h"
|
||||
@@ -35,6 +36,9 @@ static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-boot
|
||||
|
||||
static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE;
|
||||
|
||||
+static CHAR8* rmc_db;
|
||||
+static rmc_fingerprint_t *rmc_fp;
|
||||
+
|
||||
enum loader_type {
|
||||
LOADER_UNDEFINED,
|
||||
LOADER_EFI,
|
||||
@@ -1684,6 +1688,136 @@ static VOID config_free(Config *config) {
|
||||
FreePool(config->entry_oneshot);
|
||||
}
|
||||
|
||||
+/* Derived from line_get_key_value(), we could consolidate two functions later */
|
||||
+static CHAR8 *get_line(CHAR8 *content, UINT64 *pos) {
|
||||
+ CHAR8 *line;
|
||||
+ UINT64 linelen;
|
||||
+
|
||||
+skip:
|
||||
+ line = content + *pos;
|
||||
+ if (*line == '\0')
|
||||
+ return NULL;
|
||||
+
|
||||
+ linelen = 0;
|
||||
+ while (line[linelen] && !strchra((CHAR8 *)"\n\r", line[linelen]))
|
||||
+ linelen++;
|
||||
+
|
||||
+ /* move pos to next line */
|
||||
+ *pos += linelen;
|
||||
+ if (content[*pos])
|
||||
+ (*pos)++;
|
||||
+
|
||||
+ /* empty line */
|
||||
+ if (linelen == 0)
|
||||
+ goto skip;
|
||||
+
|
||||
+ /* terminate line */
|
||||
+ line[linelen] = '\0';
|
||||
+
|
||||
+ /* remove leading whitespace */
|
||||
+ while (strchra((CHAR8 *)" \t", *line)) {
|
||||
+ line++;
|
||||
+ linelen--;
|
||||
+ }
|
||||
+
|
||||
+ /* remove trailing whitespace */
|
||||
+ while (linelen > 0 && strchra((CHAR8 *)" \t", line[linelen-1]))
|
||||
+ linelen--;
|
||||
+ line[linelen] = '\0';
|
||||
+
|
||||
+ if (*line == '#')
|
||||
+ goto skip;
|
||||
+
|
||||
+ return line;
|
||||
+}
|
||||
+
|
||||
+/* load rmc database file from ESP and try to get fingerprint. These
|
||||
+ * are essential information indicating we could query rmc data for
|
||||
+ * this board at least
|
||||
+ * return 0 if both database file and fingerprint can be obtained, otherwise
|
||||
+ * non-zero value is returned.
|
||||
+ *
|
||||
+ * Note: db and fp hold valid values only when this function returns 0.
|
||||
+ * Caller is responsible to free allocated memory pointed by *db and *fp when
|
||||
+ * this function returns 0.
|
||||
+ */
|
||||
+
|
||||
+static UINTN rmc_initialize(EFI_FILE *root_dir, EFI_SYSTEM_TABLE *sys_table, CHAR8 **db, rmc_fingerprint_t **fp) {
|
||||
+ UINTN len;
|
||||
+ UINTN ret = 1;
|
||||
+
|
||||
+ if (!db || !fp)
|
||||
+ return ret;
|
||||
+
|
||||
+ *db = NULL;
|
||||
+ *fp = NULL;
|
||||
+
|
||||
+ /* load rmc database */
|
||||
+ len = file_read(root_dir, L"\\rmc.db", 0, 0, db);
|
||||
+
|
||||
+ if (len <= 0)
|
||||
+ goto done;
|
||||
+
|
||||
+ *fp = AllocateZeroPool(sizeof(rmc_fingerprint_t));
|
||||
+ /* call rmc to get fingerprint. We will use single-action rmc APIs to query multiple files.
|
||||
+ * This should bring a better performance than calling double-action rmc API every time.
|
||||
+ */
|
||||
+ if (rmc_get_fingerprint(sys_table, *fp))
|
||||
+ goto done;
|
||||
+
|
||||
+ ret = 0;
|
||||
+done:
|
||||
+ if (ret) {
|
||||
+ FreePool(*db);
|
||||
+ FreePool(*fp);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/* load RMC entries
|
||||
+ * return TRUE when at least one entry is loaded, otherwise, return FALSE
|
||||
+ */
|
||||
+static BOOLEAN config_load_rmc_entries(Config *config, EFI_HANDLE *device, CHAR16 *loaded_image_path, CHAR8 *db, rmc_fingerprint_t *fp) {
|
||||
+ CHAR8 *boot_entry = NULL;
|
||||
+ CHAR8 *boot_config = NULL;
|
||||
+ rmc_file_t rp;
|
||||
+ CHAR8 *line;
|
||||
+ UINT64 pos = 0;
|
||||
+ BOOLEAN ret = FALSE;
|
||||
+
|
||||
+ if (!db || !fp)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* query boot entry config file */
|
||||
+ if (rmc_query_file_by_fp(fp, db, "BOOTENTRY.CONFIG", &rp))
|
||||
+ return ret;
|
||||
+
|
||||
+ /* file blob read from rmc db is not necessarily null-terminated, and we
|
||||
+ * should keep mem where rmc db lives from change during parsing
|
||||
+ */
|
||||
+ boot_config = AllocatePool(rp.blob_len * sizeof(CHAR8) + 1);
|
||||
+ CopyMem(boot_config, rp.blob, rp.blob_len);
|
||||
+ boot_config[rp.blob_len] = '\0';
|
||||
+ /* parse boot entry config */
|
||||
+ while ((line = get_line(boot_config, &pos))) {
|
||||
+ if (rmc_query_file_by_fp(fp, db, (char *)line, &rp))
|
||||
+ continue;
|
||||
+ if (rp.blob_len > 0) {
|
||||
+ boot_entry = AllocatePool(rp.blob_len * sizeof(CHAR8) + 1);
|
||||
+ CopyMem(boot_entry, rp.blob, rp.blob_len);
|
||||
+ boot_entry[rp.blob_len] = '\0';
|
||||
+ config_entry_add_from_file(config, device,
|
||||
+ stra_to_str(line), boot_entry,
|
||||
+ loaded_image_path);
|
||||
+ /* tell caller success when a RMC entry is loaded */
|
||||
+ ret = TRUE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
CHAR16 *s;
|
||||
CHAR8 *b;
|
||||
@@ -1696,6 +1830,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
UINT64 init_usec;
|
||||
BOOLEAN menu = FALSE;
|
||||
CHAR16 uuid[37];
|
||||
+ BOOLEAN rmc_entry = FALSE;
|
||||
|
||||
InitializeLib(image, sys_table);
|
||||
init_usec = time_usec();
|
||||
@@ -1736,6 +1871,9 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Initialize rmc before loading any config */
|
||||
+ rmc_initialize(root_dir, sys_table, &rmc_db, &rmc_fp);
|
||||
+
|
||||
/* the filesystem path to this image, to prevent adding ourselves to the menu */
|
||||
loaded_image_path = DevicePathToStr(loaded_image->FilePath);
|
||||
efivar_set(L"LoaderImageIdentifier", loaded_image_path, FALSE);
|
||||
@@ -1743,11 +1881,15 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
ZeroMem(&config, sizeof(Config));
|
||||
config_load_defaults(&config, root_dir);
|
||||
|
||||
+ if (rmc_db && rmc_fp)
|
||||
+ rmc_entry = config_load_rmc_entries(&config, loaded_image->DeviceHandle, loaded_image_path, rmc_db, rmc_fp);
|
||||
+
|
||||
/* scan /EFI/Linux/ directory */
|
||||
config_entry_add_linux(&config, loaded_image, root_dir);
|
||||
|
||||
- /* scan /loader/entries/\*.conf files */
|
||||
- config_load_entries(&config, loaded_image->DeviceHandle, root_dir, loaded_image_path);
|
||||
+ /* scan /loader/entries/\*.conf files only when no RMC entry is loaded */
|
||||
+ if (rmc_entry == FALSE)
|
||||
+ config_load_entries(&config, loaded_image->DeviceHandle, root_dir, loaded_image_path);
|
||||
|
||||
/* sort entries after version number */
|
||||
config_sort_entries(&config);
|
||||
@@ -1841,6 +1983,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
out:
|
||||
FreePool(loaded_image_path);
|
||||
config_free(&config);
|
||||
+ FreePool(rmc_db);
|
||||
+ FreePool(rmc_fp);
|
||||
uefi_call_wrapper(root_dir->Close, 1, root_dir);
|
||||
uefi_call_wrapper(BS->CloseProtocol, 4, image, &LoadedImageProtocol, image, NULL);
|
||||
return err;
|
||||
--
|
||||
2.14.3
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
From 159c8c54f92fb44d8abd2919fa83ad1cb640fac3 Mon Sep 17 00:00:00 2001
|
||||
From: Jianxun Zhang <jianxun.zhang@linux.intel.com>
|
||||
Date: Mon, 20 Jun 2016 13:08:20 -0700
|
||||
Subject: [PATCH 4/5] sd-boot: Support global kernel command line fragment
|
||||
|
||||
Query file blob KBOOTPARAM from RMC. If it exists, we append
|
||||
it to the new linux boot entry's cmdline. A boot entry could
|
||||
be read from a .conf file on ESP, RMC database, or embedded
|
||||
linux image. content in KBOOTPARAM is effective in all of
|
||||
these cases.
|
||||
|
||||
Upstream-Status: Pending
|
||||
|
||||
Signed-off-by: Jianxun Zhang <jianxun.zhang@linux.intel.com>
|
||||
Signed-off-by: California Sullivan <california.l.sullivan@intel.com>
|
||||
---
|
||||
src/boot/efi/boot.c | 34 ++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 34 insertions(+)
|
||||
|
||||
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
|
||||
index 93cfaf193..2f400db3c 100644
|
||||
--- a/src/boot/efi/boot.c
|
||||
+++ b/src/boot/efi/boot.c
|
||||
@@ -851,6 +851,40 @@ static VOID config_add_entry(Config *config, ConfigEntry *entry) {
|
||||
config->entries = ReallocatePool(config->entries,
|
||||
sizeof(VOID *) * config->entry_count, sizeof(VOID *) * i);
|
||||
}
|
||||
+
|
||||
+ /* rmc: a linux entry could be added from .conf file or an embedded linux image
|
||||
+ * we put appending global command line here to cover both of two cases.
|
||||
+ */
|
||||
+ if (entry->type == LOADER_LINUX && rmc_db && rmc_fp) {
|
||||
+ rmc_file_t rmc_kp;
|
||||
+
|
||||
+ if (!rmc_query_file_by_fp(rmc_fp, rmc_db, "KBOOTPARAM", &rmc_kp)) {
|
||||
+ CHAR8 *cmdline;
|
||||
+ CHAR16 *s;
|
||||
+ CHAR16 *t;
|
||||
+ CHAR16 *p;
|
||||
+
|
||||
+ cmdline = AllocatePool(rmc_kp.blob_len * sizeof(CHAR8) + 1);
|
||||
+ CopyMem(cmdline, rmc_kp.blob, rmc_kp.blob_len);
|
||||
+ cmdline[rmc_kp.blob_len] = '\0';
|
||||
+ p = stra_to_str(cmdline);
|
||||
+ t = p;
|
||||
+
|
||||
+ while (*t) {
|
||||
+ if (*t == '\n')
|
||||
+ *t = '\0';
|
||||
+ t++;
|
||||
+ }
|
||||
+
|
||||
+ s = PoolPrint(L"%s %s", entry->options, p);
|
||||
+ FreePool(entry->options);
|
||||
+ FreePool(p);
|
||||
+ FreePool(cmdline);
|
||||
+
|
||||
+ entry->options = s;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
config->entries[config->entry_count++] = entry;
|
||||
}
|
||||
|
||||
--
|
||||
2.14.3
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
From 405a77233dde990fa7815d1546dc5a6b5a608479 Mon Sep 17 00:00:00 2001
|
||||
From: Mikko Ylinen <mikko.ylinen@intel.com>
|
||||
Date: Fri, 27 Jan 2017 13:31:45 +0200
|
||||
Subject: [PATCH 5/5] sd-boot: support global kernel command line in EFI stub
|
||||
|
||||
This change integrates rmc into EFI stub and supports a
|
||||
global fragment (RMC KBOOTPARAM) that is appended to the
|
||||
cmdline at boot.
|
||||
|
||||
The fragment is board-specific and read from the database.
|
||||
|
||||
Implements [YOCTO #10924].
|
||||
|
||||
Upstream-status: Pending
|
||||
|
||||
Signed-off-by: Mikko Ylinen <mikko.ylinen@intel.com>
|
||||
Signed-off-by: California Sullivan <california.l.sullivan@intel.com>
|
||||
---
|
||||
src/boot/efi/stub.c | 33 +++++++++++++++++++++++++++++++++
|
||||
1 file changed, 33 insertions(+)
|
||||
|
||||
diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c
|
||||
index 540ca5985..11047477b 100644
|
||||
--- a/src/boot/efi/stub.c
|
||||
+++ b/src/boot/efi/stub.c
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
+#include <rmc_api.h>
|
||||
|
||||
#include "disk.h"
|
||||
#include "graphics.h"
|
||||
@@ -49,6 +50,9 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
UINTN cmdline_len;
|
||||
CHAR16 uuid[37];
|
||||
EFI_STATUS err;
|
||||
+ INTN len;
|
||||
+ CHAR8 *rmc_db = NULL;
|
||||
+ rmc_file_t rmc_file;
|
||||
|
||||
InitializeLib(image, sys_table);
|
||||
|
||||
@@ -109,6 +113,35 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
#endif
|
||||
}
|
||||
|
||||
+ len = file_read(root_dir, L"\\rmc.db", 0, 0, &rmc_db);
|
||||
+ if (len <= 0)
|
||||
+ rmc_db = NULL;
|
||||
+
|
||||
+ /* If the board has a fragment in rmc database, append it to the cmdline */
|
||||
+ if (rmc_db && !rmc_gimme_file(sys_table, rmc_db, "KBOOTPARAM", &rmc_file)) {
|
||||
+ CHAR8 *line;
|
||||
+ UINTN i = 0;
|
||||
+ UINTN j;
|
||||
+
|
||||
+ line = AllocatePool(rmc_file.blob_len + cmdline_len + 2);
|
||||
+
|
||||
+ while (i < cmdline_len && cmdline[i] != '\0') {
|
||||
+ line[i] = cmdline[i];
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ line[i++] = ' ';
|
||||
+
|
||||
+ for (j=0; j < rmc_file.blob_len; j++)
|
||||
+ line[i+j] = rmc_file.blob[j];
|
||||
+ line[i+j] = '\0';
|
||||
+
|
||||
+ cmdline = line;
|
||||
+ cmdline_len = i + j;
|
||||
+
|
||||
+ FreePool(rmc_db);
|
||||
+ }
|
||||
+
|
||||
/* export the device path this image is started from */
|
||||
if (disk_get_part_uuid(loaded_image->DeviceHandle, uuid) == EFI_SUCCESS)
|
||||
efivar_set(L"LoaderDevicePartUUID", uuid, FALSE);
|
||||
--
|
||||
2.14.3
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
# This patchset contains hooks that allows systemd-boot to use RMC capablilities.
|
||||
python __anonymous () {
|
||||
import re
|
||||
target = d.getVar('TARGET_ARCH')
|
||||
prefix = "" if d.getVar('EFI_PROVIDER') == "rmc-boot" else "systemd-"
|
||||
if target == "x86_64":
|
||||
systemdimage = prefix + "bootx64.efi"
|
||||
else:
|
||||
systemdimage = prefix + "bootia32.efi"
|
||||
d.setVar("SYSTEMD_BOOT_IMAGE", systemdimage)
|
||||
prefix = "systemd-" if prefix == "" else ""
|
||||
d.setVar("SYSTEMD_BOOT_IMAGE_PREFIX", prefix)
|
||||
}
|
||||
|
||||
DEPENDS_append_intel-x86-common = " rmc rmc-efi"
|
||||
RDEPENDS_${PN}_append_intel-x86-common = " rmc-db"
|
||||
|
||||
EXTRA_OEMESON_append_intel-x86-common = ' \
|
||||
-Drmc-includedir="${STAGING_INCDIR}/rmc" \
|
||||
'
|
||||
|
||||
SRC_URI_append_intel-x86-common = " \
|
||||
file://0001-partially-revert-sd-boot-stub-Obtain-PE-section-offs.patch \
|
||||
file://0002-sd-boot-fix-RMC-compatibility-with-systemd-boot-and-.patch \
|
||||
file://0003-sd-boot-Load-board-specific-boot-entries-from-RMC-da.patch \
|
||||
file://0004-sd-boot-Support-global-kernel-command-line-fragment.patch \
|
||||
file://0005-sd-boot-support-global-kernel-command-line-in-EFI-st.patch \
|
||||
"
|
||||
|
||||
RPROVIDES_${PN} += "rmc-boot"
|
|
@ -13,6 +13,3 @@ do_compile_append_intel-x86-common() {
|
|||
do_deploy_append_intel-x86-common() {
|
||||
install ${B}/src/boot/efi/linux*.efi.stub ${DEPLOYDIR}
|
||||
}
|
||||
|
||||
# includes rmc-boot.inc if rmc-boot is the EFI_PROVIDER
|
||||
include systemd-boot/${EFI_PROVIDER}.inc
|
||||
|
|
|
@ -1,342 +0,0 @@
|
|||
#!/bin/sh -e
|
||||
#
|
||||
# Copyright (c) 2016, Intel Corporation.
|
||||
# All rights reserved.
|
||||
#
|
||||
# install.sh [device_name] [rootfs_name]
|
||||
#
|
||||
# This file is a copy of file with same name in OE:
|
||||
# meta/recipes-core/initrdscripts/files/. We modify
|
||||
# it for RMC feature to deploy file blobs from RMC
|
||||
# database file to target.
|
||||
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||
|
||||
# We need 20 Mb for the boot partition
|
||||
boot_size=20
|
||||
|
||||
# 5% for swap
|
||||
swap_ratio=5
|
||||
|
||||
# Get a list of hard drives
|
||||
hdnamelist=""
|
||||
live_dev_name=`cat /proc/mounts | grep ${1%/} | awk '{print $1}'`
|
||||
live_dev_name=${live_dev_name#\/dev/}
|
||||
# Only strip the digit identifier if the device is not an mmc
|
||||
case $live_dev_name in
|
||||
mmcblk*)
|
||||
;;
|
||||
nvme*)
|
||||
;;
|
||||
*)
|
||||
live_dev_name=${live_dev_name%%[0-9]*}
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Searching for hard drives ..."
|
||||
|
||||
for device in `ls /sys/block/`; do
|
||||
case $device in
|
||||
loop*)
|
||||
# skip loop device
|
||||
;;
|
||||
sr*)
|
||||
# skip CDROM device
|
||||
;;
|
||||
ram*)
|
||||
# skip ram device
|
||||
;;
|
||||
*)
|
||||
# skip the device LiveOS is on
|
||||
# Add valid hard drive name to the list
|
||||
case $device in
|
||||
$live_dev_name*)
|
||||
# skip the device we are running from
|
||||
;;
|
||||
*)
|
||||
hdnamelist="$hdnamelist $device"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "${hdnamelist}" ]; then
|
||||
echo "You need another device (besides the live device /dev/${live_dev_name}) to install the image. Installation aborted."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET_DEVICE_NAME=""
|
||||
for hdname in $hdnamelist; do
|
||||
# Display found hard drives and their basic info
|
||||
echo "-------------------------------"
|
||||
echo /dev/$hdname
|
||||
if [ -r /sys/block/$hdname/device/vendor ]; then
|
||||
echo -n "VENDOR="
|
||||
cat /sys/block/$hdname/device/vendor
|
||||
fi
|
||||
if [ -r /sys/block/$hdname/device/model ]; then
|
||||
echo -n "MODEL="
|
||||
cat /sys/block/$hdname/device/model
|
||||
fi
|
||||
if [ -r /sys/block/$hdname/device/uevent ]; then
|
||||
echo -n "UEVENT="
|
||||
cat /sys/block/$hdname/device/uevent
|
||||
fi
|
||||
echo
|
||||
done
|
||||
|
||||
# Get user choice
|
||||
while true; do
|
||||
echo "Please select an install target or press n to exit ($hdnamelist ): "
|
||||
read answer
|
||||
if [ "$answer" = "n" ]; then
|
||||
echo "Installation manually aborted."
|
||||
exit 1
|
||||
fi
|
||||
for hdname in $hdnamelist; do
|
||||
if [ "$answer" = "$hdname" ]; then
|
||||
TARGET_DEVICE_NAME=$answer
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ -n "$TARGET_DEVICE_NAME" ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$TARGET_DEVICE_NAME" ]; then
|
||||
echo "Installing image on /dev/$TARGET_DEVICE_NAME ..."
|
||||
else
|
||||
echo "No hard drive selected. Installation aborted."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
device=/dev/$TARGET_DEVICE_NAME
|
||||
|
||||
#
|
||||
# The udev automounter can cause pain here, kill it
|
||||
#
|
||||
rm -f /etc/udev/rules.d/automount.rules
|
||||
rm -f /etc/udev/scripts/mount*
|
||||
|
||||
#
|
||||
# Unmount anything the automounter had mounted
|
||||
#
|
||||
umount ${device}* 2> /dev/null || /bin/true
|
||||
|
||||
mkdir -p /tmp
|
||||
|
||||
# Create /etc/mtab if not present
|
||||
if [ ! -e /etc/mtab ]; then
|
||||
cat /proc/mounts > /etc/mtab
|
||||
fi
|
||||
|
||||
disk_size=$(parted ${device} unit mb print | grep '^Disk .*: .*MB' | cut -d" " -f 3 | sed -e "s/MB//")
|
||||
|
||||
swap_size=$((disk_size*swap_ratio/100))
|
||||
rootfs_size=$((disk_size-boot_size-swap_size))
|
||||
|
||||
rootfs_start=$((boot_size))
|
||||
rootfs_end=$((rootfs_start+rootfs_size))
|
||||
swap_start=$((rootfs_end))
|
||||
|
||||
# MMC devices are special in a couple of ways
|
||||
# 1) they use a partition prefix character 'p'
|
||||
# 2) they are detected asynchronously (need rootwait)
|
||||
rootwait=""
|
||||
part_prefix=""
|
||||
if [ ! "${device#/dev/mmcblk}" = "${device}" ] || \
|
||||
[ ! "${device#/dev/nvme}" = "${device}" ]; then
|
||||
part_prefix="p"
|
||||
rootwait="rootwait"
|
||||
fi
|
||||
bootfs=${device}${part_prefix}1
|
||||
rootfs=${device}${part_prefix}2
|
||||
swap=${device}${part_prefix}3
|
||||
|
||||
echo "*****************"
|
||||
echo "Boot partition size: $boot_size MB ($bootfs)"
|
||||
echo "Rootfs partition size: $rootfs_size MB ($rootfs)"
|
||||
echo "Swap partition size: $swap_size MB ($swap)"
|
||||
echo "*****************"
|
||||
echo "Deleting partition table on ${device} ..."
|
||||
dd if=/dev/zero of=${device} bs=512 count=35
|
||||
|
||||
echo "Creating new partition table on ${device} ..."
|
||||
parted ${device} mklabel gpt
|
||||
|
||||
echo "Creating boot partition on $bootfs"
|
||||
parted ${device} mkpart boot fat32 0% $boot_size
|
||||
parted ${device} set 1 boot on
|
||||
|
||||
echo "Creating rootfs partition on $rootfs"
|
||||
parted ${device} mkpart root ext3 $rootfs_start $rootfs_end
|
||||
|
||||
echo "Creating swap partition on $swap"
|
||||
parted ${device} mkpart swap linux-swap $swap_start 100%
|
||||
|
||||
parted ${device} print
|
||||
|
||||
echo "Formatting $bootfs to vfat..."
|
||||
mkfs.vfat $bootfs
|
||||
|
||||
echo "Formatting $rootfs to ext3..."
|
||||
mkfs.ext3 $rootfs
|
||||
|
||||
echo "Formatting swap partition...($swap)"
|
||||
mkswap $swap
|
||||
|
||||
mkdir /tgt_root
|
||||
mkdir /src_root
|
||||
mkdir -p /boot
|
||||
|
||||
# Handling of the target root partition
|
||||
mount $rootfs /tgt_root
|
||||
mount -o rw,loop,noatime,nodiratime /run/media/$1/$2 /src_root
|
||||
echo "Copying rootfs files..."
|
||||
cp -a /src_root/* /tgt_root
|
||||
if [ -d /tgt_root/etc/ ] ; then
|
||||
boot_uuid=$(blkid -o value -s UUID ${bootfs})
|
||||
swap_part_uuid=$(blkid -o value -s PARTUUID ${swap})
|
||||
echo "/dev/disk/by-partuuid/$swap_part_uuid swap swap defaults 0 0" >> /tgt_root/etc/fstab
|
||||
echo "UUID=$boot_uuid /boot vfat defaults 1 2" >> /tgt_root/etc/fstab
|
||||
# We dont want udev to mount our root device while we're booting...
|
||||
if [ -d /tgt_root/etc/udev/ ] ; then
|
||||
echo "${device}" >> /tgt_root/etc/udev/mount.blacklist
|
||||
fi
|
||||
fi
|
||||
|
||||
# Handling of the target boot partition
|
||||
mount $bootfs /boot
|
||||
echo "Preparing boot partition..."
|
||||
|
||||
EFIDIR="/boot/EFI/BOOT"
|
||||
mkdir -p $EFIDIR
|
||||
# Copy the efi loader
|
||||
cp /run/media/$1/EFI/BOOT/*.efi $EFIDIR
|
||||
|
||||
# RMC deployment
|
||||
RMC_CMD=/src_root/usr/bin/rmc
|
||||
RMC_DB=/run/media/$1/rmc.db
|
||||
|
||||
# We don't want to quit when a step failed. For example,
|
||||
# a file system could not support some operations.
|
||||
set +e
|
||||
|
||||
if [ -f "${RMC_DB}" ] && [ -f "${RMC_CMD}" ]; then
|
||||
echo "Found RMC database and tool, start RMC deployment"
|
||||
# query INSTALLER.CONFIG from RMC DB
|
||||
if ${RMC_CMD} -B INSTALLER.CONFIG -d "${RMC_DB}" -o /tmp/installer.config; then
|
||||
while IFS=':' read -r NAME TGT_UID TGT_GID TGT_MODE TGT_PATH; do
|
||||
# skip comment
|
||||
# The regexp in grep works with busybox grep which doesn't
|
||||
# seem to have a -P to recognize '\t'. But this expression could not
|
||||
# work with gnu grep...
|
||||
if echo "$NAME"|grep -q $'^[ \t]*#'; then
|
||||
continue
|
||||
fi
|
||||
# check if we should create a directory (last char in target path is '/')
|
||||
# or deploy a file
|
||||
LAST_CHAR=$(echo "${TGT_PATH:$((${#TGT_PATH}-1)):1}")
|
||||
|
||||
# Do not bail out for failures but user should get stderr message
|
||||
if [ ${LAST_CHAR} = "/" ]; then
|
||||
# name field is skipped for directory
|
||||
echo "DIR: ${TGT_UID}:${TGT_GID}:${TGT_MODE} => ${TGT_PATH}"
|
||||
mkdir -p "$TGT_PATH"
|
||||
chown "${TGT_UID}:${TGT_GID}" "$TGT_PATH"
|
||||
chmod "${TGT_MODE}" "$TGT_PATH"
|
||||
else
|
||||
${RMC_CMD} -B "${NAME}" -d "${RMC_DB}" -o "${TGT_PATH}"
|
||||
echo "FILE: ${NAME}:${TGT_UID}:${TGT_GID}:${TGT_MODE} => ${TGT_PATH}"
|
||||
chown "${TGT_UID}:${TGT_GID}" "$TGT_PATH"
|
||||
chmod "${TGT_MODE}" "$TGT_PATH"
|
||||
fi
|
||||
done < /tmp/installer.config
|
||||
rm -rf /tmp/installer.config
|
||||
|
||||
# remove rmc from target since we don't think it is a valid
|
||||
# case to run rmc after installation.
|
||||
rm -rf /tgt_root/usr/bin/rmc
|
||||
echo "RMC deployment finished"
|
||||
else
|
||||
echo "INSTALLER.CONFIG is not found, skip RMC deployment"
|
||||
fi
|
||||
|
||||
# Final retouching by calling post-install hook
|
||||
if ${RMC_CMD} -B POSTINSTALL.sh -d "${RMC_DB}" -o /tmp/POSTINSTALL.sh; then
|
||||
echo "Found POSTINSTALL.sh execute it..."
|
||||
chmod 500 /tmp/POSTINSTALL.sh
|
||||
/tmp/POSTINSTALL.sh
|
||||
rm -rf /tmp/POSTINSTALL.sh
|
||||
fi
|
||||
fi
|
||||
set -e
|
||||
|
||||
if [ -f /run/media/$1/EFI/BOOT/grub.cfg ]; then
|
||||
root_part_uuid=$(blkid -o value -s PARTUUID ${rootfs})
|
||||
GRUBCFG="$EFIDIR/grub.cfg"
|
||||
cp /run/media/$1/EFI/BOOT/grub.cfg $GRUBCFG
|
||||
# Update grub config for the installed image
|
||||
# Delete the install entry
|
||||
sed -i "/menuentry 'install'/,/^}/d" $GRUBCFG
|
||||
# Delete the initrd lines
|
||||
sed -i "/initrd /d" $GRUBCFG
|
||||
# Delete any LABEL= strings
|
||||
sed -i "s/ LABEL=[^ ]*/ /" $GRUBCFG
|
||||
# Delete any root= strings
|
||||
sed -i "s/ root=[^ ]*/ /g" $GRUBCFG
|
||||
# Add the root= and other standard boot options
|
||||
sed -i "s@linux /vmlinuz *@linux /vmlinuz root=PARTUUID=$root_part_uuid rw $rootwait quiet @" $GRUBCFG
|
||||
fi
|
||||
|
||||
if [ -d /run/media/$1/loader ]; then
|
||||
rootuuid=$(blkid -o value -s PARTUUID ${rootfs})
|
||||
GUMMIBOOT_CFGS="/boot/loader/entries/*.conf"
|
||||
if [ -d /boot/loader ]; then
|
||||
# Don't override loader.conf RMC already deployed
|
||||
if [ ! -f /boot/loader/loader.conf ]; then
|
||||
cp /run/media/$1/loader/loader.conf /boot/loader/
|
||||
fi
|
||||
# only copy built OE entries when RMC entries don't exist.
|
||||
if [ ! -d /boot/loader/entries ] || [ ! ls /boot/loader/entries/*.conf &>/dev/null ]; then
|
||||
cp -dr /run/media/$1/loader/entries /boot/loader
|
||||
fi
|
||||
else
|
||||
# copy config files for gummiboot
|
||||
cp -dr /run/media/$1/loader /boot
|
||||
# delete the install entry
|
||||
rm -f /boot/loader/entries/install.conf
|
||||
fi
|
||||
# delete the initrd lines
|
||||
sed -i "/initrd /d" $GUMMIBOOT_CFGS
|
||||
# delete any LABEL= strings
|
||||
sed -i "s/ LABEL=[^ ]*/ /" $GUMMIBOOT_CFGS
|
||||
# delete any root= strings
|
||||
sed -i "s/ root=[^ ]*/ /" $GUMMIBOOT_CFGS
|
||||
# add the root= and other standard boot options
|
||||
sed -i "s@options *@options root=PARTUUID=$rootuuid rw $rootwait quiet @" $GUMMIBOOT_CFGS
|
||||
# if RMC feature presents, append global kernel command line fragment when it exists.
|
||||
if [ -f "${RMC_DB}" ] && [ -f "${RMC_CMD}" ]; then
|
||||
if ${RMC_CMD} -B KBOOTPARAM -d "${RMC_DB}" -o /tmp/kbootparam; then
|
||||
sed -i "/^[ \t]*options/ s/$/ $(cat /tmp/kbootparam)/" $GUMMIBOOT_CFGS
|
||||
rm /tmp/kbootparam
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
cp /run/media/$1/vmlinuz /boot
|
||||
|
||||
umount /src_root
|
||||
umount /tgt_root
|
||||
umount /boot
|
||||
|
||||
sync
|
||||
|
||||
echo "Remove your installation media, and press ENTER"
|
||||
|
||||
read enter
|
||||
|
||||
echo "Rebooting..."
|
||||
reboot -f
|
|
@ -1,2 +0,0 @@
|
|||
FILESEXTRAPATHS_prepend_intel-x86-common := "${THISDIR}/files:"
|
||||
PACKAGE_ARCH_intel-x86-common = "${INTEL_COMMON_PACKAGE_ARCH}"
|
Loading…
Reference in New Issue
Block a user