Add early microcode support with early cpio. All files added under /early_root will be created as a separate cpio prepend to original one. Add a early_cpio file to early cpio to detect whether cpio contains early cpio, thus we can have lsinitcpio work normally like old one. --- Makefile | 7 ++++++- install/microcode | 24 ++++++++++++++++++++++++ lsinitcpio | 29 +++++++++++++++++++++++++++-- mkinitcpio | 43 ++++++++++++++++++++++++++++++------------- skipcpio | 31 +++++++++++++++++++++++++++++++ 5 files changed, 118 insertions(+), 16 deletions(-) create mode 100644 install/microcode create mode 100755 skipcpio diff --git a/Makefile b/Makefile index 5af0eb2..83a21dc 100644 --- a/Makefile +++ b/Makefile @@ -40,10 +40,15 @@ install: all < mkinitcpio > $(DESTDIR)/usr/bin/mkinitcpio sed -e 's|\(^_f_functions\)=.*|\1=/usr/lib/initcpio/functions|' \ + -e 's|\(^_f_skipcpio\)=.*|\1=/usr/lib/initcpio/skipcpio|' \ -e 's|%VERSION%|$(VERSION)|g' \ < lsinitcpio > $(DESTDIR)/usr/bin/lsinitcpio - chmod 755 $(DESTDIR)/usr/bin/lsinitcpio $(DESTDIR)/usr/bin/mkinitcpio + sed -e 's|\(^_f_functions\)=.*|\1=/usr/lib/initcpio/functions|' \ + < skipcpio > $(DESTDIR)/usr/lib/initcpio/skipcpio + + chmod 755 $(DESTDIR)/usr/bin/lsinitcpio $(DESTDIR)/usr/bin/mkinitcpio \ + $(DESTDIR)/usr/lib/initcpio/skipcpio install -m644 mkinitcpio.conf $(DESTDIR)/etc/mkinitcpio.conf install -m755 -t $(DESTDIR)/usr/lib/initcpio init shutdown diff --git a/install/microcode b/install/microcode new file mode 100644 index 0000000..4dfd69e --- /dev/null +++ b/install/microcode @@ -0,0 +1,24 @@ +#!/bin/bash + +build() { + ucode_dir=(amd-ucode intel-ucode) + ucode_dest=(AuthenticAMD.bin GenuineIntel.bin) + + for idx in 0 1; do + fw=${ucode_dir[$idx]} + for fwpath in "${_d_firmware[@]}"; do + if [[ -d $fwpath/$fw ]]; then + add_dir '/early_root/kernel/x86/microcode' + cat $fwpath/$fw/* > $BUILDROOT/early_root/kernel/x86/microcode/${ucode_dest[$idx]} + fi + done + done +} + +help() { + cat <<HELPEOF +This hook generate early ucode update +HELPEOF +} + +# vim: set ft=sh ts=4 sw=4 et: diff --git a/lsinitcpio b/lsinitcpio index 9567b79..8d0ed1f 100755 --- a/lsinitcpio +++ b/lsinitcpio @@ -8,6 +8,8 @@ shopt -s extglob _list='--list' _optcolor=1 _optverbose= _f_functions=functions +_f_skipcpio=./skipcpio +_tmp_files=() usage() { cat<<USAGE @@ -131,7 +133,7 @@ analyze_image() { local kernver ratio columns=$(tput cols) image=$1 workdir=$(mktemp -d --tmpdir lsinitcpio.XXXXXX) - trap 'rm -rf "$workdir"' EXIT + _tmp_files+=("$workdir") # fallback in case tput failed us columns=${columns:-80} @@ -174,7 +176,7 @@ analyze_image() { explicitmod=($MODULES) # print results - imagename=$_image + imagename=$_origimage [[ -L $_image ]] && imagename+=" -> $(readlink -e "$_image")" msg 'Image: %s %s' "$imagename" [[ $version ]] && msg 'Created with mkinitcpio %s' "$version" @@ -225,6 +227,14 @@ analyze_image() { printf ' %s\n' $CLEANUPHOOKS printf '\n' fi + + msg 'Contains early CPIO:' + if (( _hasearly )); then + printf ' yes\n' + else + printf ' no\n' + fi + printf '\n' } _opt_short='achlnVvx' @@ -262,6 +272,8 @@ while :; do done _image=$1 +_origimage=$1 +_hasearly=0 if [[ -t 1 ]] && (( _optcolor )); then try_enable_color @@ -278,9 +290,22 @@ case $(( _optanalyze + _optlistcontents + _optshowconfig )) in die "Only one action may be specified at a time" ;; esac +trap '(( ${#_tmp_files[@]} )) && rm -rf "${_tmp_files[@]}"' EXIT + # read compression type _compress=$(detect_filetype "$_image") || exit +if decomp "$_image" | bsdcpio -i --quiet --list | grep -q '^early_cpio'; then + _hasearly=1 + _real_image=$(mktemp --tmpdir lsinitcpio.XXXXXX) + _tmp_files+=("$_real_image") + "$_f_skipcpio" "$_image" > "$_real_image" + _image="$_real_image" + # read compression type again for real image + _compress=$(detect_filetype "$_image") || exit +fi + + if (( _optanalyze )); then analyze_image "$_image" elif (( _optshowconfig )); then diff --git a/mkinitcpio b/mkinitcpio index 01fe8ba..d5dd46a 100755 --- a/mkinitcpio +++ b/mkinitcpio @@ -221,19 +221,36 @@ build_image() { cpio_opts+=('-R' '0:0') fi - pushd "$BUILDROOT" >/dev/null - find . -print0 | - LANG=C bsdcpio "${cpio_opts[@]}" | - $compress $COMPRESSION_OPTIONS > "$out" - pipesave=("${PIPESTATUS[@]}") # save immediately - popd >/dev/null - - if (( pipesave[0] )); then - errmsg="find reported an error" - elif (( pipesave[1] )); then - errmsg="bsdcpio reported an error" - elif (( pipesave[2] )); then - errmsg="$compress reported an error" + > "$out" + if [[ -d "$BUILDROOT/early_root" ]]; then + pushd "$BUILDROOT/early_root" >/dev/null + touch "$BUILDROOT/early_root/early_cpio" + find . -mindepth 1 -printf "%P\0" | + LANG=C bsdcpio "${cpio_opts[@]}" >> "$out" + popd >/dev/null + pipesave=("${PIPESTATUS[@]}") # save immediately + if (( pipesave[0] )); then + errmsg="find reported an error" + elif (( pipesave[1] )); then + errmsg="bsdcpio reported an error" + fi + fi + + if [[ ! $errmsg ]]; then + pushd "$BUILDROOT" >/dev/null + find . -path "./early_root" -prune -o -print0 | + LANG=C bsdcpio "${cpio_opts[@]}" | + $compress $COMPRESSION_OPTIONS >> "$out" + pipesave=("${PIPESTATUS[@]}") # save immediately + popd >/dev/null + + if (( pipesave[0] )); then + errmsg="find reported an error" + elif (( pipesave[1] )); then + errmsg="bsdcpio reported an error" + elif (( pipesave[2] )); then + errmsg="$compress reported an error" + fi fi if (( _builderrors )); then diff --git a/skipcpio b/skipcpio new file mode 100755 index 0000000..b106d87 --- /dev/null +++ b/skipcpio @@ -0,0 +1,31 @@ +#!/bin/bash +# +# skipcpio - skip current uncompressed cpio part +# + +shopt -s extglob + +_f_functions=functions + +. "$_f_functions" + +die() { + error "$@" + exit 1 +} + +_image=$1 +[[ $_image ]] || die "No image specified" +[[ -f $_image ]] || die "No such file: %s" "$_image" + +_CPIO_END='TRAILER!!!' + +# check if it's a cpio file +if [[ $(hexdump -n 6 -e '"%c"' "$1") = '070701' ]]; then + offset=$(grep -m 1 --byte-offset --only-matching --text $_CPIO_END "$1") + offset=$(( ${offset%%:$_CPIO_END} + ${#_CPIO_END} )) + # skip zero byte at the begining + dd if=$1 bs=$offset skip=1 2>/dev/null | sed '1 s/^\x00*//' +else + exec cat $1 +fi -- 2.0.2