Skip to content

Commit 66572be

Browse files
committed
apps/boot/nxboot: Enhancements to add progress messages and copy-to-RAM feature
This adds Kconfig-enabled progress messages that are output to stdout. It also adds Kconfig-enabled option to copy the validated and bootable image to RAM Signed-off by: Tim Hardisty <[email protected]>
1 parent f14249d commit 66572be

File tree

5 files changed

+305
-18
lines changed

5 files changed

+305
-18
lines changed

boot/nxboot/Kconfig

+15
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,17 @@ config NXBOOT_BOOTLOADER
6464

6565
if NXBOOT_BOOTLOADER
6666

67+
config NXBOOT_COPY_TO_RAM
68+
bool "Copy bootable image to RAM before calling board boot-image function"
69+
default n
70+
71+
config NXBOOT_RAMSTART
72+
hex "Start address in RAM that the application is to be loaded"
73+
default 0x0
74+
depends on NXBOOT_COPY_TO_RAM
75+
---help---
76+
This will be board specific.
77+
6778
config NXBOOT_SWRESET_ONLY
6879
bool "Perform update/revert only on SW reset"
6980
default n
@@ -92,6 +103,10 @@ config NXBOOT_PREVENT_DOWNGRADE
92103
WARNING: NXboot currently implements preferences only for
93104
MAJOR.MINOR.PATCH and ignores prerelease.
94105

106+
config NXBOOT_PRINTF_PROGRESS
107+
bool "Enable progress messages to be sent to STDOUT"
108+
default n
109+
95110
endif # NXBOOT_BOOTLOADER
96111

97112
endif # BOOT_NXBOOT

boot/nxboot/include/nxboot.h

+57-6
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ struct nxboot_img_header
117117

118118
struct nxboot_img_version img_version; /* Image version */
119119
};
120+
120121
static_assert(CONFIG_NXBOOT_HEADER_SIZE > sizeof(struct nxboot_img_header),
121122
"CONFIG_NXBOOT_HEADER_SIZE has to be larger than"
122123
"sizeof(struct nxboot_img_header)");
@@ -131,10 +132,41 @@ struct nxboot_state
131132
enum nxboot_update_type next_boot; /* nxboot_update_type with next operation */
132133
};
133134

135+
enum progress_type_e
136+
{
137+
nxboot_info = 0, /* Prefixes arg. string with "INFO:" */
138+
nxboot_error, /* Prefixes arg. string with "ERR:" */
139+
nxboot_progress_start, /* Prints arg. string with no newline to allow ..... sequence to follow */
140+
nxboot_progress_dot, /* Prints of a "." to the ..... progress sequence */
141+
nxboot_progress_end, /* Flags end of a "..." progrees sequence and prints newline */
142+
};
143+
144+
enum progress_msg_e
145+
{
146+
startup_msg = 0,
147+
found_bootable_image,
148+
no_bootable_image,
149+
boardioc_image_boot_fail,
150+
ramcopy_started,
151+
recovery_revert,
152+
recovery_create,
153+
update_from_update,
154+
validate_primary,
155+
validate_recovery,
156+
validate_update,
157+
recovery_created,
158+
recovery_invalid,
159+
update_failed,
160+
power_reset,
161+
soft_reset,
162+
};
163+
134164
/****************************************************************************
135165
* Public Function Prototypes
136166
****************************************************************************/
137167

168+
void nxboot_progress(enum progress_type_e type, ...);
169+
138170
/****************************************************************************
139171
* Name: nxboot_get_state
140172
*
@@ -148,7 +180,7 @@ struct nxboot_state
148180
* state: The pointer to nxboot_state structure. The state is stored here.
149181
*
150182
* Returned Value:
151-
* 0 on success, -1 and sets errno on failure.
183+
* OK (0) on success, ERROR (-1) and sets errno on failure.
152184
*
153185
****************************************************************************/
154186

@@ -164,7 +196,7 @@ int nxboot_get_state(struct nxboot_state *state);
164196
* if afterwards.
165197
*
166198
* Returned Value:
167-
* Valid file descriptor on success, -1 and sets errno on failure.
199+
* Valid file descriptor on success, ERROR (-1) and sets errno on failure.
168200
*
169201
****************************************************************************/
170202

@@ -180,7 +212,7 @@ int nxboot_open_update_partition(void);
180212
* state of the bootloader.
181213
*
182214
* Returned Value:
183-
* 1 means confirmed, 0 not confirmed, -1 and sets errno on failure.
215+
* 1 if confirmed, OK (0) on success, ERROR (-1) and sets errno on failure.
184216
*
185217
****************************************************************************/
186218

@@ -194,14 +226,14 @@ int nxboot_get_confirm(void);
194226
* its copy in update partition as a recovery.
195227
*
196228
* Returned Value:
197-
* 0 on success, -1 and sets errno on failure.
229+
* OK (0) on success, ERROR (-1) and sets errno on failure.
198230
*
199231
****************************************************************************/
200232

201233
int nxboot_confirm(void);
202234

203235
/****************************************************************************
204-
* Name: nxboot_perform_swap
236+
* Name: nxboot_perform_update
205237
*
206238
* Description:
207239
* Checks for the possible firmware update and performs it by copying
@@ -216,10 +248,29 @@ int nxboot_confirm(void);
216248
* check_only: Only repairs corrupted update, but do not start another one
217249
*
218250
* Returned Value:
219-
* 0 on success, -1 and sets errno on failure.
251+
* OK (0) on success, ERROR (-1) and sets errno on failure.
220252
*
221253
****************************************************************************/
222254

223255
int nxboot_perform_update(bool check_only);
224256

257+
/****************************************************************************
258+
* Name: nxboot_ramcopy
259+
*
260+
* Description:
261+
* Copies the (already) validate bootable image to RAM memory
262+
*
263+
* NOTE - no checking that the RAM location is correct, nor that the
264+
* image size is appropriate for that RAM address!
265+
*
266+
* Input parameters:
267+
* none
268+
*
269+
* Returned Value:
270+
* OK (0) on success, ERROR (-1) on fail
271+
*
272+
****************************************************************************/
273+
274+
int nxboot_ramcopy(void);
275+
225276
#endif /* __BOOT_NXBOOT_INCLUDE_NXBOOT_H */

boot/nxboot/loader/boot.c

+85-4
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ static uint32_t calculate_crc(int fd, struct nxboot_img_header *header)
106106
off += readsiz;
107107
remain -= readsiz;
108108
crc = crc32part((uint8_t *)buf, readsiz, crc);
109+
if ((remain % 25) == 0)
110+
{
111+
nxboot_progress(nxboot_progress_dot);
112+
}
109113
}
110114

111115
free(buf);
@@ -202,6 +206,10 @@ static int copy_partition(int from, int where, struct nxboot_state *state,
202206

203207
off += readsiz;
204208
remain -= readsiz;
209+
if ((remain % 25) == 0)
210+
{
211+
nxboot_progress(nxboot_progress_dot);
212+
}
205213
}
206214

207215
free(buf);
@@ -218,6 +226,7 @@ static bool validate_image(int fd)
218226
return false;
219227
}
220228

229+
syslog(LOG_INFO, "Validating image.\n");
221230
return calculate_crc(fd, &header) == header.crc;
222231
}
223232

@@ -268,18 +277,24 @@ static enum nxboot_update_type
268277
struct nxboot_img_header *update_header,
269278
struct nxboot_img_header *recovery_header)
270279
{
280+
nxboot_progress(nxboot_progress_start, validate_primary);
271281
bool primary_valid = validate_image(primary);
282+
nxboot_progress(nxboot_progress_end);
272283

284+
nxboot_progress(nxboot_progress_start, validate_update);
273285
if (update_header->magic == NXBOOT_HEADER_MAGIC && validate_image(update))
274286
{
275287
if (primary_header->crc != update_header->crc ||
276288
!compare_versions(&primary_header->img_version,
277289
&update_header->img_version) || !primary_valid)
278290
{
291+
nxboot_progress(nxboot_progress_end);
279292
return NXBOOT_UPDATE_TYPE_UPDATE;
280293
}
281294
}
282295

296+
nxboot_progress(nxboot_progress_end);
297+
283298
if (IS_INTERNAL_MAGIC(recovery_header->magic) && state->recovery_valid &&
284299
((IS_INTERNAL_MAGIC(primary_header->magic) &&
285300
!state->primary_confirmed) || !primary_valid))
@@ -292,6 +307,7 @@ static enum nxboot_update_type
292307

293308
static int perform_update(struct nxboot_state *state, bool check_only)
294309
{
310+
int successful;
295311
int update;
296312
int recovery;
297313
int primary;
@@ -331,18 +347,25 @@ static int perform_update(struct nxboot_state *state, bool check_only)
331347
recovery = secondary;
332348
}
333349

350+
nxboot_progress(nxboot_progress_start, validate_primary);
334351
if (state->next_boot == NXBOOT_UPDATE_TYPE_REVERT &&
335352
(!check_only || !validate_image(primary)))
336353
{
354+
nxboot_progress(nxboot_progress_end);
337355
if (state->recovery_valid)
338356
{
339357
syslog(LOG_INFO, "Reverting image to recovery.\n");
358+
nxboot_progress(nxboot_progress_start, recovery_revert);
340359
copy_partition(recovery, primary, state, false);
360+
nxboot_progress(nxboot_progress_end);
341361
}
342362
}
343363
else
344364
{
365+
nxboot_progress(nxboot_progress_end);
366+
nxboot_progress(nxboot_progress_start, validate_primary);
345367
primary_valid = validate_image(primary);
368+
nxboot_progress(nxboot_progress_end);
346369
if (primary_valid && check_only)
347370
{
348371
/* Skip if primary image is valid (does not mather whether
@@ -368,21 +391,33 @@ static int perform_update(struct nxboot_state *state, bool check_only)
368391
*/
369392

370393
syslog(LOG_INFO, "Creating recovery image.\n");
394+
nxboot_progress(nxboot_progress_start, recovery_create);
371395
copy_partition(primary, recovery, state, false);
372-
if (!validate_image(recovery))
396+
nxboot_progress(nxboot_progress_end);
397+
nxboot_progress(nxboot_progress_start, validate_recovery);
398+
successful = validate_image(recovery);
399+
nxboot_progress(nxboot_progress_end);
400+
if (!successful)
373401
{
374-
syslog(LOG_INFO, "New recovery is not valid, stop update.\n");
402+
syslog(LOG_INFO,
403+
"New recovery is not valid,stop update.\n");
404+
nxboot_progress(nxboot_info, recovery_invalid);
375405
goto perform_update_done;
376406
}
377407

378408
syslog(LOG_INFO, "Recovery image created.\n");
409+
nxboot_progress(nxboot_info, recovery_created);
379410
}
380411

381-
if (validate_image(update))
412+
nxboot_progress(nxboot_progress_start, validate_update);
413+
successful = validate_image(update);
414+
nxboot_progress(nxboot_progress_end);
415+
if (successful)
382416
{
383417
/* Perform update only if update slot contains valid image. */
384418

385419
syslog(LOG_INFO, "Updating from update image.\n");
420+
nxboot_progress(nxboot_progress_start, update_from_update);
386421
if (copy_partition(update, primary, state, true) >= 0)
387422
{
388423
/* Erase the first sector of update partition. This marks the
@@ -393,6 +428,8 @@ static int perform_update(struct nxboot_state *state, bool check_only)
393428

394429
flash_partition_erase_first_sector(update);
395430
}
431+
432+
nxboot_progress(nxboot_progress_end);
396433
}
397434
}
398435

@@ -403,6 +440,46 @@ static int perform_update(struct nxboot_state *state, bool check_only)
403440
return OK;
404441
}
405442

443+
#ifdef CONFIG_NXBOOT_COPY_TO_RAM
444+
int nxboot_ramcopy(void)
445+
{
446+
int ret = OK;
447+
int primary;
448+
struct nxboot_img_header header;
449+
ssize_t bytes;
450+
static uint8_t *buf;
451+
452+
primary = flash_partition_open(CONFIG_NXBOOT_PRIMARY_SLOT_PATH);
453+
if (primary < 0)
454+
{
455+
return ERROR;
456+
}
457+
458+
get_image_header(primary, &header);
459+
buf = malloc(header.size);
460+
if (!buf)
461+
{
462+
ret = ERROR;
463+
goto exit_with_error;
464+
}
465+
466+
bytes = pread(primary, buf, header.size, header.header_size);
467+
if (bytes != header.size)
468+
{
469+
ret = ERROR;
470+
goto exit_with_error;
471+
}
472+
473+
memcpy((uint32_t *)CONFIG_NXBOOT_RAMSTART, buf, header.size);
474+
475+
exit_with_error:
476+
flash_partition_close(primary);
477+
free(buf);
478+
479+
return ret;
480+
}
481+
#endif
482+
406483
/****************************************************************************
407484
* Public Functions
408485
****************************************************************************/
@@ -528,7 +605,9 @@ int nxboot_get_state(struct nxboot_state *state)
528605
state->update = NXBOOT_TERTIARY_SLOT_NUM;
529606
}
530607

608+
nxboot_progress(nxboot_progress_start, validate_recovery);
531609
state->recovery_valid = validate_image(recovery);
610+
nxboot_progress(nxboot_progress_end);
532611
state->recovery_present = primary_header.crc == recovery_header->crc;
533612

534613
/* The image is confirmed if it has either NXBOOT_HEADER_MAGIC or a
@@ -611,7 +690,7 @@ int nxboot_get_confirm(void)
611690
int recovery;
612691
int recovery_pointer;
613692
char *path;
614-
int ret = 0;
693+
int ret = OK;
615694
struct nxboot_img_header primary_header;
616695
struct nxboot_img_header recovery_header;
617696

@@ -799,6 +878,7 @@ int nxboot_perform_update(bool check_only)
799878
*/
800879

801880
syslog(LOG_ERR, "Update process failed: %s\n", strerror(errno));
881+
nxboot_progress(nxboot_error, update_failed);
802882
}
803883
}
804884

@@ -823,3 +903,4 @@ int nxboot_perform_update(bool check_only)
823903

824904
return ret;
825905
}
906+

boot/nxboot/loader/flash.c

+5-4
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,8 @@ int flash_partition_read(int fd, void *buf, size_t count, off_t off)
202202
nbytes = read(fd, buf, count);
203203
if (nbytes != count)
204204
{
205-
syslog(LOG_ERR, "Read from offset %ld failed %s\n",
206-
off, strerror(errno));
205+
syslog(LOG_ERR, "Read from offset %ld failed %s\n", off,
206+
strerror(errno));
207207
return ERROR;
208208
}
209209

@@ -265,7 +265,7 @@ int flash_partition_erase_first_sector(int fd)
265265
if (ret < 0)
266266
{
267267
syslog(LOG_ERR, "Could not erase the partition: %s\n",
268-
strerror(errno));
268+
strerror(errno));
269269
return ERROR;
270270
}
271271

@@ -295,7 +295,8 @@ int flash_partition_info(int fd, struct flash_partition_info *info)
295295
ret = ioctl(fd, MTDIOC_GEOMETRY, (unsigned long)((uintptr_t)&geometry));
296296
if (ret < 0)
297297
{
298-
syslog(LOG_ERR, "ioctl MTDIOC_GEOMETRY failed: %s\n", strerror(errno));
298+
syslog(LOG_ERR, "ioctl MTDIOC_GEOMETRY failed: %s\n",
299+
strerror(errno));
299300
return ERROR;
300301
}
301302

0 commit comments

Comments
 (0)