Add dtb test command

This commit is contained in:
topjohnwu 2022-06-15 02:26:50 -07:00
parent 1699da1754
commit db78c20161
2 changed files with 58 additions and 30 deletions

View File

@ -93,47 +93,43 @@ static int find_fstab(const void *fdt, int node = 0) {
return -1; return -1;
} }
static void dtb_print(const char *file, bool fstab) { template<typename Func>
fprintf(stderr, "Loading dtbs from [%s]\n", file); static void for_each_fdt(const char *file, bool rw, Func fn) {
auto m = mmap_data(file); auto m = mmap_data(file, rw);
// Loop through all the dtbs uint8_t *end = m.buf + m.sz;
int dtb_num = 0;
uint8_t * const end = m.buf + m.sz;
for (uint8_t *fdt = m.buf; fdt < end;) { for (uint8_t *fdt = m.buf; fdt < end;) {
fdt = static_cast<uint8_t*>(memmem(fdt, end - fdt, DTB_MAGIC, sizeof(fdt32_t))); fdt = static_cast<uint8_t*>(memmem(fdt, end - fdt, DTB_MAGIC, sizeof(fdt32_t)));
if (fdt == nullptr) if (fdt == nullptr)
break; break;
fn(fdt);
fdt += fdt_totalsize(fdt);
}
}
static void dtb_print(const char *file, bool fstab) {
fprintf(stderr, "Loading dtbs from [%s]\n", file);
int dtb_num = 0;
for_each_fdt(file, false, [&](uint8_t *fdt) {
if (fstab) { if (fstab) {
int node = find_fstab(fdt); if (int node = find_fstab(fdt); node >= 0) {
if (node >= 0) { fprintf(stderr, "Found fstab in dtb.%04d\n", dtb_num);
fprintf(stderr, "Found fstab in buf.%04d\n", dtb_num);
print_node(fdt, node); print_node(fdt, node);
} }
} else { } else {
fprintf(stderr, "Printing buf.%04d\n", dtb_num); fprintf(stderr, "Printing dtb.%04d\n", dtb_num);
print_node(fdt); print_node(fdt);
} }
++dtb_num; ++dtb_num;
fdt += fdt_totalsize(fdt); });
}
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
[[maybe_unused]]
static bool dtb_patch_rebuild(uint8_t *dtb, size_t dtb_sz, const char *file);
static bool dtb_patch(const char *file) { static bool dtb_patch(const char *file) {
bool keep_verity = check_env("KEEPVERITY");
fprintf(stderr, "Loading dtbs from [%s]\n", file); fprintf(stderr, "Loading dtbs from [%s]\n", file);
auto m = mmap_data(file, true);
bool keep_verity = check_env("KEEPVERITY");
bool patched = false; bool patched = false;
uint8_t * const end = m.buf + m.sz; for_each_fdt(file, true, [&](uint8_t *fdt) {
for (uint8_t *fdt = m.buf; fdt < end;) {
fdt = static_cast<uint8_t*>(memmem(fdt, end - fdt, DTB_MAGIC, sizeof(fdt32_t)));
if (fdt == nullptr)
break;
int node; int node;
// Patch the chosen node for bootargs // Patch the chosen node for bootargs
fdt_for_each_subnode(node, fdt, 0) { fdt_for_each_subnode(node, fdt, 0) {
@ -149,20 +145,41 @@ static bool dtb_patch(const char *file) {
} }
break; break;
} }
if (int fstab = find_fstab(fdt); fstab >= 0) { if (!keep_verity) {
fdt_for_each_subnode(node, fdt, fstab) { if (int fstab = find_fstab(fdt); fstab >= 0) {
if (!keep_verity) { fdt_for_each_subnode(node, fdt, fstab) {
int len; int len;
char *value = (char *) fdt_getprop(fdt, node, "fsmgr_flags", &len); char *value = (char *) fdt_getprop(fdt, node, "fsmgr_flags", &len);
patched |= patch_verity(value, len) != len; patched |= patch_verity(value, len) != len;
} }
} }
} }
fdt += fdt_totalsize(fdt); });
}
return patched; return patched;
} }
[[noreturn]]
static void dtb_test(const char *file) {
for_each_fdt(file, false, [&](uint8_t *fdt) {
// Find the system node in fstab
if (int fstab = find_fstab(fdt); fstab >= 0) {
int node;
fdt_for_each_subnode(node, fdt, fstab) {
if (auto name = fdt_get_name(fdt, node, nullptr); !name || name != "system"sv)
continue;
int len;
if (auto value = fdt_getprop(fdt, node, "mnt_point", &len)) {
// If mnt_point is set to /system_root, abort!
if (strncmp(static_cast<const char *>(value), "/system_root", len) == 0) {
exit(1);
}
}
}
}
});
exit(0);
}
int dtb_commands(int argc, char *argv[]) { int dtb_commands(int argc, char *argv[]) {
char *dtb = argv[0]; char *dtb = argv[0];
++argv; ++argv;
@ -175,11 +192,17 @@ int dtb_commands(int argc, char *argv[]) {
if (!dtb_patch(dtb)) if (!dtb_patch(dtb))
exit(1); exit(1);
return 0; return 0;
} else if (argv[0] == "test"sv) {
dtb_test(dtb);
} else { } else {
return 1; return 1;
} }
} }
// The following code is unused, left here for historical purpose. Since the code is
// extremely complicated, I won't want to rewrite this whole thing if somehow we need
// to use it in the future...
namespace { namespace {
struct fdt_blob { struct fdt_blob {
@ -188,8 +211,6 @@ struct fdt_blob {
uint32_t len; uint32_t len;
}; };
}
static bool fdt_patch(void *fdt) { static bool fdt_patch(void *fdt) {
int fstab = find_fstab(fdt); int fstab = find_fstab(fdt);
if (fstab < 0) if (fstab < 0)
@ -361,6 +382,7 @@ static bool blob_patch(uint8_t *dtb, size_t dtb_sz, const char *out) {
#define DTB_MATCH(s) BUFFER_MATCH(dtb, s) #define DTB_MATCH(s) BUFFER_MATCH(dtb, s)
[[maybe_unused]]
static bool dtb_patch_rebuild(uint8_t *dtb, size_t dtb_sz, const char *file) { static bool dtb_patch_rebuild(uint8_t *dtb, size_t dtb_sz, const char *file) {
if (DTB_MATCH(QCDT_MAGIC)) { if (DTB_MATCH(QCDT_MAGIC)) {
auto hdr = reinterpret_cast<qcdt_hdr*>(dtb); auto hdr = reinterpret_cast<qcdt_hdr*>(dtb);
@ -426,3 +448,5 @@ static bool dtb_patch_rebuild(uint8_t *dtb, size_t dtb_sz, const char *file) {
return blob_patch(dtb, dtb_sz, file); return blob_patch(dtb, dtb_sz, file);
} }
} }
} // namespace

View File

@ -91,6 +91,10 @@ Supported actions:
Search for fstab and remove verity/avb Search for fstab and remove verity/avb
Modifications are done directly to the file in-place Modifications are done directly to the file in-place
Configure with env variables: KEEPVERITY Configure with env variables: KEEPVERITY
test
Test the fstab's status
Return values:
0:valid 1:error
split <file> split <file>
Split image.*-dtb into kernel + kernel_dtb Split image.*-dtb into kernel + kernel_dtb