[arch-projects] [mkinitcpio] [PATCH v2] Add 'microcode' hooks

Weng Xuetian wengxt at gmail.com
Mon Nov 3 19:03:47 UTC 2014


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


More information about the arch-projects mailing list