summaryrefslogtreecommitdiff
path: root/scripts/package-build/linux-kernel/build-kernel.sh
blob: a4a4fc3c3f2ddd09d270c27a54eaa2bde52f32f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/bin/bash
CWD=$(pwd)
KERNEL_SRC=linux
GIT_ROOT=$(git rev-parse --show-toplevel)

set -e

if [ ! -d ${KERNEL_SRC} ]; then
    echo "Linux Kernel source directory does not exists, please 'git clone'"
    exit 1
fi

cd ${KERNEL_SRC}

if [ -d .git ]; then
    echo "I: Clean modified files - reset Git repo"
    git reset --hard HEAD
    git clean --force -d -x
fi

if [ -d /usr/lib/ccache/ ]; then
    export PATH=/usr/lib/ccache:$PATH
fi

KERNEL_VERSION=$(make kernelversion)
KERNEL_SUFFIX=-$(awk -F "= " '/kernel_flavor/ {print $2}' ../../../../data/defaults.toml | tr -d \")

echo "I: Generate Kernel config"
ARCH=$(dpkg --print-architecture)
# array to hold config fragments for merging
# allows safe handling of paths with spaces and avoids word-splitting issues
# The first entry is the base defconfig; subsequent entries are merged on top.
KCONFIG_MERGE_FRAGMENTS=()
if [ "${ARCH}" = "arm64" ]; then
    KCONFIG_MERGE_FRAGMENTS+=("${CWD}/config/arm64/vyos_defconfig")
elif [ "${ARCH}" = "amd64" ]; then
    KCONFIG_MERGE_FRAGMENTS+=("${CWD}/config/x86/vyos_defconfig")
else
    echo "E: unsupported architecture"
    exit 1
fi
# NOTE: do NOT export KCONFIG_CONFIG here. KCONFIG_CONFIG is interpreted by
# kbuild as the path to the OUTPUT .config file. Exporting it globally would
# cause `make vyos_defconfig` (and the rest of the kernel build) to write the
# resulting config to that path instead of producing a normal `.config` in the
# kernel source root, which breaks downstream steps that expect `linux/.config`
# to exist.

# VyOS requires some small Kernel Patches - apply them here
# It's easier to have them here and make use of the upstream
# repository instead of maintaining a full Kernel Fork.
# Saving time/resources is essential :-)
# Note that the patches should be applied BEFORE the kernel config is generated
# because patches may add new options!
PATCH_DIR=${CWD}/patches/kernel
for patch in $(ls ${PATCH_DIR})
do
    echo "I: Apply Kernel patch: ${PATCH_DIR}/${patch}"
    patch -p1 < ${PATCH_DIR}/${patch}
done

# Change name of Signing Cert
sed -i -e "s/CN =.*/CN=VyOS Networks build time autogenerated Kernel key/" certs/default_x509.genkey

TRUSTED_KEYS_FILE=trusted_keys.pem
# start with empty key file
echo -n "" > $TRUSTED_KEYS_FILE
CERTS=$(find ${GIT_ROOT}/data/certificates -name "*.pem" -type f || true)
TRUSTED_KEYS_FRAGMENT_TMP=""
if [ ! -z "${CERTS}" ]; then
  # add known public keys to Kernel certificate chain
  for file in $CERTS; do
    cat $file >> $TRUSTED_KEYS_FILE
  done
  # Force Kernel module signing and embed public keys
  TRUSTED_KEYS_FRAGMENT_TMP=$(mktemp --suffix=.config)
  echo "CONFIG_SYSTEM_TRUSTED_KEYRING=y" > $TRUSTED_KEYS_FRAGMENT_TMP
  echo "CONFIG_SYSTEM_TRUSTED_KEYS=\"$TRUSTED_KEYS_FILE\"" >> $TRUSTED_KEYS_FRAGMENT_TMP
fi

echo "I: Merge Kernel config snippets"
# Collect config fragments into the fragment array
for fragment in "${CWD}"/config/*.config; do
    [ -f "${fragment}" ] || continue
    echo "I: adding configuration snippet ${fragment}"
    KCONFIG_MERGE_FRAGMENTS+=("${fragment}")
done
if [ -n "${TRUSTED_KEYS_FRAGMENT_TMP}" ]; then
    echo "I: adding configuration snippet ${TRUSTED_KEYS_FRAGMENT_TMP}"
    KCONFIG_MERGE_FRAGMENTS+=("${TRUSTED_KEYS_FRAGMENT_TMP}")
fi

# Use the kernel's own merge_config.sh to properly merge all config fragments.
# This writes .config into the current (kernel source) dir.
# The first fragment in the array is the base defconfig; the remaining ones
# are merged on top of it. merge_config.sh will run `make alldefconfig` at
# the end to expand defaults, this replaces the previous separate
# `make vyos_defconfig` step.
# This will contain some warnings about "<symbol> not in final .config"
# which can mostly be ignored, but may provide relevant insight so we
# don't suppress it.
echo "I: Run scripts/kconfig/merge_config.sh to produce .config"

if [ ${#KCONFIG_MERGE_FRAGMENTS[@]} -eq 0 ]; then
    echo "E: No config fragments found for merging, cannot proceed"
    exit 1
fi
scripts/kconfig/merge_config.sh "${KCONFIG_MERGE_FRAGMENTS[@]}"

if [ ! -f .config ]; then
    echo "E: merge_config.sh did not produce a .config in $(pwd)"
    exit 1
fi

echo "I: Generate environment file containing Kernel variable"
EPHEMERAL_KEY="/tmp/ephemeral.key"
EPHEMERAL_PEM="/tmp/ephemeral.pem"
cat << EOF >${CWD}/kernel-vars
#!/bin/sh
export KERNEL_VERSION=${KERNEL_VERSION}
export KERNEL_SUFFIX=${KERNEL_SUFFIX}
export KERNEL_DIR=${CWD}/${KERNEL_SRC}
export EPHEMERAL_KEY=${EPHEMERAL_KEY}
export EPHEMERAL_CERT=${EPHEMERAL_PEM}
EOF

echo "I: Build Debian Kernel package"
touch .scmversion
make bindeb-pkg BUILD_TOOLS=1 LOCALVERSION=${KERNEL_SUFFIX} KDEB_PKGVERSION=${KERNEL_VERSION}-1 -j $(getconf _NPROCESSORS_ONLN)

# Back to the old Kernel build-scripts directory
cd $CWD
EPHEMERAL_KERNEL_KEY=$(grep -E "^CONFIG_MODULE_SIG_KEY=" "${KERNEL_SRC}/.config" | awk -F= '{print $2}' | tr -d \")
if test -f "${EPHEMERAL_KEY}"; then
    rm -f ${EPHEMERAL_KEY}
fi
if test -f "${EPHEMERAL_PEM}"; then
    rm -f ${EPHEMERAL_PEM}
fi
if test -f "${KERNEL_SRC}/${EPHEMERAL_KERNEL_KEY}"; then
    openssl rsa -in ${KERNEL_SRC}/${EPHEMERAL_KERNEL_KEY} -out ${EPHEMERAL_KEY}
    openssl x509 -in ${KERNEL_SRC}/${EPHEMERAL_KERNEL_KEY} -out ${EPHEMERAL_PEM}
fi