summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu-Ping Wu <yupingso@chromium.org>2021-10-13 11:02:20 +0800
committerCommit Bot <commit-bot@chromium.org>2021-10-15 09:06:41 +0000
commit2d1ce45dc46b0dd5522edf1edabef35b90a66942 (patch)
tree79b805d4776f9432c1ecb35fb5a49c4d399aaeb5
parent1269365169791c65a6bf6f364583209195874138 (diff)
downloadvboot-2d1ce45dc46b0dd5522edf1edabef35b90a66942.tar.gz
vboot: Support booting from non-active miniOS partition
To support booting from the non-active miniOS partition in recovery UI, add minios_flags argument to VbTryLoadMiniOsKernel. Currently there is only one flag: VB_MINIOS_FLAG_NON_ACTIVE. When it is set, we will attempt to boot from the non-active partition only. BUG=b:200750322 TEST=make runtests BRANCH=none Cq-Depend: chromium:3219727 Change-Id: I6221f10c09de2487e89e6113981bc9e9755d67f4 Signed-off-by: Yu-Ping Wu <yupingso@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/vboot_reference/+/3219901 Reviewed-by: Julius Werner <jwerner@chromium.org> Reviewed-by: Jae Hoon Kim <kimjae@chromium.org>
-rw-r--r--firmware/include/vboot_api.h9
-rw-r--r--firmware/lib/include/load_kernel_fw.h3
-rw-r--r--firmware/lib/vboot_api_kernel.c12
-rw-r--r--firmware/lib/vboot_kernel.c9
-rw-r--r--tests/vboot_api_kernel_tests.c4
-rw-r--r--tests/vboot_kernel2_tests.c59
6 files changed, 66 insertions, 30 deletions
diff --git a/firmware/include/vboot_api.h b/firmware/include/vboot_api.h
index f19ee747..1fee766d 100644
--- a/firmware/include/vboot_api.h
+++ b/firmware/include/vboot_api.h
@@ -89,6 +89,11 @@ vb2_error_t VbSelectAndLoadKernel(struct vb2_context *ctx,
*/
vb2_error_t VbTryLoadKernel(struct vb2_context *ctx, uint32_t disk_flags);
+/* miniOS flags */
+
+/* Boot from non-active miniOS partition only */
+#define VB_MINIOS_FLAG_NON_ACTIVE (1 << 0)
+
/**
* Attempt loading a miniOS kernel from internal disk.
*
@@ -100,9 +105,11 @@ vb2_error_t VbTryLoadKernel(struct vb2_context *ctx, uint32_t disk_flags);
* VB2_SUCCESS.
*
* @param ctx Vboot context
+ * @param minios_flags Flags for miniOS
* @return VB2_SUCCESS or the most specific VB2_ERROR_LK error.
*/
-vb2_error_t VbTryLoadMiniOsKernel(struct vb2_context *ctx);
+vb2_error_t VbTryLoadMiniOsKernel(struct vb2_context *ctx,
+ uint32_t minios_flags);
/*****************************************************************************/
/* Disk access (previously in boot_device.h) */
diff --git a/firmware/lib/include/load_kernel_fw.h b/firmware/lib/include/load_kernel_fw.h
index af454703..76d25560 100644
--- a/firmware/lib/include/load_kernel_fw.h
+++ b/firmware/lib/include/load_kernel_fw.h
@@ -30,11 +30,12 @@ vb2_error_t LoadKernel(struct vb2_context *ctx,
* @param ctx Vboot context
* @param params Params specific to loading the kernel
* @param disk_info Disk from which to read kernel
+ * @param minios_flags Flags for miniOS
*
* Returns VB2_SUCCESS if successful. If unsuccessful, returns an error code.
*/
vb2_error_t LoadMiniOsKernel(struct vb2_context *ctx,
VbSelectAndLoadKernelParams *params,
- VbDiskInfo *disk_info);
+ VbDiskInfo *disk_info, uint32_t minios_flags);
#endif /* VBOOT_REFERENCE_LOAD_KERNEL_FW_H_ */
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index 2abd57eb..54447c26 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -62,7 +62,8 @@ static int is_valid_disk(VbDiskInfo *info, uint32_t disk_flags)
}
static vb2_error_t VbTryLoadKernelImpl(struct vb2_context *ctx,
- uint32_t disk_flags, int minios)
+ uint32_t disk_flags, int minios,
+ uint32_t minios_flags)
{
vb2_error_t rv = VB2_ERROR_LK_NO_DISK_FOUND;
VbDiskInfo* disk_info = NULL;
@@ -96,7 +97,7 @@ static vb2_error_t VbTryLoadKernelImpl(struct vb2_context *ctx,
if (minios) {
new_rv = LoadMiniOsKernel(ctx, kparams_ptr,
- &disk_info[i]);
+ &disk_info[i], minios_flags);
VB2_DEBUG("LoadMiniOsKernel() = %#x\n", new_rv);
} else {
new_rv = LoadKernel(ctx, kparams_ptr, &disk_info[i]);
@@ -142,13 +143,14 @@ static vb2_error_t VbTryLoadKernelImpl(struct vb2_context *ctx,
test_mockable
vb2_error_t VbTryLoadKernel(struct vb2_context *ctx, uint32_t disk_flags)
{
- return VbTryLoadKernelImpl(ctx, disk_flags, 0);
+ return VbTryLoadKernelImpl(ctx, disk_flags, 0, 0);
}
test_mockable
-vb2_error_t VbTryLoadMiniOsKernel(struct vb2_context *ctx)
+vb2_error_t VbTryLoadMiniOsKernel(struct vb2_context *ctx,
+ uint32_t minios_flags)
{
- return VbTryLoadKernelImpl(ctx, VB_DISK_FLAG_FIXED, 1);
+ return VbTryLoadKernelImpl(ctx, VB_DISK_FLAG_FIXED, 1, minios_flags);
}
vb2_error_t VbSelectAndLoadKernel(struct vb2_context *ctx,
diff --git a/firmware/lib/vboot_kernel.c b/firmware/lib/vboot_kernel.c
index 34a8a426..cb83d40d 100644
--- a/firmware/lib/vboot_kernel.c
+++ b/firmware/lib/vboot_kernel.c
@@ -607,12 +607,17 @@ static vb2_error_t try_minios_sector_region(struct vb2_context *ctx,
*/
vb2_error_t LoadMiniOsKernel(struct vb2_context *ctx,
VbSelectAndLoadKernelParams *params,
- VbDiskInfo *disk_info)
+ VbDiskInfo *disk_info, uint32_t minios_flags)
{
vb2_error_t rv;
int end_region_first = vb2_nv_get(ctx, VB2_NV_MINIOS_PRIORITY);
- rv = try_minios_sector_region(ctx, params, disk_info, end_region_first);
+ if (minios_flags & VB_MINIOS_FLAG_NON_ACTIVE)
+ rv = VB2_ERROR_UNKNOWN; /* Ignore active partition */
+ else
+ rv = try_minios_sector_region(ctx, params, disk_info,
+ end_region_first);
+
if (rv)
rv = try_minios_sector_region(ctx, params, disk_info,
!end_region_first);
diff --git a/tests/vboot_api_kernel_tests.c b/tests/vboot_api_kernel_tests.c
index 51f0ddb1..b66c4320 100644
--- a/tests/vboot_api_kernel_tests.c
+++ b/tests/vboot_api_kernel_tests.c
@@ -563,7 +563,7 @@ vb2_error_t LoadKernel(struct vb2_context *c,
vb2_error_t LoadMiniOsKernel(struct vb2_context *c,
VbSelectAndLoadKernelParams *params,
- VbDiskInfo *disk_info)
+ VbDiskInfo *disk_info, uint32_t minios_flags)
{
lk_minios_calls++;
return LoadKernelImpl(c, params, disk_info);
@@ -616,7 +616,7 @@ static void VbTryLoadMiniOsKernelTest(void)
printf("Test case: %s ...\n", minios_tests[i].name);
ResetMocks(&minios_tests[i]);
ctx->flags = t->ctx_flags;
- TEST_EQ(VbTryLoadMiniOsKernel(ctx),
+ TEST_EQ(VbTryLoadMiniOsKernel(ctx, 0),
t->expected_return_val, " return value");
TEST_EQ(got_recovery_request_val,
t->expected_recovery_request_val, " recovery_request");
diff --git a/tests/vboot_kernel2_tests.c b/tests/vboot_kernel2_tests.c
index 5424e86c..bc4ea0fe 100644
--- a/tests/vboot_kernel2_tests.c
+++ b/tests/vboot_kernel2_tests.c
@@ -264,7 +264,7 @@ static void load_minios_kernel_tests(void)
disk_info.bytes_per_lba = KBUF_SIZE;
disk_info.lba_count = 1;
add_mock_kernel(0, VB2_SUCCESS);
- TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
"{valid kernel}");
TEST_EQ(mock_tpm_set_mode_calls, 1,
" TPM disabled");
@@ -272,7 +272,7 @@ static void load_minios_kernel_tests(void)
reset_common_data();
disk_info.bytes_per_lba = KBUF_SIZE;
disk_info.lba_count = 1;
- TEST_EQ(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_EQ(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
VB2_ERROR_LK_NO_KERNEL_FOUND, "{no kernel}");
TEST_EQ(mock_tpm_set_mode_calls, 0,
" TPM not disabled");
@@ -281,7 +281,7 @@ static void load_minios_kernel_tests(void)
disk_info.bytes_per_lba = KBUF_SIZE;
disk_info.lba_count = 2;
add_mock_kernel(1, VB2_SUCCESS);
- TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
"{no kernel, valid kernel}");
TEST_EQ(cur_kernel->sector, 1, " select kernel");
@@ -290,7 +290,7 @@ static void load_minios_kernel_tests(void)
disk_info.lba_count = 2;
add_mock_kernel(0, VB2_ERROR_MOCK);
add_mock_kernel(1, VB2_SUCCESS);
- TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
"{invalid kernel, valid kernel}");
TEST_EQ(cur_kernel->sector, 1, " select second kernel");
@@ -299,7 +299,7 @@ static void load_minios_kernel_tests(void)
disk_info.lba_count = 2;
add_mock_kernel(0, VB2_ERROR_MOCK);
add_mock_kernel(1, VB2_ERROR_MOCK);
- TEST_EQ(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_EQ(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
VB2_ERROR_LK_NO_KERNEL_FOUND,
"{invalid kernel, invalid kernel}");
TEST_EQ(mock_tpm_set_mode_calls, 0,
@@ -310,7 +310,7 @@ static void load_minios_kernel_tests(void)
disk_info.lba_count = 2;
add_mock_kernel(0, VB2_SUCCESS);
add_mock_kernel(1, VB2_SUCCESS);
- TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
"{valid kernel, valid kernel} minios_priority=0");
TEST_EQ(cur_kernel->sector, 0, " select first kernel");
@@ -320,15 +320,36 @@ static void load_minios_kernel_tests(void)
add_mock_kernel(0, VB2_SUCCESS);
add_mock_kernel(1, VB2_SUCCESS);
vb2_nv_set(ctx, VB2_NV_MINIOS_PRIORITY, 1);
- TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
"{valid kernel, valid kernel} minios_priority=1");
TEST_EQ(cur_kernel->sector, 1, " select second kernel");
reset_common_data();
+ disk_info.bytes_per_lba = KBUF_SIZE;
+ disk_info.lba_count = 2;
+ add_mock_kernel(0, VB2_SUCCESS);
+ add_mock_kernel(1, VB2_SUCCESS);
+ TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info,
+ VB_MINIOS_FLAG_NON_ACTIVE),
+ "{valid kernel, valid kernel} minios_priority=0 non-active");
+ TEST_EQ(cur_kernel->sector, 1, " select second kernel");
+
+ reset_common_data();
+ disk_info.bytes_per_lba = KBUF_SIZE;
+ disk_info.lba_count = 2;
+ add_mock_kernel(0, VB2_ERROR_MOCK);
+ add_mock_kernel(1, VB2_SUCCESS);
+ vb2_nv_set(ctx, VB2_NV_MINIOS_PRIORITY, 1);
+ TEST_EQ(LoadMiniOsKernel(ctx, &lkp, &disk_info,
+ VB_MINIOS_FLAG_NON_ACTIVE),
+ VB2_ERROR_LK_NO_KERNEL_FOUND,
+ "{invalid kernel, valid kernel} minios_priority=1 non-active");
+
+ reset_common_data();
disk_info.bytes_per_lba = VB2_KEYBLOCK_MAGIC_SIZE;
disk_info.lba_count = 4;
add_mock_kernel(1, VB2_SUCCESS);
- TEST_EQ(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_EQ(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
VB2_ERROR_LK_NO_KERNEL_FOUND,
"valid kernel header near start of disk (disk too small)");
@@ -336,7 +357,7 @@ static void load_minios_kernel_tests(void)
disk_info.bytes_per_lba = VB2_KEYBLOCK_MAGIC_SIZE;
disk_info.lba_count = 1000;
add_mock_kernel(999, VB2_SUCCESS);
- TEST_EQ(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_EQ(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
VB2_ERROR_LK_NO_KERNEL_FOUND,
"valid kernel header near end of disk");
@@ -344,35 +365,35 @@ static void load_minios_kernel_tests(void)
disk_info.bytes_per_lba = 1024;
disk_info.lba_count = 128;
add_mock_kernel(63, VB2_SUCCESS);
- TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
"start/end overlap assuming >128 MB search range (start)");
reset_common_data();
disk_info.bytes_per_lba = 1024;
disk_info.lba_count = 128;
add_mock_kernel(64, VB2_SUCCESS);
- TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
"start/end overlap assuming >128 MB search range (end)");
reset_common_data();
disk_info.bytes_per_lba = 128;
disk_info.lba_count = 1024;
add_mock_kernel(3, VB2_SUCCESS);
- TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
"kernel at last sector in batch assuming 512 KB batches");
reset_common_data();
disk_info.bytes_per_lba = 256;
disk_info.lba_count = 1024;
add_mock_kernel(3, VB2_SUCCESS);
- TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
"kernel at last sector in batch assuming 1 MB batches");
reset_common_data();
disk_info.bytes_per_lba = 512;
disk_info.lba_count = 1024;
add_mock_kernel(3, VB2_SUCCESS);
- TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
"kernel at last sector in batch assuming 2 MB batches");
reset_common_data();
@@ -382,7 +403,7 @@ static void load_minios_kernel_tests(void)
disk_info.bytes_per_lba = KBUF_SIZE;
disk_info.lba_count = 2;
add_mock_kernel(0, VB2_SUCCESS);
- TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
"kernel with minios keyblock flag");
reset_common_data();
@@ -392,7 +413,7 @@ static void load_minios_kernel_tests(void)
disk_info.bytes_per_lba = KBUF_SIZE;
disk_info.lba_count = 2;
add_mock_kernel(0, VB2_SUCCESS);
- TEST_EQ(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_EQ(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
VB2_ERROR_LK_NO_KERNEL_FOUND,
"kernel with !minios keyblock flag");
@@ -402,7 +423,7 @@ static void load_minios_kernel_tests(void)
add_mock_kernel(0, VB2_SUCCESS);
sd->kernel_version_secdata = 5 << 24;
kph.kernel_version = 4;
- TEST_EQ(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_EQ(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
VB2_ERROR_LK_NO_KERNEL_FOUND,
"kernel version too old");
@@ -412,7 +433,7 @@ static void load_minios_kernel_tests(void)
add_mock_kernel(0, VB2_SUCCESS);
sd->kernel_version_secdata = 5 << 24;
kph.kernel_version = 0x100;
- TEST_EQ(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_EQ(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
VB2_ERROR_LK_NO_KERNEL_FOUND,
"kernel version greater than 0xff");
@@ -422,7 +443,7 @@ static void load_minios_kernel_tests(void)
add_mock_kernel(0, VB2_SUCCESS);
sd->kernel_version_secdata = 5 << 24;
kph.kernel_version = 6;
- TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info),
+ TEST_SUCC(LoadMiniOsKernel(ctx, &lkp, &disk_info, 0),
"newer kernel version");
}