-
Notifications
You must be signed in to change notification settings - Fork 604
binary_manager: Support new APIs for partition swap #6706
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -244,3 +244,66 @@ binmgr_result_type_e binary_manager_get_current_path(char *binary_name, char *do | |
|
||
return response_msg.result; | ||
} | ||
|
||
binmgr_result_type_e binary_manager_swap_partition(void) | ||
{ | ||
#ifndef CONFIG_USE_BP | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about locating positive case first? Because |
||
/* In the case of 3.1 bootloader, we dont have bp. So we need not | ||
* update the bp to swap partitions, it is automatically done on | ||
* reboot, so return success */ | ||
return BINMGR_OK; | ||
#else | ||
binmgr_result_type_e ret; | ||
binmgr_request_t request_msg; | ||
binmgr_setbp_response_t response_msg; | ||
|
||
ret = binary_manager_set_request(&request_msg, BINMGR_SWAPBP, NULL); | ||
if (ret != BINMGR_OK) { | ||
return ret; | ||
} | ||
|
||
ret = binary_manager_send_request(&request_msg); | ||
if (ret != BINMGR_OK) { | ||
return ret; | ||
} | ||
|
||
ret = binary_manager_receive_response(&response_msg, sizeof(binmgr_response_t)); | ||
if (ret != BINMGR_OK) { | ||
return ret; | ||
} | ||
|
||
return response_msg.result; | ||
#endif | ||
} | ||
|
||
binmgr_result_type_e binary_manager_get_inactive_info_all(binary_update_info_list_t *binary_info_list) | ||
{ | ||
binmgr_result_type_e ret; | ||
binmgr_request_t request_msg; | ||
binmgr_getinfo_all_response_t response_msg; | ||
|
||
ret = binary_manager_set_request(&request_msg, BINMGR_GET_INFO_INACTIVE_ALL, NULL); | ||
if (ret != BINMGR_OK) { | ||
return ret; | ||
} | ||
|
||
ret = binary_manager_send_request(&request_msg); | ||
if (ret != BINMGR_OK) { | ||
return ret; | ||
} | ||
|
||
ret = binary_manager_receive_response(&response_msg, sizeof(binmgr_getinfo_all_response_t)); | ||
if (ret != BINMGR_OK) { | ||
return ret; | ||
} | ||
|
||
if (response_msg.result == BINMGR_OK) { | ||
/* Copy binary info list data */ | ||
memset(binary_info_list, 0, sizeof(binary_update_info_list_t)); | ||
memcpy(binary_info_list, &response_msg.data, sizeof(binary_update_info_list_t)); | ||
} else { | ||
bmdbg("Binary manager getinfo_inactive_all FAIL %d\n", response_msg.result); | ||
} | ||
|
||
return response_msg.result; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,10 @@ | |
#include <limits.h> | ||
#include <stdbool.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#ifdef CONFIG_BINARY_MANAGER | ||
/**************************************************************************** | ||
* Pre-processor Definitions | ||
|
@@ -125,6 +129,10 @@ enum binmgr_request_msg_type { | |
#ifdef CONFIG_BINMGR_RECOVERY | ||
BINMGR_FAULT, | ||
#endif | ||
#ifdef CONFIG_USE_BP | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In enum, I wanna remove conditionals. |
||
BINMGR_SWAPBP, | ||
#endif | ||
BINMGR_GET_INFO_INACTIVE_ALL, | ||
}; | ||
|
||
/* Result values of returned from binary manager. */ | ||
|
@@ -254,6 +262,11 @@ struct binmgr_request_s { | |
}; | ||
typedef struct binmgr_request_s binmgr_request_t; | ||
|
||
struct binmgr_response_s { | ||
binmgr_result_type_e result; | ||
}; | ||
typedef struct binmgr_response_s binmgr_response_t; | ||
|
||
struct binmgr_setbp_response_s { | ||
binmgr_result_type_e result; | ||
binary_setbp_result_t data; | ||
|
@@ -300,14 +313,6 @@ void binary_manager_register_respart(int part_num, int part_size, uint32_t part_ | |
int binary_manager_mount_resource(void); | ||
void binary_manager_deinit_modules(void); | ||
|
||
#ifdef __cplusplus | ||
#define EXTERN extern "C" | ||
extern "C" { | ||
#else | ||
#define EXTERN extern | ||
#endif | ||
|
||
#undef EXTERN | ||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ | |
#include <stdbool.h> | ||
|
||
#include <tinyara/binary_manager.h> | ||
#include <tinyara/reboot_reason.h> | ||
|
||
#include "binary_manager.h" | ||
|
||
|
@@ -284,8 +285,8 @@ void binary_manager_update_bootparam(int requester_pid, uint8_t type) | |
|
||
if (BM_CHECK_GROUP(type, BINARY_KERNEL)) { | ||
/* Update bootparam and Reboot if new kernel binary exists */ | ||
ret = binary_manager_check_kernel_update(); | ||
if (ret == BINMGR_OK) { | ||
ret = binary_manager_check_kernel_update(true); | ||
if (ret > 0) { | ||
/* Update index for inactive partition */ | ||
update_bp_data.active_idx ^= 1; | ||
} 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) | |
#ifdef CONFIG_RESOURCE_FS | ||
if (BM_CHECK_GROUP(type, BINARY_RESOURCE)) { | ||
/* Update bootparam if new resource binary exists */ | ||
ret = binary_manager_check_resource_update(); | ||
if (ret == BINMGR_OK) { | ||
ret = binary_manager_check_resource_update(true); | ||
if (ret > 0) { | ||
/* Update index for inactive partition */ | ||
update_bp_data.resource_active_idx ^= 1; | ||
} 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) | |
/* Reload binaries if new binary is scanned */ | ||
for (bin_idx = 1; bin_idx <= bin_count; bin_idx++) { | ||
/* Scan binary files */ | ||
ret = binary_manager_check_user_update(bin_idx); | ||
if (ret == BINMGR_OK) { | ||
ret = binary_manager_check_user_update(bin_idx, true); | ||
if (ret > 0) { | ||
/* Update index for inactive partition */ | ||
update_bp_data.app_data[BIN_BPIDX(bin_idx)].useidx ^= 1; | ||
need_update = true; | ||
|
@@ -345,8 +346,8 @@ void binary_manager_update_bootparam(int requester_pid, uint8_t type) | |
|
||
#ifdef CONFIG_SUPPORT_COMMON_BINARY | ||
if (BM_CHECK_GROUP(type, BINARY_COMMON)) { | ||
ret = binary_manager_check_user_update(BM_CMNLIB_IDX); | ||
if (ret == BINMGR_OK) { | ||
ret = binary_manager_check_user_update(BM_CMNLIB_IDX, true); | ||
if (ret > 0) { | ||
/* Update index for inactive partition */ | ||
update_bp_data.app_data[BIN_BPIDX(BM_CMNLIB_IDX)].useidx ^= 1; | ||
} 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) | |
} | ||
|
||
send_response: | ||
kmm_free(bootparam); | ||
if (bootparam) { | ||
kmm_free(bootparam); | ||
} | ||
response_msg.result = ret; | ||
snprintf(q_name, BIN_PRIVMQ_LEN, "%s%d", BINMGR_RESPONSE_MQ_PREFIX, requester_pid); | ||
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) | |
{ | ||
g_bp_info.inuse_idx = index; | ||
} | ||
|
||
void binary_manager_swap_bootparam(int requester_pid) | ||
{ | ||
int ret; | ||
char *bootparam; | ||
bool is_all_updatable; | ||
char q_name[BIN_PRIVMQ_LEN]; | ||
binmgr_bpdata_t update_bp_data; | ||
binmgr_response_t response_msg; | ||
#ifdef CONFIG_APP_BINARY_SEPARATION | ||
int bin_idx; | ||
uint32_t bin_count; | ||
#endif | ||
|
||
memset((void *)&response_msg, 0, sizeof(binmgr_response_t)); | ||
|
||
if (requester_pid < 0) { | ||
bmdbg("Invalid requester pid %d\n", requester_pid); | ||
return; | ||
} | ||
|
||
bootparam = (char *)kmm_malloc(BOOTPARAM_SIZE); | ||
if (!bootparam) { | ||
bmdbg("Fail to malloc to read BP\n"); | ||
ret = BINMGR_OUT_OF_MEMORY; | ||
goto send_response; | ||
} | ||
memset(bootparam, 0xff, BOOTPARAM_SIZE); | ||
|
||
response_msg.result = BINMGR_OK; | ||
is_all_updatable = true; | ||
|
||
/* Get current bootparam data */ | ||
memcpy(&update_bp_data, binary_manager_get_bpdata(), sizeof(binmgr_bpdata_t)); | ||
update_bp_data.version++; | ||
|
||
/* Update bootparam and Reboot if valid kernel binary exists */ | ||
ret = binary_manager_check_kernel_update(false); | ||
if (ret < 0) { | ||
bmdbg("Fail to find valid kernel binary, %d\n", ret); | ||
goto send_response; | ||
} | ||
update_bp_data.active_idx ^= 1; | ||
|
||
#ifdef CONFIG_RESOURCE_FS | ||
/* Update bootparam if valid resource binary exists */ | ||
ret = binary_manager_check_resource_update(false); | ||
if (ret < 0) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When we get failure at somewhere, kernel update or resource update or user update, can we know which gets failure? |
||
bmdbg("Fail to find valid resource binary, %d\n", ret); | ||
goto send_response; | ||
} | ||
update_bp_data.resource_active_idx ^= 1; | ||
#endif | ||
|
||
#ifdef CONFIG_APP_BINARY_SEPARATION | ||
bin_count = binary_manager_get_ucount(); | ||
for (bin_idx = 1; bin_idx <= bin_count; bin_idx++) { | ||
/* Scan binary files */ | ||
ret = binary_manager_check_user_update(bin_idx, false); | ||
if (ret < 0) { | ||
bmdbg("Fail to find valid user binary, %d\n", ret); | ||
goto send_response; | ||
} | ||
update_bp_data.app_data[BIN_BPIDX(bin_idx)].useidx ^= 1; | ||
} | ||
|
||
#ifdef CONFIG_SUPPORT_COMMON_BINARY | ||
ret = binary_manager_check_user_update(BM_CMNLIB_IDX, false); | ||
if (ret < 0) { | ||
bmdbg("Fail to find valid common binary, %d\n", ret); | ||
goto send_response; | ||
} | ||
update_bp_data.app_data[BIN_BPIDX(BM_CMNLIB_IDX)].useidx ^= 1; | ||
#endif | ||
#endif | ||
|
||
/* Then, Write bootparam with updated bootparam data */ | ||
memcpy(bootparam, &update_bp_data, sizeof(binmgr_bpdata_t)); | ||
ret = binary_manager_write_bootparam(bootparam); | ||
if (ret == BINMGR_OK) { | ||
bmvdbg("Update BP SUCCESS\n"); | ||
} else { | ||
bmdbg("Fail to update BP, %d\n", ret); | ||
} | ||
|
||
send_response: | ||
if (bootparam) { | ||
kmm_free(bootparam); | ||
} | ||
response_msg.result = ret; | ||
snprintf(q_name, BIN_PRIVMQ_LEN, "%s%d", BINMGR_RESPONSE_MQ_PREFIX, requester_pid); | ||
binary_manager_send_response(q_name, &response_msg, sizeof(binmgr_response_t)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this necessary? It looks that
default
covers.