hlleng commited on
Commit
497dfd9
·
verified ·
1 Parent(s): 9f07ad2

Upload tools/cmm-os-mem-config.sh

Browse files
Files changed (1) hide show
  1. sdk/tools/cmm-os-mem-config.sh +404 -0
sdk/tools/cmm-os-mem-config.sh ADDED
@@ -0,0 +1,404 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+ # Extend the AX650 OS MEM and CMM memory layout.
3
+ # Changes to U-Boot bootargs take effect only after a reboot.
4
+
5
+ set -u
6
+
7
+ MIN_OS_MEM_MIB=512
8
+ BACKUP_FILE=/root/cmm-os-mem-config.bootargs.bak
9
+ AUTO_LOAD_SCRIPT=/soc/scripts/auto_load_all_drv.sh
10
+ AUTO_LOAD_BACKUP_FILE=/root/cmm-os-mem-config.auto_load_all_drv.sh.bak
11
+ FW_ENV_CONFIG_FILE=/etc/fw_env.config
12
+ FW_ENV_CONFIG_BACKUP_FILE=/root/cmm-os-mem-config.fw_env.config.bak
13
+ FW_ENV_CONFIG_LINE='/dev/mmcblk0p3 0x0000 0x20000 0x100'
14
+ LINUX_PHYS_BASE_MIB=4096
15
+ EXPANDED_TOTAL_MIB=8192
16
+ LEGACY_REPORTED_TOTAL_MIB=6144
17
+ MODE=
18
+ TARGET_MIB=
19
+ TOTAL_OVERRIDE_MIB=
20
+ ASSUME_YES=0
21
+ INIT_FW_ENV=0
22
+ ALLOW_FW_ENV_INIT=0
23
+ EXPANDED_LAYOUT_DETECTED=0
24
+
25
+ die() {
26
+ printf 'Error: %s\n' "$*" >&2
27
+ exit 1
28
+ }
29
+
30
+ usage() {
31
+ cat <<'EOF'
32
+ Usage:
33
+ cmm-os-mem-config.sh Extend memory interactively
34
+ cmm-os-mem-config.sh --show Show the current split
35
+ cmm-os-mem-config.sh --os-mem MiB [opts] Set OS MEM
36
+ cmm-os-mem-config.sh --cmm MiB [opts] Set CMM
37
+ cmm-os-mem-config.sh --init-fw-env Initialize fw_env.config for this board
38
+
39
+ Options:
40
+ --total-mem MiB Specify total physical memory when auto-detection fails
41
+ --init-fw-env Create or replace /etc/fw_env.config with the board default
42
+ --yes Skip confirmations; valid only with a write or init option
43
+ -h, --help Show this help text
44
+
45
+ Examples:
46
+ cmm-os-mem-config.sh --show
47
+ cmm-os-mem-config.sh --init-fw-env
48
+ cmm-os-mem-config.sh --cmm 4096
49
+ cmm-os-mem-config.sh --os-mem 6144 --yes
50
+ cmm-os-mem-config.sh --cmm 4096 --total-mem 8192
51
+
52
+ OS MEM maps to the mem= bootargs value.
53
+ CMM maps to the ax_cmm.ko cmmpool value in /soc/scripts/auto_load_all_drv.sh.
54
+ After a successful write, run reboot manually. This script never reboots automatically.
55
+ EOF
56
+ }
57
+
58
+ is_nonnegative_integer() {
59
+ case "$1" in
60
+ ''|*[!0-9]*) return 1 ;;
61
+ *) return 0 ;;
62
+ esac
63
+ }
64
+
65
+ read_bootargs() {
66
+ command -v fw_printenv >/dev/null 2>&1 || die 'fw_printenv was not found, please install libubootenv-tool'
67
+ if ! BOOTARGS=$(fw_printenv -n bootargs 2>&1); then
68
+ FW_PRINTENV_ERROR=$BOOTARGS
69
+ if [ "$INIT_FW_ENV" -eq 1 ] || [ "$ALLOW_FW_ENV_INIT" -eq 1 ]; then
70
+ init_fw_env_config
71
+ BOOTARGS=$(fw_printenv -n bootargs 2>/dev/null) || die 'Failed to read U-Boot bootargs after initializing /etc/fw_env.config.'
72
+ else
73
+ explain_bootargs_read_failure "$FW_PRINTENV_ERROR"
74
+ exit 1
75
+ fi
76
+ fi
77
+ CURRENT_OS_MIB=$(printf '%s\n' "$BOOTARGS" | sed -n 's/.*mem=\([0-9][0-9]*\)M.*/\1/p')
78
+ is_nonnegative_integer "$CURRENT_OS_MIB" || die 'No valid mem=<MiB>M parameter was found in bootargs.'
79
+ }
80
+
81
+ explain_bootargs_read_failure() {
82
+ printf 'Error: Failed to read U-Boot bootargs.\n' >&2
83
+ if [ -n "$1" ]; then
84
+ printf 'fw_printenv output: %s\n' "$1" >&2
85
+ fi
86
+ if [ ! -s "$FW_ENV_CONFIG_FILE" ]; then
87
+ printf '%s is missing or empty.\n' "$FW_ENV_CONFIG_FILE" >&2
88
+ elif grep -Fqx "$FW_ENV_CONFIG_LINE" "$FW_ENV_CONFIG_FILE"; then
89
+ printf '%s already contains the expected board default, but fw_printenv still failed.\n' "$FW_ENV_CONFIG_FILE" >&2
90
+ else
91
+ printf '%s exists but does not contain the expected board default.\n' "$FW_ENV_CONFIG_FILE" >&2
92
+ fi
93
+ printf 'This board usually needs:\n %s\n' "$FW_ENV_CONFIG_LINE" >&2
94
+ printf 'Run this script with --init-fw-env to create it, or update %s manually.\n' "$FW_ENV_CONFIG_FILE" >&2
95
+ }
96
+
97
+ confirm_fw_env_init() {
98
+ if [ "$ASSUME_YES" -eq 1 ]; then
99
+ return
100
+ fi
101
+
102
+ [ -t 0 ] || die 'Cannot initialize /etc/fw_env.config without a terminal. Re-run with --init-fw-env --yes.'
103
+ printf 'Initialize %s with "%s"? [y/N] ' "$FW_ENV_CONFIG_FILE" "$FW_ENV_CONFIG_LINE"
104
+ read -r ANSWER || exit 1
105
+ case "$ANSWER" in
106
+ y|Y|yes|YES) ;;
107
+ *) printf 'Cancelled. No configuration was changed.\n'; exit 0 ;;
108
+ esac
109
+ }
110
+
111
+ init_fw_env_config() {
112
+ [ -b /dev/mmcblk0p3 ] || die 'Expected block device /dev/mmcblk0p3 was not found.'
113
+
114
+ if [ -s "$FW_ENV_CONFIG_FILE" ] && grep -Fqx "$FW_ENV_CONFIG_LINE" "$FW_ENV_CONFIG_FILE"; then
115
+ printf '%s already contains the board default.\n' "$FW_ENV_CONFIG_FILE"
116
+ return
117
+ fi
118
+
119
+ if [ -e "$FW_ENV_CONFIG_FILE" ]; then
120
+ printf '%s exists and will be backed up to %s before replacement.\n' "$FW_ENV_CONFIG_FILE" "$FW_ENV_CONFIG_BACKUP_FILE"
121
+ fi
122
+ confirm_fw_env_init
123
+
124
+ umask 077
125
+ if [ -e "$FW_ENV_CONFIG_FILE" ]; then
126
+ cp -p "$FW_ENV_CONFIG_FILE" "$FW_ENV_CONFIG_BACKUP_FILE" || die "Cannot back up ${FW_ENV_CONFIG_FILE}."
127
+ fi
128
+ printf '%s\n' "$FW_ENV_CONFIG_LINE" > "${FW_ENV_CONFIG_FILE}.tmp" || die "Cannot create ${FW_ENV_CONFIG_FILE}.tmp."
129
+ chmod 0644 "${FW_ENV_CONFIG_FILE}.tmp" || die "Cannot chmod ${FW_ENV_CONFIG_FILE}.tmp."
130
+ mv "${FW_ENV_CONFIG_FILE}.tmp" "$FW_ENV_CONFIG_FILE" || die "Cannot save ${FW_ENV_CONFIG_FILE}."
131
+ sync
132
+
133
+ printf 'Initialized %s.\n' "$FW_ENV_CONFIG_FILE"
134
+ }
135
+
136
+ read_current_cmm() {
137
+ CURRENT_CMM_MIB=
138
+ CURRENT_AUTO_LOAD_CMM_BASE=
139
+ CURRENT_AUTO_LOAD_CMM_MIB=
140
+
141
+ if [ -r "$AUTO_LOAD_SCRIPT" ]; then
142
+ CURRENT_AUTO_LOAD_CMM_BASE=$(sed -n 's/.*cmmpool=anonymous,0,\(0x[0-9A-Fa-f][0-9A-Fa-f]*\),[0-9][0-9]*M.*/\1/p' "$AUTO_LOAD_SCRIPT" | sed -n '1p')
143
+ CURRENT_AUTO_LOAD_CMM_MIB=$(sed -n 's/.*cmmpool=anonymous,0,0x[0-9A-Fa-f][0-9A-Fa-f]*,\([0-9][0-9]*\)M.*/\1/p' "$AUTO_LOAD_SCRIPT" | sed -n '1p')
144
+ fi
145
+
146
+ if is_nonnegative_integer "$CURRENT_AUTO_LOAD_CMM_MIB"; then
147
+ CURRENT_CMM_MIB=$CURRENT_AUTO_LOAD_CMM_MIB
148
+ elif [ -r /proc/ax_proc/mem_cmm_info ]; then
149
+ CURRENT_CMM_MIB=$(sed -n 's/.*Size=[0-9][0-9]*KB(\([0-9][0-9]*\)MB).*/\1/p' /proc/ax_proc/mem_cmm_info | awk '{sum += $1} END {if (NR > 0) print sum}')
150
+ fi
151
+ }
152
+
153
+ cmm_base_for_os_mib() {
154
+ printf '0x%X\n' $(((LINUX_PHYS_BASE_MIB + $1) * 1024 * 1024))
155
+ }
156
+
157
+ detect_expanded_memory_layout() {
158
+ EXPANDED_LAYOUT_DETECTED=0
159
+ if is_nonnegative_integer "$CURRENT_CMM_MIB"; then
160
+ CURRENT_REPORTED_TOTAL_MIB=$((CURRENT_OS_MIB + CURRENT_CMM_MIB))
161
+ if [ "$CURRENT_REPORTED_TOTAL_MIB" -eq "$LEGACY_REPORTED_TOTAL_MIB" ]; then
162
+ EXPANDED_LAYOUT_DETECTED=1
163
+ fi
164
+ fi
165
+ }
166
+
167
+ determine_total_memory() {
168
+ if [ "$EXPANDED_LAYOUT_DETECTED" -eq 1 ]; then
169
+ if [ -n "$TOTAL_OVERRIDE_MIB" ] && [ "$TOTAL_OVERRIDE_MIB" -ne "$EXPANDED_TOTAL_MIB" ]; then
170
+ die "This memory layout requires --total-mem ${EXPANDED_TOTAL_MIB} or omitted."
171
+ fi
172
+ TOTAL_MIB=$EXPANDED_TOTAL_MIB
173
+ return
174
+ fi
175
+
176
+ if [ -n "$TOTAL_OVERRIDE_MIB" ]; then
177
+ TOTAL_MIB=$TOTAL_OVERRIDE_MIB
178
+ return
179
+ fi
180
+
181
+ if is_nonnegative_integer "$CURRENT_CMM_MIB"; then
182
+ TOTAL_MIB=$((CURRENT_OS_MIB + CURRENT_CMM_MIB))
183
+ return
184
+ fi
185
+
186
+ die 'Unable to detect total physical memory. Add --total-mem MiB, for example --total-mem 8192.'
187
+ }
188
+
189
+ show_status() {
190
+ printf 'Current OS MEM: %s MiB\n' "$CURRENT_OS_MIB"
191
+ if is_nonnegative_integer "$CURRENT_CMM_MIB"; then
192
+ printf 'Current CMM: %s MiB\n' "$CURRENT_CMM_MIB"
193
+ else
194
+ printf 'Current CMM: unavailable from /proc/ax_proc/mem_cmm_info\n'
195
+ fi
196
+ if [ -n "$CURRENT_AUTO_LOAD_CMM_BASE" ]; then
197
+ printf 'Current CMM base in auto_load script: %s\n' "$CURRENT_AUTO_LOAD_CMM_BASE"
198
+ fi
199
+ if [ -n "${TOTAL_MIB:-}" ]; then
200
+ printf 'Total physical memory: %s MiB\n' "$TOTAL_MIB"
201
+ fi
202
+ }
203
+
204
+ confirm_write() {
205
+ if [ "$ASSUME_YES" -eq 1 ]; then
206
+ return
207
+ fi
208
+
209
+ printf 'Set OS MEM=%s MiB and CMM=%s MiB; changes apply after reboot. Continue? [y/N] ' "$NEW_OS_MIB" "$NEW_CMM_MIB"
210
+ read -r ANSWER || exit 1
211
+ case "$ANSWER" in
212
+ y|Y|yes|YES) ;;
213
+ *) printf 'Cancelled. No configuration was changed.\n'; exit 0 ;;
214
+ esac
215
+ }
216
+
217
+ confirm_total_memory() {
218
+ if [ "$ASSUME_YES" -eq 1 ]; then
219
+ return
220
+ fi
221
+
222
+ if [ "$EXPANDED_LAYOUT_DETECTED" -eq 1 ]; then
223
+ return
224
+ fi
225
+
226
+ printf 'Detected total physical memory: %s MiB. Continue with this value? [y/N] ' "$TOTAL_MIB"
227
+ read -r ANSWER || exit 1
228
+ case "$ANSWER" in
229
+ y|Y|yes|YES) ;;
230
+ *) printf 'Cancelled. No configuration was changed.\n'; exit 0 ;;
231
+ esac
232
+ }
233
+
234
+ check_write_targets() {
235
+ command -v fw_setenv >/dev/null 2>&1 || die 'fw_setenv was not found.'
236
+ [ -r "$AUTO_LOAD_SCRIPT" ] || die "${AUTO_LOAD_SCRIPT} was not found or is not readable."
237
+ [ -w "$AUTO_LOAD_SCRIPT" ] || die "${AUTO_LOAD_SCRIPT} is not writable."
238
+ AUTO_LOAD_CMM_FOUND=$(sed -n 's/.*cmmpool=anonymous,0,0x[0-9A-Fa-f][0-9A-Fa-f]*,[0-9][0-9]*M.*/yes/p' "$AUTO_LOAD_SCRIPT" | sed -n '1p')
239
+ [ -n "$AUTO_LOAD_CMM_FOUND" ] || die "No ax_cmm.ko cmmpool parameter was found in ${AUTO_LOAD_SCRIPT}."
240
+ }
241
+
242
+ prepare_auto_load_config() {
243
+ [ -r "$AUTO_LOAD_SCRIPT" ] || die "${AUTO_LOAD_SCRIPT} was not found or is not readable."
244
+ [ -w "$AUTO_LOAD_SCRIPT" ] || die "${AUTO_LOAD_SCRIPT} is not writable."
245
+
246
+ AUTO_LOAD_TMP_FILE="${AUTO_LOAD_SCRIPT}.tmp"
247
+ sed "s/cmmpool=anonymous,0,0x[0-9A-Fa-f][0-9A-Fa-f]*,[0-9][0-9]*M/cmmpool=anonymous,0,${NEW_CMM_BASE},${NEW_CMM_MIB}M/" "$AUTO_LOAD_SCRIPT" > "$AUTO_LOAD_TMP_FILE" || die "Cannot create ${AUTO_LOAD_TMP_FILE}."
248
+ if cmp -s "$AUTO_LOAD_SCRIPT" "$AUTO_LOAD_TMP_FILE"; then
249
+ die "No ax_cmm.ko cmmpool parameter was found in ${AUTO_LOAD_SCRIPT}."
250
+ fi
251
+ chmod 0755 "$AUTO_LOAD_TMP_FILE" || die "Cannot chmod ${AUTO_LOAD_TMP_FILE}."
252
+ }
253
+
254
+ write_config() {
255
+ NEW_BOOTARGS=$(printf '%s\n' "$BOOTARGS" | sed "s/mem=[0-9][0-9]*M/mem=${NEW_OS_MIB}M/")
256
+ [ "$NEW_BOOTARGS" != "$BOOTARGS" ] || die 'Failed to replace the mem= parameter in bootargs.'
257
+ NEW_CMM_BASE=$(cmm_base_for_os_mib "$NEW_OS_MIB")
258
+ prepare_auto_load_config
259
+
260
+ umask 077
261
+ printf '%s\n' "$BOOTARGS" > "${BACKUP_FILE}.tmp" || die "Cannot create ${BACKUP_FILE}."
262
+ mv "${BACKUP_FILE}.tmp" "$BACKUP_FILE" || die "Cannot save ${BACKUP_FILE}."
263
+ cp -p "$AUTO_LOAD_SCRIPT" "$AUTO_LOAD_BACKUP_FILE" || die "Cannot back up ${AUTO_LOAD_SCRIPT}."
264
+ fw_setenv bootargs "$NEW_BOOTARGS" || die 'Failed to write U-Boot bootargs.'
265
+ mv "$AUTO_LOAD_TMP_FILE" "$AUTO_LOAD_SCRIPT" || die "Cannot save ${AUTO_LOAD_SCRIPT}."
266
+ sync
267
+
268
+ printf 'Configuration was written to the U-Boot environment and auto_load script.\n'
269
+ printf 'OS MEM: %s MiB; CMM: %s MiB; CMM base: %s.\n' "$NEW_OS_MIB" "$NEW_CMM_MIB" "$NEW_CMM_BASE"
270
+ printf 'Original bootargs backup: %s\n' "$BACKUP_FILE"
271
+ printf 'Original auto_load script backup: %s\n' "$AUTO_LOAD_BACKUP_FILE"
272
+ printf 'Run reboot to apply the new memory split.\n'
273
+ }
274
+
275
+ parse_args() {
276
+ while [ "$#" -gt 0 ]; do
277
+ case "$1" in
278
+ --show)
279
+ [ -z "$MODE" ] || die '--show cannot be combined with a set option.'
280
+ MODE=show
281
+ ;;
282
+ --os-mem)
283
+ [ "$#" -ge 2 ] || die '--os-mem requires a MiB value.'
284
+ [ -z "$MODE" ] || die 'Choose either --os-mem or --cmm, not both.'
285
+ MODE=os
286
+ TARGET_MIB=$2
287
+ shift
288
+ ;;
289
+ --cmm)
290
+ [ "$#" -ge 2 ] || die '--cmm requires a MiB value.'
291
+ [ -z "$MODE" ] || die 'Choose either --os-mem or --cmm, not both.'
292
+ MODE=cmm
293
+ TARGET_MIB=$2
294
+ shift
295
+ ;;
296
+ --total-mem)
297
+ [ "$#" -ge 2 ] || die '--total-mem requires a MiB value.'
298
+ TOTAL_OVERRIDE_MIB=$2
299
+ shift
300
+ ;;
301
+ --init-fw-env)
302
+ INIT_FW_ENV=1
303
+ ;;
304
+ --yes)
305
+ ASSUME_YES=1
306
+ ;;
307
+ -h|--help)
308
+ usage
309
+ exit 0
310
+ ;;
311
+ *)
312
+ die "Unknown option: $1"
313
+ ;;
314
+ esac
315
+ shift
316
+ done
317
+ }
318
+
319
+ choose_interactively() {
320
+ [ -t 0 ] || die 'Use --os-mem or --cmm in a non-interactive environment.'
321
+ show_status
322
+ printf '\nSelect the value to change:\n 1) OS MEM\n 2) CMM\n q) Quit\n> '
323
+ read -r CHOICE || exit 1
324
+ case "$CHOICE" in
325
+ 1)
326
+ MODE=os
327
+ printf 'Enter OS MEM in MiB: '
328
+ read -r TARGET_MIB || exit 1
329
+ ;;
330
+ 2)
331
+ MODE=cmm
332
+ printf 'Enter CMM in MiB: '
333
+ read -r TARGET_MIB || exit 1
334
+ ;;
335
+ q|Q)
336
+ exit 0
337
+ ;;
338
+ *)
339
+ die 'Invalid selection.'
340
+ ;;
341
+ esac
342
+ }
343
+
344
+ main() {
345
+ parse_args "$@"
346
+ if [ "$ASSUME_YES" -eq 1 ] && [ "$MODE" != os ] && [ "$MODE" != cmm ] && [ "$INIT_FW_ENV" -ne 1 ]; then
347
+ die '--yes is valid only with --os-mem, --cmm, or --init-fw-env.'
348
+ fi
349
+ is_nonnegative_integer "$TOTAL_OVERRIDE_MIB" || [ -z "$TOTAL_OVERRIDE_MIB" ] || die '--total-mem must be an integer MiB value.'
350
+ if [ -z "$MODE" ] && [ "$INIT_FW_ENV" -eq 1 ]; then
351
+ MODE=init
352
+ fi
353
+ if [ -z "$MODE" ] && [ -t 0 ]; then
354
+ ALLOW_FW_ENV_INIT=1
355
+ fi
356
+
357
+ [ "$(id -u)" -eq 0 ] || die 'Run this script as root.'
358
+ read_bootargs
359
+
360
+ if [ "$MODE" = init ]; then
361
+ printf 'U-Boot bootargs can be read successfully. No memory split was changed.\n'
362
+ exit 0
363
+ fi
364
+
365
+ read_current_cmm
366
+ detect_expanded_memory_layout
367
+ determine_total_memory
368
+
369
+ if [ "$MODE" = show ]; then
370
+ show_status
371
+ exit 0
372
+ fi
373
+
374
+ if [ -z "$MODE" ]; then
375
+ choose_interactively
376
+ fi
377
+
378
+ is_nonnegative_integer "$TARGET_MIB" || die 'The memory size must be an integer MiB value.'
379
+ case "$MODE" in
380
+ os)
381
+ NEW_OS_MIB=$TARGET_MIB
382
+ NEW_CMM_MIB=$((TOTAL_MIB - NEW_OS_MIB))
383
+ ;;
384
+ cmm)
385
+ NEW_CMM_MIB=$TARGET_MIB
386
+ NEW_OS_MIB=$((TOTAL_MIB - NEW_CMM_MIB))
387
+ ;;
388
+ *)
389
+ die 'Internal mode error.'
390
+ ;;
391
+ esac
392
+
393
+ [ "$TOTAL_MIB" -gt "$MIN_OS_MEM_MIB" ] || die "Total memory must exceed ${MIN_OS_MEM_MIB} MiB."
394
+ [ "$NEW_OS_MIB" -ge "$MIN_OS_MEM_MIB" ] || die "OS MEM must be at least ${MIN_OS_MEM_MIB} MiB."
395
+ [ "$NEW_CMM_MIB" -ge 1 ] || die 'CMM must retain at least 1 MiB.'
396
+ [ "$NEW_OS_MIB" -lt "$TOTAL_MIB" ] || die 'OS MEM must be smaller than total physical memory.'
397
+
398
+ check_write_targets
399
+ confirm_total_memory
400
+ confirm_write
401
+ write_config
402
+ }
403
+
404
+ main "$@"