Skip to content

Commit 91f2a69

Browse files
committed
extensions/mtkflash: Mediatek mtk-flash direct flashing after build
- similar to `rkdevflash`, but for Mediatek devices - also simpler; lk.bin & fip.img are produced by image build and directly used - requires Rust+Cargo, so add those to hostdeps - since this is a core extension, those will be included in all Docker images too - which was bound to happen anyway since Rust in Linux Kernel is no longer an experiment - example invocation: - `BOARD=radxa-nio-12l BRANCH=collabora RELEASE=trixie EXT=ufs,mtkflash MTKFLASH_TTYACM_DEVICE=1`
1 parent 2859e35 commit 91f2a69

1 file changed

Lines changed: 132 additions & 0 deletions

File tree

extensions/mtkflash.sh

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#
2+
# SPDX-License-Identifier: GPL-2.0
3+
# Copyright (c) 2026 Ricardo Pardini <ricardo@pardini.net>
4+
# This file is a part of the Armbian Build Framework https://github.com/armbian/build/
5+
#
6+
7+
# This adds the required host-side dependencies, clones and builds mtk-flash.
8+
# mtk-flash is a rust application, so the rust toolchain is required.
9+
# When build is done, it flashes the device with the produced lk.bin/fip.img and disk image.
10+
# Mediatek devices show up as ttyACMx devices when in flashing mode.
11+
# Some common UART devices and modems might _also_ use ttyACMx.
12+
# If you can predict which ttyACMx to use for flashing, pass it via eg MTKFLASH_TTYACM_DEVICE=1
13+
# otherwise MTKFLASH_TTYACM_DEVICE=0 is used by default.
14+
15+
function add_host_dependencies__mtkflash() {
16+
display_alert "Preparing mtkflash host-side dependencies" "${EXTENSION}" "info"
17+
declare -g EXTRA_BUILD_DEPS="${EXTRA_BUILD_DEPS} rustc cargo build-essential" # @TODO: convert to array later
18+
}
19+
20+
function extension_finish_config__900_mtkflash() {
21+
display_alert "Preparing mtkflash extension" "${EXTENSION}" "info"
22+
declare -g -r mtkflash_dir="${SRC}/cache/sources/mtk-flash"
23+
declare -g -r mtkflash_bin_path="${mtkflash_dir}/target/release/mtk-flash"
24+
25+
# if under docker, exit_with_error; we can't get at the USB needed.
26+
if [[ "${ARMBIAN_RUNNING_IN_CONTAINER}" == "yes" ]]; then
27+
exit_with_error "mtkflash: running under Docker is not supported. it requires direct access to the host USB devices."
28+
fi
29+
}
30+
31+
function host_dependencies_ready__mtkflash() {
32+
display_alert "Preparing mtkflash for usage" "${EXTENSION}" "info"
33+
34+
if [[ ! -f "${mtkflash_bin_path}" ]]; then
35+
display_alert "mtkflash not found, building it" "${EXTENSION}" "info"
36+
build_mtkflash
37+
fi
38+
39+
check_mtkflash # logs the version of mtkflash
40+
}
41+
42+
# post_build_image_write hooks are called in logging context, which is not so great for interactive flashing tools.
43+
# we probably should introduce a different hook that runs outside logging context for such tools.
44+
function post_build_image_write__mtkflash() {
45+
: "${built_image_file:?built_image_file is not set}" # check built_image_file is set
46+
display_alert "Starting mtk-flash flashing process" "${EXTENSION} :: ${built_image_file}" "info"
47+
48+
# Check the built image file exists
49+
if [[ ! -f "${built_image_file}" ]]; then
50+
exit_with_error "mtkflash: Built image file not found: '${built_image_file}'"
51+
fi
52+
53+
# We also need the lk.bin and fip.img file. Obtain their names by replacing the image file extension '.img' with '.lk.bin' and '.fip.img'
54+
declare lk_bin_file="${built_image_file%.img}.lk.bin"
55+
declare fip_img_file="${built_image_file%.img}.fip.img"
56+
if [[ ! -f "${lk_bin_file}" ]]; then
57+
exit_with_error "mtkflash: LK binary file not found: '${lk_bin_file}'"
58+
fi
59+
if [[ ! -f "${fip_img_file}" ]]; then
60+
exit_with_error "mtkflash: FIP image file not found: '${fip_img_file}'"
61+
fi
62+
63+
# Handle the ttyACMx device selection via MTKFLASH_TTYACM_DEVICE environment variable.
64+
# Default to 0 if not set; user can override it.
65+
# If user-set MTKFLASH_TTYACM_DEVICE begins with a slash, use it as full device path.
66+
# Otherwise assume it's a number and append to /dev/ttyACM.
67+
declare mtkflash_device_path="/dev/ttyACM0"
68+
if [[ -n "${MTKFLASH_TTYACM_DEVICE:-""}" ]]; then
69+
if [[ "${MTKFLASH_TTYACM_DEVICE}" == /* ]]; then
70+
mtkflash_device_path="${MTKFLASH_TTYACM_DEVICE}"
71+
else
72+
mtkflash_device_path="/dev/ttyACM${MTKFLASH_TTYACM_DEVICE}"
73+
fi
74+
fi
75+
76+
declare -a mtkflash_cmd_args=()
77+
78+
display_alert "mtk-flash flashing disk image file" "${built_image_file}" "info"
79+
mtkflash_cmd_args+=("--img" "${built_image_file}")
80+
display_alert "mtk-flash flashing LK binary file" "${lk_bin_file}" "info"
81+
mtkflash_cmd_args+=("--da" "${lk_bin_file}")
82+
display_alert "mtk-flash flashing FIP image file" "${fip_img_file}" "info"
83+
mtkflash_cmd_args+=("--fip" "${fip_img_file}")
84+
85+
display_alert "mtk-flash using ttyACM device" "${mtkflash_device_path} (customize with MTKFLASH_TTYACM_DEVICE if needed)" "info"
86+
mtkflash_cmd_args+=("--dev" "${mtkflash_device_path}")
87+
88+
display_alert "mtk-flash command line" "${mtkflash_bin_path} ${mtkflash_cmd_args[*]@Q}" "debug"
89+
90+
# Since I hit this before: if the device exists at this stage, it's very likely a conflict with some modem or UART.
91+
# The device should only appear when user puts the board in flashing mode, not before.
92+
# If the mtkflash_device_path exists, and is a character device, warn the user to use MTKFLASH_TTYACM_DEVICE.
93+
if [[ -c "${mtkflash_device_path}" ]]; then
94+
display_alert "Warning: mtkflash device '${mtkflash_device_path}' already exists before you were asked to set the board to flashing mode." "${EXTENSION}" "warn"
95+
display_alert "This may indicate a conflict with some modem or UART device using a ttyACMx device." "${EXTENSION}" "warn"
96+
display_alert "Ensure you have the correct device path set via MTKFLASH_TTYACM_DEVICE environment variable." "${EXTENSION}" "warn"
97+
else
98+
display_alert "mtkflash device '${mtkflash_device_path}' (correctly) does not exist - hopefully it will show up when board is put in flashing mode." "${EXTENSION}" "info"
99+
fi
100+
101+
# let user know to put the device in flashing mode
102+
display_alert "NOW! is the time to put the Mediatek board in flashing mode" "${EXTENSION}" "ext"
103+
104+
# finally run mtk-flash with the accumulated arguments
105+
"${mtkflash_bin_path}" "${mtkflash_cmd_args[@]}"
106+
}
107+
108+
function build_mtkflash() {
109+
# Clone mtkflash
110+
fetch_from_repo "https://github.com/grinn-global/mtk-flash.git" "mtk-flash" "commit:2aa9ce8a0398a5ea67180df9178b0725de9ce259"
111+
112+
# Build mtkflash
113+
pushd "${mtkflash_dir}" &> /dev/null || exit_with_error "Fail to cd to mtkflash: ${mtkflash_dir}"
114+
115+
run_host_command_logged pipetty cargo build --release
116+
run_host_command_logged pipetty ls -la "${mtkflash_bin_path}"
117+
118+
popd &> /dev/null || exit_with_error "Fail to cd back to armbian-build"
119+
}
120+
121+
function check_mtkflash() {
122+
declare mtkflash_version="undetermined"
123+
mtkflash_version="$("${mtkflash_bin_path}" --version)"
124+
display_alert "mtkflash version" "${EXTENSION} :: '${mtkflash_version}'" ""
125+
126+
# as a courtesy to the user, install a symlink into /usr/local/bin, so mtk-flash can be called by itself as well
127+
# either way never fail due to this
128+
if [[ -f /usr/local/bin/mtk-flash ]]; then
129+
run_host_command_logged rm -f /usr/local/bin/mtk-flash || true
130+
fi
131+
run_host_command_logged sudo ln -sf "${mtkflash_bin_path}" /usr/local/bin/mtk-flash || true
132+
}

0 commit comments

Comments
 (0)