Skip to content

Commit 3104542

Browse files
committed
binary_manager: Support new APIs for partition swap
1. binary_manager_get_inactive_info_all : Get info of all registered binaries in inactive(non-running) partition 2. binary_manager_swap_partition : Update bootparam data to swap opposite partition if all valid binaries exist in opposite partition
1 parent 4e97940 commit 3104542

File tree

10 files changed

+380
-59
lines changed

10 files changed

+380
-59
lines changed

framework/include/binary_manager/binary_manager.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@
3232
* Included Files
3333
***************************************************************************/
3434
#include <tinyara/binary_manager.h>
35+
#include <tinyara/config.h>
36+
37+
#ifdef __cplusplus
38+
extern "C" {
39+
#endif
3540

3641
/****************************************************************************
3742
* Pre-processor Definitions
@@ -69,6 +74,17 @@ binmgr_result_type_e binary_manager_get_update_info(char *binary_name, binary_up
6974
* @since TizenRT v3.0
7075
*/
7176
binmgr_result_type_e binary_manager_get_update_info_all(binary_update_info_list_t *binary_info_list);
77+
78+
/**
79+
* @brief Get the all binaries information in inactive partition
80+
* @details @b #include <binary_manager/binary_manager.h>\n
81+
* It requests the binary manager to get the information of all binaries in inactive partition.
82+
* @param[out] binary_info_list The address value to receive the binary information list
83+
* @return A defined value of binmgr_result_type_e in <tinyara/binary_manager.h>
84+
* 0 (BINMGR_OK) On success. On failure, negative value is returned.
85+
* @since TizenRT v3.0
86+
*/
87+
binmgr_result_type_e binary_manager_get_inactive_info_all(binary_update_info_list_t *binary_info_list);
7288
#endif
7389

7490
/**
@@ -150,6 +166,19 @@ binmgr_result_type_e binary_manager_get_state(char *binary_name, int *state);
150166
*/
151167
binmgr_result_type_e binary_manager_set_bootparam(uint8_t type, binary_setbp_result_t *update_result);
152168

169+
/**
170+
* @brief Swap partition to inactive partition
171+
* @details @b #include <binary_manager/binary_manager.h>\n
172+
* It sends a message the binary manager to update boot paramer to swap opposite partition.
173+
* @return A defined value of binmgr_result_type_e in <tinyara/binary_manager.h>
174+
* 0 (BINMGR_OK) on success. On failure, negative value is returned.
175+
* @since TizenRT v5.0
176+
*/
177+
binmgr_result_type_e binary_manager_swap_partition(void);
178+
#ifdef __cplusplus
179+
}
180+
#endif
181+
153182
#endif
154183
/**
155184
* @}

framework/src/binary_manager/binary_manager_interface.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ binmgr_result_type_e binary_manager_set_request(binmgr_request_t *request_msg, i
5959
case BINMGR_SETBP:
6060
request_msg->data.type = *(uint8_t *)arg;
6161
break;
62+
case BINMGR_SWAPBP:
63+
break;
6264
#endif
6365
case BINMGR_REGISTER_STATECB:
6466
if (arg == NULL) {

framework/src/binary_manager/binary_manager_update.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,66 @@ binmgr_result_type_e binary_manager_get_current_path(char *binary_name, char *do
244244

245245
return response_msg.result;
246246
}
247+
248+
binmgr_result_type_e binary_manager_swap_partition(void)
249+
{
250+
#ifndef CONFIG_USE_BP
251+
/* In the case of 3.1 bootloader, we dont have bp. So we need not
252+
* update the bp to swap partitions, it is automatically done on
253+
* reboot, so return success */
254+
return BINMGR_OK;
255+
#else
256+
binmgr_result_type_e ret;
257+
binmgr_request_t request_msg;
258+
binmgr_setbp_response_t response_msg;
259+
260+
ret = binary_manager_set_request(&request_msg, BINMGR_SWAPBP, NULL);
261+
if (ret != BINMGR_OK) {
262+
return ret;
263+
}
264+
265+
ret = binary_manager_send_request(&request_msg);
266+
if (ret != BINMGR_OK) {
267+
return ret;
268+
}
269+
270+
ret = binary_manager_receive_response(&response_msg, sizeof(binmgr_response_t));
271+
if (ret != BINMGR_OK) {
272+
return ret;
273+
}
274+
275+
return response_msg.result;
276+
#endif
277+
}
278+
279+
binmgr_result_type_e binary_manager_get_inactive_info_all(binary_update_info_list_t *binary_info_list)
280+
{
281+
binmgr_result_type_e ret;
282+
binmgr_request_t request_msg;
283+
binmgr_getinfo_all_response_t response_msg;
284+
285+
ret = binary_manager_set_request(&request_msg, BINMGR_GET_INFO_INACTIVE_ALL, NULL);
286+
if (ret != BINMGR_OK) {
287+
return ret;
288+
}
289+
290+
ret = binary_manager_send_request(&request_msg);
291+
if (ret != BINMGR_OK) {
292+
return ret;
293+
}
294+
295+
ret = binary_manager_receive_response(&response_msg, sizeof(binmgr_getinfo_all_response_t));
296+
if (ret != BINMGR_OK) {
297+
return ret;
298+
}
299+
300+
if (response_msg.result == BINMGR_OK) {
301+
/* Copy binary info list data */
302+
memset(binary_info_list, 0, sizeof(binary_update_info_list_t));
303+
memcpy(binary_info_list, &response_msg.data, sizeof(binary_update_info_list_t));
304+
} else {
305+
bmdbg("Binary manager getinfo_inactive_all FAIL %d\n", response_msg.result);
306+
}
307+
308+
return response_msg.result;
309+
}

os/include/tinyara/binary_manager.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
#include <limits.h>
2929
#include <stdbool.h>
3030

31+
#ifdef __cplusplus
32+
extern "C" {
33+
#endif
34+
3135
#ifdef CONFIG_BINARY_MANAGER
3236
/****************************************************************************
3337
* Pre-processor Definitions
@@ -125,6 +129,10 @@ enum binmgr_request_msg_type {
125129
#ifdef CONFIG_BINMGR_RECOVERY
126130
BINMGR_FAULT,
127131
#endif
132+
#ifdef CONFIG_USE_BP
133+
BINMGR_SWAPBP,
134+
#endif
135+
BINMGR_GET_INFO_INACTIVE_ALL,
128136
};
129137

130138
/* Result values of returned from binary manager. */
@@ -254,6 +262,11 @@ struct binmgr_request_s {
254262
};
255263
typedef struct binmgr_request_s binmgr_request_t;
256264

265+
struct binmgr_response_s {
266+
binmgr_result_type_e result;
267+
};
268+
typedef struct binmgr_response_s binmgr_response_t;
269+
257270
struct binmgr_setbp_response_s {
258271
binmgr_result_type_e result;
259272
binary_setbp_result_t data;
@@ -300,14 +313,6 @@ void binary_manager_register_respart(int part_num, int part_size, uint32_t part_
300313
int binary_manager_mount_resource(void);
301314
void binary_manager_deinit_modules(void);
302315

303-
#ifdef __cplusplus
304-
#define EXTERN extern "C"
305-
extern "C" {
306-
#else
307-
#define EXTERN extern
308-
#endif
309-
310-
#undef EXTERN
311316
#ifdef __cplusplus
312317
}
313318
#endif

os/kernel/binary_manager/binary_manager.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ int binary_manager(int argc, char *argv[])
211211
case BINMGR_GET_INFO_ALL:
212212
binary_manager_get_info_all(request_msg.requester_pid);
213213
break;
214+
case BINMGR_GET_INFO_INACTIVE_ALL:
215+
binary_manager_get_inactive_info_all(request_msg.requester_pid);
216+
break;
214217
case BINMGR_GET_DOWNLOAD_PATH:
215218
binary_manager_get_inactive_path(request_msg.requester_pid, request_msg.data.bin_name);
216219
break;
@@ -221,6 +224,9 @@ int binary_manager(int argc, char *argv[])
221224
case BINMGR_SETBP:
222225
binary_manager_update_bootparam(request_msg.requester_pid, request_msg.data.type);
223226
break;
227+
case BINMGR_SWAPBP:
228+
binary_manager_swap_bootparam(request_msg.requester_pid);
229+
break;
224230
#endif
225231
case BINMGR_UPDATE:
226232
#ifdef CONFIG_APP_BINARY_SEPARATION

os/kernel/binary_manager/binary_manager.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,10 @@ int binary_manager_update_kernel_binary(void);
302302
#ifdef CONFIG_RESOURCE_FS
303303
binmgr_resinfo_t *binary_manager_get_resdata(void);
304304
int binary_manager_unmount_resource(void);
305-
int binary_manager_check_resource_update(void);
305+
int binary_manager_check_resource_update(bool check_updatable);
306306
#endif
307+
int binary_manager_check_kernel_update(bool check_updatable);
308+
int binary_manager_check_user_update(int bin_idx, bool check_updatable);
307309

308310
/****************************************************************************
309311
* Binary Manager Main Thread

os/kernel/binary_manager/binary_manager_bootparam.c

Lines changed: 105 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <stdbool.h>
2828

2929
#include <tinyara/binary_manager.h>
30+
#include <tinyara/reboot_reason.h>
3031

3132
#include "binary_manager.h"
3233

@@ -284,8 +285,8 @@ void binary_manager_update_bootparam(int requester_pid, uint8_t type)
284285

285286
if (BM_CHECK_GROUP(type, BINARY_KERNEL)) {
286287
/* Update bootparam and Reboot if new kernel binary exists */
287-
ret = binary_manager_check_kernel_update();
288-
if (ret == BINMGR_OK) {
288+
ret = binary_manager_check_kernel_update(true);
289+
if (ret > 0) {
289290
/* Update index for inactive partition */
290291
update_bp_data.active_idx ^= 1;
291292
} else if (ret == BINMGR_ALREADY_UPDATED || ret == BINMGR_NOT_FOUND) {
@@ -301,8 +302,8 @@ void binary_manager_update_bootparam(int requester_pid, uint8_t type)
301302
#ifdef CONFIG_RESOURCE_FS
302303
if (BM_CHECK_GROUP(type, BINARY_RESOURCE)) {
303304
/* Update bootparam if new resource binary exists */
304-
ret = binary_manager_check_resource_update();
305-
if (ret == BINMGR_OK) {
305+
ret = binary_manager_check_resource_update(true);
306+
if (ret > 0) {
306307
/* Update index for inactive partition */
307308
update_bp_data.resource_active_idx ^= 1;
308309
} else if (ret == BINMGR_ALREADY_UPDATED || ret == BINMGR_NOT_FOUND) {
@@ -324,8 +325,8 @@ void binary_manager_update_bootparam(int requester_pid, uint8_t type)
324325
/* Reload binaries if new binary is scanned */
325326
for (bin_idx = 1; bin_idx <= bin_count; bin_idx++) {
326327
/* Scan binary files */
327-
ret = binary_manager_check_user_update(bin_idx);
328-
if (ret == BINMGR_OK) {
328+
ret = binary_manager_check_user_update(bin_idx, true);
329+
if (ret > 0) {
329330
/* Update index for inactive partition */
330331
update_bp_data.app_data[BIN_BPIDX(bin_idx)].useidx ^= 1;
331332
need_update = true;
@@ -345,8 +346,8 @@ void binary_manager_update_bootparam(int requester_pid, uint8_t type)
345346

346347
#ifdef CONFIG_SUPPORT_COMMON_BINARY
347348
if (BM_CHECK_GROUP(type, BINARY_COMMON)) {
348-
ret = binary_manager_check_user_update(BM_CMNLIB_IDX);
349-
if (ret == BINMGR_OK) {
349+
ret = binary_manager_check_user_update(BM_CMNLIB_IDX, true);
350+
if (ret > 0) {
350351
/* Update index for inactive partition */
351352
update_bp_data.app_data[BIN_BPIDX(BM_CMNLIB_IDX)].useidx ^= 1;
352353
} else if (ret == BINMGR_ALREADY_UPDATED || ret == BINMGR_NOT_FOUND) {
@@ -376,7 +377,9 @@ void binary_manager_update_bootparam(int requester_pid, uint8_t type)
376377
}
377378

378379
send_response:
379-
kmm_free(bootparam);
380+
if (bootparam) {
381+
kmm_free(bootparam);
382+
}
380383
response_msg.result = ret;
381384
snprintf(q_name, BIN_PRIVMQ_LEN, "%s%d", BINMGR_RESPONSE_MQ_PREFIX, requester_pid);
382385
binary_manager_send_response(q_name, &response_msg, sizeof(binmgr_setbp_response_t));
@@ -422,3 +425,96 @@ void binary_manager_set_bpidx(uint8_t index)
422425
{
423426
g_bp_info.inuse_idx = index;
424427
}
428+
429+
void binary_manager_swap_bootparam(int requester_pid)
430+
{
431+
int ret;
432+
char *bootparam;
433+
bool is_all_updatable;
434+
char q_name[BIN_PRIVMQ_LEN];
435+
binmgr_bpdata_t update_bp_data;
436+
binmgr_response_t response_msg;
437+
#ifdef CONFIG_APP_BINARY_SEPARATION
438+
int bin_idx;
439+
uint32_t bin_count;
440+
#endif
441+
442+
memset((void *)&response_msg, 0, sizeof(binmgr_response_t));
443+
444+
if (requester_pid < 0) {
445+
bmdbg("Invalid requester pid %d\n", requester_pid);
446+
return;
447+
}
448+
449+
bootparam = (char *)kmm_malloc(BOOTPARAM_SIZE);
450+
if (!bootparam) {
451+
bmdbg("Fail to malloc to read BP\n");
452+
ret = BINMGR_OUT_OF_MEMORY;
453+
goto send_response;
454+
}
455+
memset(bootparam, 0xff, BOOTPARAM_SIZE);
456+
457+
response_msg.result = BINMGR_OK;
458+
is_all_updatable = true;
459+
460+
/* Get current bootparam data */
461+
memcpy(&update_bp_data, binary_manager_get_bpdata(), sizeof(binmgr_bpdata_t));
462+
update_bp_data.version++;
463+
464+
/* Update bootparam and Reboot if valid kernel binary exists */
465+
ret = binary_manager_check_kernel_update(false);
466+
if (ret < 0) {
467+
bmdbg("Fail to find valid kernel binary, %d\n", ret);
468+
goto send_response;
469+
}
470+
update_bp_data.active_idx ^= 1;
471+
472+
#ifdef CONFIG_RESOURCE_FS
473+
/* Update bootparam if valid resource binary exists */
474+
ret = binary_manager_check_resource_update(false);
475+
if (ret < 0) {
476+
bmdbg("Fail to find valid resource binary, %d\n", ret);
477+
goto send_response;
478+
}
479+
update_bp_data.resource_active_idx ^= 1;
480+
#endif
481+
482+
#ifdef CONFIG_APP_BINARY_SEPARATION
483+
bin_count = binary_manager_get_ucount();
484+
for (bin_idx = 1; bin_idx <= bin_count; bin_idx++) {
485+
/* Scan binary files */
486+
ret = binary_manager_check_user_update(bin_idx, false);
487+
if (ret < 0) {
488+
bmdbg("Fail to find valid user binary, %d\n", ret);
489+
goto send_response;
490+
}
491+
update_bp_data.app_data[BIN_BPIDX(bin_idx)].useidx ^= 1;
492+
}
493+
494+
#ifdef CONFIG_SUPPORT_COMMON_BINARY
495+
ret = binary_manager_check_user_update(BM_CMNLIB_IDX, false);
496+
if (ret < 0) {
497+
bmdbg("Fail to find valid common binary, %d\n", ret);
498+
goto send_response;
499+
}
500+
update_bp_data.app_data[BIN_BPIDX(BM_CMNLIB_IDX)].useidx ^= 1;
501+
#endif
502+
#endif
503+
504+
/* Then, Write bootparam with updated bootparam data */
505+
memcpy(bootparam, &update_bp_data, sizeof(binmgr_bpdata_t));
506+
ret = binary_manager_write_bootparam(bootparam);
507+
if (ret == BINMGR_OK) {
508+
bmvdbg("Update BP SUCCESS\n");
509+
} else {
510+
bmdbg("Fail to update BP, %d\n", ret);
511+
}
512+
513+
send_response:
514+
if (bootparam) {
515+
kmm_free(bootparam);
516+
}
517+
response_msg.result = ret;
518+
snprintf(q_name, BIN_PRIVMQ_LEN, "%s%d", BINMGR_RESPONSE_MQ_PREFIX, requester_pid);
519+
binary_manager_send_response(q_name, &response_msg, sizeof(binmgr_response_t));
520+
}

0 commit comments

Comments
 (0)