aboutsummaryrefslogtreecommitdiff
path: root/stages/build.sh
diff options
context:
space:
mode:
authorKacper Sagalara <mail@kasesag.me>2026-06-19 19:08:11 +0200
committerKacper Sagalara <mail@kasesag.me>2026-06-19 19:08:11 +0200
commit7821c02171d77229797e3a57edd0502e942373cc (patch)
tree2856fdb7f36144c6e539cfedacd475bf10458ce1 /stages/build.sh
parent0339c6b9e1cafffc2e37c47df4277157fc678041 (diff)
Add missing files.HEADmaster
Diffstat (limited to 'stages/build.sh')
-rwxr-xr-xstages/build.sh334
1 files changed, 334 insertions, 0 deletions
diff --git a/stages/build.sh b/stages/build.sh
new file mode 100755
index 0000000..6e1c02c
--- /dev/null
+++ b/stages/build.sh
@@ -0,0 +1,334 @@
+#!/bin/bash
+
+if [ ! -f .config ]; then
+ echo "[x] Configuration file not found!"
+ echo " Please configure build with 'make config' first."
+ exit 1
+fi
+
+source .config
+
+SUPER_IMAGE="$STOCK_FIRMWARE_PATH/super.img"
+FIRMWARE_OUT_DIR="./firmware"
+UNPACKED_DIR="./unpacked"
+MNT_BASE="$UNPACKED_DIR/mnt"
+TMP_DIR="/tmp/driedlamu"
+MNT_PARTITIONS=(
+ "system_a"
+ "product_a"
+ "system_ext_a"
+)
+
+if [[ -d $TMP_DIR || -d $UNPACKED_DIR ]]; then
+ echo "[x] Build directories detected"
+ echo " Please clean build environment with 'make clean' first."
+ exit 1
+fi
+
+prepare_erofs_utils() {
+ local erofs_utils_repo="https://api.github.com/repos/sekaiacg/erofs-utils/releases/latest"
+ local aarch=$(lscpu | sed -n 's/Architecture:[ \t]*//p')
+ local erofs_utils_url=$(curl -s "$erofs_utils_repo" | jq --arg aarch_jq $aarch -c '[ .assets[] | select( .browser_download_url | test("Linux_" + $aarch_jq + ".zip$")) ]' | jq -r ".[] | .browser_download_url")
+ local download_location="$TMP_DIR/erofs-utils.zip"
+
+ wget -O "$download_location" "$erofs_utils_url"
+ unzip "$download_location" -d "./utils/bin/"
+}
+
+prepare_apatch_utils() {
+ local apatch_repo="https://api.github.com/repos/bmax121/KernelPatch/releases/latest"
+ local apatch_urls=$(curl -s "$apatch_repo" | jq -r '[ .assets[] | select( .browser_download_url | test("kptools-linux|kpimg-android") ) ]' | jq -r ".[] | .browser_download_url")
+
+ for l in $apatch_urls; do
+ wget -P "./utils/bin/" "$l"
+ chmod +x ./utils/bin/kp*
+ done
+}
+
+simg() {
+ local super_image=$1
+ local unpacked_dir=$2
+ local super_dir=$(dirname "$super_image")
+ local super_raw="$super_dir/super_raw.img"
+
+ echo "[i] Converting a sparse image to raw"
+ if [ ! -f "$super_image" ]; then
+ echo "[x] super.img not found"
+ exit 1
+ fi
+
+ # converting from sparse
+ if ! simg2img "$super_image" "$super_raw"; then
+ echo "[x] Failed to convert super image"
+ exit 1
+ fi
+
+ echo "[i] Unpacking super raw image"
+ if ! lpunpack "$super_raw" "$unpacked_dir"; then
+ echo "[x] Failed to unpack super image"
+ exit 1
+ fi
+
+ echo "[i] Super image converting successful"
+}
+
+extract_erofs() {
+ local DIR=$1
+ local MNT_BASE="$2"
+
+ mkdir -p "${MNT_BASE}/${DIR}"
+
+ ./utils/bin/extract.erofs -i "${UNPACKED_DIR}/${DIR}.img" -o "${MNT_BASE}" -x
+ echo "[STAGE 2] ${DIR} EROFS partition extracted"
+}
+
+make_erofs() {
+ local part_name=$1
+ local target_dir=$2
+ local fs_config_dir="unpacked/mnt/config/"
+ local fs_uuid=$(cat ./${fs_config_dir}/${part_name}_fs_options | awk 'NR==2 {print $3}')
+
+ ./utils/bin/mkfs.erofs --quiet -zlz4hc -T 0 -U "$fs_uuid" --mount-point="/${part_name}" --fs-config-file="${fs_config_dir}/${part_name}_fs_config" --file-contexts="${fs_config_dir}/${part_name}_file_contexts" "${target_dir}/${part_name}.img" "unpacked/mnt/${part_name}"
+ echo "[STAGE 3] ${part_name} EROFS partition repacked"
+}
+
+unpack_images() {
+ local FS=$1
+
+ if [ ! -d "$MNT_BASE" ]; then
+ mkdir -p "$MNT_BASE"
+ echo "[+] Directory $MNT_BASE created"
+ else
+ echo "[i] Directory $MNT_BASE already exists"
+ fi
+
+ for dir in "${MNT_PARTITIONS[@]}"; do
+ if [ ! -d "${MNT_BASE}/$dir" ]; then
+ mkdir -p "${MNT_BASE}/$dir"
+ echo "[+] Directory $dir created"
+ else
+ echo "[i] Directory $dir already exists"
+ fi
+
+ if [[ "${FS}" = "erofs" ]]; then
+ extract_erofs "${dir}" "${MNT_BASE}"
+ mkdir -p "unpacked/original"
+ mv "unpacked/${dir}.img" "unpacked/original/${dir}.img"
+ fi
+ done
+}
+
+pack_images() {
+ for i in "${MNT_PARTITIONS[@]}"; do
+ if [ ! -f "unpacked/${i}.img" ]; then
+ make_erofs "$i" "${UNPACKED_DIR}"
+ echo "[+] Image 'unpacked/${i}.img' created"
+ else
+ echo "[?] Image 'unpacked/${i}.img' already exists"
+ fi
+ done
+
+ echo "[i] All images built"
+}
+
+apatch_patch_boot() {
+ local apatch_key=$1
+ local workdir="$TMP_DIR/root"
+ local previous_dir="$(pwd)"
+
+ cd "$workdir"
+
+ "$previous_dir"/utils/bin/kptools-linux unpack boot.img
+ "$previous_dir"/utils/bin/kptools-linux -p --image kernel --skey "$apatch_key" --kpimg "$previous_dir/utils/bin/kpimg-android" --out kernel
+ "$previous_dir"/utils/bin//kptools-linux repack boot.img
+
+ cd "$previous_dir"
+}
+
+vbmeta_add_hashtree() {
+ local partition="$1"
+ local properties=$(avbtool info_image --image ${UNPACKED_DIR}/original/${partition}.img | grep -E "Prop: com.android.build." | sed -e "s/[[:space:]]//g;s/Prop://g;s/->/:/g;s/^/--prop /g")
+ local cmd="avbtool add_hashtree_footer \
+ --image '$UNPACKED_DIR/${partition}.img' \
+ --partition_name $(sed -e "s/_a//g" <<< $partition) \
+ --block_size 4096 \
+ --hash_algorithm sha256 \
+ ${properties[@]} \
+ --key '$CUSTOM_AVB_KEY'"
+
+ echo -e "[i] Adding hashtree footer to $partition"
+
+ eval $cmd
+}
+
+make_vbmeta() {
+ local CUSTOM_AVB_KEY_PATH="${AVB_KEY_PATH/#\~/$HOME}"
+ local CUSTOM_AVB_KEY="$CUSTOM_AVB_KEY_PATH/driedlamu_rsa2048_private.pem"
+ local CUSTOM_AVB_KEY_PUB="$CUSTOM_AVB_KEY_PATH/driedlamu_rsa2048_public.pem"
+
+ local ORIGINAL_AVB_KEY_PATH="$TMP_DIR/vbmeta/keys/"
+
+ mkdir -p $TMP_DIR \
+ $TMP_DIR/vbmeta \
+ $TMP_DIR/vbmeta/keys
+
+ if [[ ! -f "$CUSTOM_AVB_KEY" ]]; then
+ echo "[i] Generating RSA2048 private key"
+
+ openssl genpkey -algorithm RSA \
+ -pkeyopt rsa_keygen_bits:2048 \
+ -outform PEM \
+ -out "$CUSTOM_AVB_KEY"
+ fi
+
+ if [[ ! -f "$CUSTOM_AVB_KEY_PUB" ]]; then
+ echo "[i] Extracting RSA2048 public key with AVBTool"
+
+ avbtool extract_public_key \
+ --key "$CUSTOM_AVB_KEY" \
+ --output "$CUSTOM_AVB_KEY_PUB"
+ fi
+
+ # While all keys are the same, It's not known whether Motorola is going to change
+ # them between partition.
+ dd if="$STOCK_FIRMWARE_PATH/vbmeta.img" of="$ORIGINAL_AVB_KEY_PATH/vbmeta_system_key.pem" bs=1 skip="681" count="520"
+ dd if="$STOCK_FIRMWARE_PATH/vbmeta.img" of="$ORIGINAL_AVB_KEY_PATH/vbmeta_vendor_key.pem" bs=1 skip="1313" count="520"
+ dd if="$STOCK_FIRMWARE_PATH/vbmeta.img" of="$ORIGINAL_AVB_KEY_PATH/vbmeta_unknown_key.pem" bs=1 skip="6080" count="520"
+
+ for i in "${MNT_PARTITIONS[@]}"; do
+ vbmeta_add_hashtree "$i"
+ done
+
+ echo -e "[i] Making vbmeta_system"
+
+ avbtool make_vbmeta_image \
+ --key "$CUSTOM_AVB_KEY" \
+ --algorithm 'SHA256_RSA2048' \
+ --flags 0 --padding_size '4096' \
+ --include_descriptors_from_image $UNPACKED_DIR/system_a.img \
+ --output "$TMP_DIR/vbmeta/vbmeta_system.img"
+
+ echo -e "[i] Making vbmeta"
+
+ avbtool make_vbmeta_image --key "$CUSTOM_AVB_KEY" --algorithm 'SHA256_RSA2048' --flags 0 \
+ --chain_partition vbmeta_system:2:"$CUSTOM_AVB_KEY_PUB" \
+ --chain_partition vbmeta_vendor:4:"$ORIGINAL_AVB_KEY_PATH/vbmeta_vendor_key.pem" \
+ --include_descriptors_from_image "$STOCK_FIRMWARE_PATH/boot.img" \
+ --include_descriptors_from_image "$STOCK_FIRMWARE_PATH/dtbo.img" \
+ --include_descriptors_from_image "$STOCK_FIRMWARE_PATH/init_boot.img" \
+ --include_descriptors_from_image "$STOCK_FIRMWARE_PATH/vendor_boot.img" \
+ --include_descriptors_from_image "$UNPACKED_DIR/odm_dlkm_a.img" \
+ --include_descriptors_from_image "$UNPACKED_DIR/product_a.img" \
+ --include_descriptors_from_image "$UNPACKED_DIR/system_dlkm_a.img" \
+ --include_descriptors_from_image "$UNPACKED_DIR/system_ext_a.img" \
+ --include_descriptors_from_image "$UNPACKED_DIR/vendor_dlkm_a.img" \
+ --output "$TMP_DIR/vbmeta/vbmeta.img"
+
+ echo -e "[i] VBMeta created"
+}
+
+make_super() {
+ local output_path="$1"
+ local size=0
+ local params=""
+
+ mkdir -p "$UNPACKED_DIR/sparse"
+
+ for file in `ls -1 $UNPACKED_DIR/*.img`; do
+ size=$(($size + $(stat -c %s $file)))
+ img2simg "$file" "$UNPACKED_DIR/sparse/$(basename $file)"
+ params+="--partition $(basename $file .img):readonly:$(stat -c %s $file):main_$(echo $(basename $file .img) | tail -c 2) "
+ if [[ $(stat -c %s $file) != 0 ]]; then
+ params+="--image $(basename $file .img)=${UNPACKED_DIR}/sparse/$(basename $file) "
+ fi
+ done
+
+ size=$(($size * 2))
+
+ local cmd="lpmake --metadata-size 65536 --metadata-slots 3 --block-size 4096 --virtual-ab --device super:$size --group main_a:$(($size - 2097152)) --group main_b:$(($size - 2097152)) "
+
+ cmd+="$params"
+ cmd+="--sparse --output $output_path/super.img"
+
+ eval $cmd
+}
+
+echo -e "[i] Prepare"
+
+# mkdir -p $FIRMWARE_OUT_DIR \
+# $TMP_DIR
+
+mkdir -p $TMP_DIR
+
+if [[ ! -f "./utils/bin/mkfs.erofs" && ! -f "./utils/bin/extract.erofs" ]]; then
+ echo -e "[i] Downloading erofs-utils"
+ prepare_erofs_utils
+fi
+
+if [[ $INSTALL_SU == 1 ]]; then
+ if [[ $SU_METHOD == "apatch" ]]; then
+ if [[ ! -f "./utils/bin/kpimg-android" && ! -f "./utils/bin/kptools-linux" ]]; then
+ echo -e "[i] Downloading APatch tools"
+ prepare_apatch_utils
+ fi
+ fi
+fi
+
+echo -e "[i] Stage 1"
+
+simg "${SUPER_IMAGE}" "${UNPACKED_DIR}"
+
+find ./res/* -type d -exec mkdir -p /tmp/driedlamu/{} \;
+find res/* -type f -exec ln -sf "$(pwd)/{}" /tmp/driedlamu/{} \;
+
+echo -e "[i] Stage 2\n"
+unpack_images "erofs"
+
+echo -e "[i] Running scripts"
+echo " "
+echo "[-] - Removed"
+echo "[+] - Added"
+echo "[=] - Modified"
+echo " "
+
+./scripts/bloatware/main.sh "$MNT_BASE"
+./scripts/props.sh "$MNT_BASE"
+./scripts/configs/main.sh "$MNT_BASE" "$TMP_DIR"
+./scripts/download_apks.sh "$TMP_DIR"
+./scripts/apk_obtain_permissions.sh "$TMP_DIR"
+
+if [[ $PRELOAD_MICROG == 1 ]]; then
+ ./scripts/microg.sh "$MNT_BASE" "$TMP_DIR"
+fi
+
+./scripts/install_apks.sh "$MNT_BASE" "$TMP_DIR/res"
+./scripts/permissions/main.sh "$MNT_BASE" "$TMP_DIR"
+
+if [[ $ADD_TONES == 1 ]]; then
+ ./scripts/add_media.sh "$MNT_BASE" "$TMP_DIR"
+fi
+
+echo -e "[i] Stage 3\n"
+pack_images
+
+if [[ $INSTALL_SU == 1 ]]; then
+ echo -e "[i] Installing superuser"
+ mkdir -p "$TMP_DIR/root"
+
+ cp -r "$STOCK_FIRMWARE_PATH/boot.img" "$TMP_DIR/root"
+
+ if [[ $SU_METHOD == "apatch" ]]; then
+ echo -e "[i] Patching with APatch"
+ apatch_patch_boot "$SU_PASSWORD"
+ cp -r "$TMP_DIR/root/new-boot.img" "$UNPACKED_DIR/boot_su.img"
+ fi
+fi
+
+if [[ $ENABLE_VBMETA == 1 ]]; then
+ echo -e "[i] Stage 4 (vbmeta)"
+
+ make_vbmeta
+ make_super "."
+fi
+
+echo -e "DriedLamu firmware was built!"