forked from armbian/build
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathnuvoton-ma35d1.conf
More file actions
275 lines (215 loc) · 10.1 KB
/
Copy pathnuvoton-ma35d1.conf
File metadata and controls
275 lines (215 loc) · 10.1 KB
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
#
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (c) 2013-2026 Igor Pecovnik, igor@armbian.com
#
# This file is a part of the Armbian Build Framework
# https://github.com/armbian/build/
#
# Nuvoton MA35D1 SoC family - ARM Cortex-A35 dual-core + Cortex-M4
# Boot flow: Mask ROM (IBR) -> BL2 (TF-A) -> BL31 -> BL32 (OP-TEE) -> BL33 (U-Boot) -> Linux
declare -g ARCH="arm64"
# Disable BTF - 5.10.y kernel has issues with newer pahole/toolchain
declare -g KERNEL_BTF="no"
# Use NetworkManager for network configuration
declare -g NETWORKING_STACK="network-manager"
declare -g ATF_PLAT="ma35d1"
declare -g BOOTDELAY=1
declare -g BOOTPATCHDIR="u-boot-nuvoton-ma35d1"
# U-Boot source from Nuvoton
declare -g BOOTSOURCE='https://github.com/OpenNuvoton/MA35D1_u-boot-v2020.07.git'
declare -g BOOTBRANCH='branch:master'
declare -g BOOTDIR='u-boot-nuvoton-ma35d1'
declare -g UBOOT_TARGET_MAP=";;u-boot.bin header.bin fip.bin bl2.bin bl31.bin bl2-ma35d1.dtb tee-header_v2.bin tee-pager_v2.bin"
# TF-A source from Nuvoton
declare -g ATFSOURCE="https://github.com/OpenNuvoton/MA35D1_arm-trusted-firmware-v2.3.git"
declare -g ATFDIR="arm-trusted-firmware-ma35d1"
declare -g ATFBRANCH="branch:master"
declare -g ATFPATCHDIR="atf-nuvoton-ma35d1"
declare -g ATF_SKIP_LDFLAGS_WL="yes"
# DDR configuration DTB - 512MB for IoT board
MA35D1_DDR_DTB="${MA35D1_DDR_DTB:-ma35d1-cpu800-wb-512m}"
# TF-A build: BL2 + BL31 + DTB (FIP is created later in uboot_custom_postprocess)
declare -g ATF_TARGET_MAP="PLAT=ma35d1 DEBUG=1 DTB_FILE_NAME=${MA35D1_DDR_DTB}.dtb bl2 bl31 dtbs;;build/ma35d1/debug/bl2.bin build/ma35d1/debug/bl31.bin build/ma35d1/debug/fdts/${MA35D1_DDR_DTB}.dtb:bl2-ma35d1.dtb"
declare -g LINUXFAMILY="nuvoton-ma35d1"
declare -g IMAGE_PARTITION_TABLE="msdos"
# Boot script for loading kernel/initrd/dtb from partition
declare -g BOOTSCRIPT="boot-nuvoton-ma35d1.cmd:boot.cmd"
declare -g BOOTENV_FILE="nuvoton-ma35d1.txt"
case "${BRANCH}" in
vendor)
declare -g KERNEL_MAJOR_MINOR="5.10"
declare -g KERNELSOURCE='https://github.com/OpenNuvoton/MA35D1_linux-5.10.y.git'
declare -g KERNELBRANCH="branch:master"
declare -g KERNELPATCHDIR="nuvoton-ma35d1-${BRANCH}"
declare -g LINUXCONFIG="linux-nuvoton-ma35d1-${BRANCH}"
;;
esac
declare -g KERNEL_TARGET="vendor"
declare -g CPUMIN=180000
declare -g CPUMAX=800000
declare -g GOVERNOR="ondemand"
# Host dependencies for OP-TEE build
function add_host_dependencies__ma35d1_optee_deps() {
display_alert "Adding MA35D1 OP-TEE host dependencies" "python3-pycryptodome python3-pyelftools" "info"
declare -g EXTRA_BUILD_DEPS="${EXTRA_BUILD_DEPS} python3-pycryptodome python3-pyelftools"
}
# Fetch OP-TEE source using Armbian's fetch_from_repo mechanism
function fetch_sources_tools__ma35d1_fetch_optee() {
local optee_source="https://github.com/OpenNuvoton/MA35D1_optee_os-v3.9.0.git"
local optee_dir="optee-os-ma35d1"
local optee_branch="branch:master"
display_alert "Fetching OP-TEE source" "for MA35D1" "info"
fetch_from_repo "${optee_source}" "${optee_dir}" "${optee_branch}"
}
# ATF post-processing: verify build outputs and build fiptool
function atf_custom_postprocess() {
display_alert "Post-processing ATF" "MA35D1" "info"
local atf_src_dir="$(pwd)"
local atf_build_dir="${atf_src_dir}/build/ma35d1/debug"
if [[ ! -d "${atf_build_dir}" ]]; then
exit_with_error "ATF build directory not found: ${atf_build_dir}"
fi
# Verify required files
[[ -f "${atf_build_dir}/bl2.bin" ]] || exit_with_error "bl2.bin not found in ${atf_build_dir}"
[[ -f "${atf_build_dir}/bl31.bin" ]] || exit_with_error "bl31.bin not found in ${atf_build_dir}"
[[ -f "${atf_build_dir}/fdts/${MA35D1_DDR_DTB}.dtb" ]] || exit_with_error "DTB ${MA35D1_DDR_DTB}.dtb not found"
# Build fiptool for use in uboot_custom_postprocess
display_alert "Building fiptool" "MA35D1" "info"
run_host_command_logged make -C "${atf_src_dir}/tools/fiptool" HOSTCC=gcc
[[ -x "${atf_src_dir}/tools/fiptool/fiptool" ]] || exit_with_error "fiptool build failed"
display_alert "ATF post-processing complete" "bl2.bin + bl31.bin + fiptool ready" "info"
}
# Post-process U-Boot: create FIP and Nuvoton boot header
function uboot_custom_postprocess() {
# Compile OP-TEE for MA35D1 (defined inside for correct hashing)
function compile_optee_ma35d1() {
local optee_src_dir="${SRC}/cache/sources/optee-os-ma35d1"
local optee_out_dir="${optee_src_dir}/out/arm-plat-nuvoton/core"
display_alert "Compiling OP-TEE" "MA35D1" "info"
[[ -d "${optee_src_dir}" ]] || exit_with_error "OP-TEE source not found at ${optee_src_dir}"
local cross_compile="aarch64-linux-gnu-"
run_host_command_logged make -C "${optee_src_dir}" clean PLATFORM=nuvoton-MA35D1 2>/dev/null || true
display_alert "Building OP-TEE" "PLATFORM=nuvoton-MA35D1" "info"
run_host_command_logged make -C "${optee_src_dir}" \
CROSS_COMPILE_core="${cross_compile}" \
CROSS_COMPILE_ta_arm64="${cross_compile}" \
PLATFORM=nuvoton-MA35D1 \
CFG_ARM64_core=y \
CFG_TEE_CORE_LOG_LEVEL=1 \
LDFLAGS="--no-warn-rwx-segments" \
NOWERROR=1 \
-j$(nproc)
[[ -f "${optee_out_dir}/tee-header_v2.bin" ]] || exit_with_error "OP-TEE build failed: tee-header_v2.bin not found"
[[ -f "${optee_out_dir}/tee-pager_v2.bin" ]] || exit_with_error "OP-TEE build failed: tee-pager_v2.bin not found"
display_alert "OP-TEE built successfully" "MA35D1" "info"
}
display_alert "Creating MA35D1 boot images" "BL2 + OP-TEE + FIP + Header" "info"
local atf_dir="${SRC}/cache/sources/${ATFDIR}/${ATFBRANCH##*:}"
local atf_build_dir="${atf_dir}/build/ma35d1/debug"
local fiptool="${atf_dir}/tools/fiptool/fiptool"
# Verify fiptool exists (built in atf_custom_postprocess)
[[ -x "${fiptool}" ]] || exit_with_error "fiptool not found at ${fiptool}"
# Copy DTB from ATF build if not already present
if [[ ! -f "bl2-ma35d1.dtb" ]] && [[ -f "${atf_build_dir}/fdts/${MA35D1_DDR_DTB}.dtb" ]]; then
cp "${atf_build_dir}/fdts/${MA35D1_DDR_DTB}.dtb" "bl2-ma35d1.dtb"
fi
# Verify required files
[[ -f "bl2.bin" ]] || exit_with_error "bl2.bin not found"
[[ -f "bl31.bin" ]] || exit_with_error "bl31.bin not found"
[[ -f "bl2-ma35d1.dtb" ]] || exit_with_error "bl2-ma35d1.dtb not found"
# Build OP-TEE
compile_optee_ma35d1
# Copy OP-TEE binaries
local optee_out_dir="${SRC}/cache/sources/optee-os-ma35d1/out/arm-plat-nuvoton/core"
cp "${optee_out_dir}/tee-header_v2.bin" .
cp "${optee_out_dir}/tee-pager_v2.bin" .
# Create FIP
display_alert "Creating FIP" "bl31 + optee + u-boot" "info"
run_host_command_logged "${fiptool}" create \
--soc-fw bl31.bin \
--tos-fw tee-header_v2.bin \
--tos-fw-extra1 tee-pager_v2.bin \
--nt-fw u-boot.bin \
fip.bin
# Create Nuvoton boot header for SD card boot
display_alert "Creating Nuvoton boot header" "SD card" "info"
python3 <<- 'HEADER_SCRIPT'
import struct
import os
import binascii
HEADER_VERSION = 0x20210107
BL2_ENTRY = 0x28000000
BL2_DTB_LOAD = 0x28023000
BL2_LOAD = 0x28000000
IMG_TYPE_DATA = 3
IMG_TYPE_EXEC = 4
dtb_offset = 0x20000
bl2_offset = 0x30000
bl2_size = os.path.getsize('bl2.bin')
dtb_size = os.path.getsize('bl2-ma35d1.dtb') if os.path.exists('bl2-ma35d1.dtb') else 0
header = bytearray(512)
struct.pack_into('<I', header, 0, 0x4E565420)
struct.pack_into('<I', header, 8, 0xC0)
struct.pack_into('<I', header, 12, HEADER_VERSION)
struct.pack_into('<H', header, 16, 2048)
struct.pack_into('<H', header, 18, 64)
struct.pack_into('<H', header, 20, 64)
struct.pack_into('<B', header, 22, 0x6B)
struct.pack_into('<B', header, 23, 0x05)
struct.pack_into('<B', header, 24, 0x01)
struct.pack_into('<B', header, 25, 0x02)
struct.pack_into('<B', header, 26, 0)
struct.pack_into('<B', header, 27, 1)
struct.pack_into('<B', header, 28, 1)
for i in range(29, 32):
header[i] = 0xFF
struct.pack_into('<I', header, 32, BL2_ENTRY)
struct.pack_into('<I', header, 36, 2)
desc_offset = 40
DESC_SIZE = 80
struct.pack_into('<I', header, desc_offset + 0, dtb_offset)
struct.pack_into('<I', header, desc_offset + 4, BL2_DTB_LOAD)
struct.pack_into('<I', header, desc_offset + 8, dtb_size)
struct.pack_into('<I', header, desc_offset + 12, IMG_TYPE_DATA)
for i in range(desc_offset + 16, desc_offset + DESC_SIZE):
header[i] = 0xFF
desc_offset += DESC_SIZE
struct.pack_into('<I', header, desc_offset + 0, bl2_offset)
struct.pack_into('<I', header, desc_offset + 4, BL2_LOAD)
struct.pack_into('<I', header, desc_offset + 8, bl2_size)
struct.pack_into('<I', header, desc_offset + 12, IMG_TYPE_EXEC)
for i in range(desc_offset + 16, desc_offset + DESC_SIZE):
header[i] = 0xFF
total_header_size = 200
checksum = binascii.crc32(header[8:total_header_size]) & 0xFFFFFFFF
struct.pack_into('<I', header, 4, checksum)
with open('header.bin', 'wb') as f:
f.write(header[:total_header_size])
print(f"Header created: {total_header_size} bytes, CRC=0x{checksum:08x}")
HEADER_SCRIPT
[[ -f "header.bin" ]] || exit_with_error "Failed to create boot header"
display_alert "MA35D1 boot images created" "header.bin + bl2.bin + fip.bin" "info"
}
# Write bootloader to SD card/image
# Note: This only works during image creation, not on target board
function write_uboot_platform() {
local src_dir="$1"
local target_dev="$2"
local header_bin="${src_dir}/header.bin"
local bl2_dtb_bin="${src_dir}/bl2-ma35d1.dtb"
local bl2_bin="${src_dir}/bl2.bin"
local fip_bin="${src_dir}/fip.bin"
[[ -f "${header_bin}" ]] || { echo "Missing header.bin"; return 1; }
[[ -f "${bl2_bin}" ]] || { echo "Missing bl2.bin"; return 1; }
[[ -f "${fip_bin}" ]] || { echo "Missing fip.bin"; return 1; }
# Write header at 1KB and 1.5KB offsets (sectors 2 and 3)
dd if="${header_bin}" of="${target_dev}" bs=512 seek=2 conv=notrunc status=none
dd if="${header_bin}" of="${target_dev}" bs=512 seek=3 conv=notrunc status=none
# Write DTB at 128KB offset (0x20000)
[[ -f "${bl2_dtb_bin}" ]] && dd if="${bl2_dtb_bin}" of="${target_dev}" bs=1024 seek=128 conv=notrunc status=none
# Write BL2 at 192KB offset (0x30000)
dd if="${bl2_bin}" of="${target_dev}" bs=1024 seek=192 conv=notrunc status=none
# Write FIP at 768KB offset (0xC0000)
dd if="${fip_bin}" of="${target_dev}" bs=1024 seek=768 conv=notrunc status=none
}