system/core
Revision | 85f2319b3b1562b50d95f2d4078043bbbf6957a1 (tree) |
---|---|
Zeit | 2017-09-21 12:37:47 |
Autor | Yu Ning <yu.ning@inte...> |
Commiter | Chih-Wei Huang |
Allow the use of a custom Android DT directory
On platforms that use ACPI instead of Device Tree (DT), such as
Ranchu x86/x86_64, /proc/device-tree/firmware/android/ does not
exist. As a result, Android O is unable to mount /system, etc.
at the first stage of init:
Those platforms may create another directory that mimics the layout
of the standard DT directory in procfs, and store early mount
configuration there. E.g., Ranchu x86/x86_64 creates one in sysfs
using information encoded in the ACPI tables:
Therefore, instead of hardcoding the Android DT path, load it from
the kernel command line using a new Android-specific property key
("androidboot.android_dt_dir"). If no such property exists, fall
back to the standard procfs path (so no change is needed for DT-
aware platforms).
Note that init/ and fs_mgr/ each have their own copy of the Android
DT path, because they do not share any global state. A future CL
should remove the duplication by refactoring.
With this CL as well as the above ones, the said warning is gone,
but early mount fails. That is a separate bug, though, and will be
addressed by another CL.
Test: Boot patched sdk_phone_x86-userdebug system image with patched
Signed-off-by: Yu Ning <yu.ning@intel.com>
(cherry picked from commit c08d2cb0fb7ce470e128c7571553aa12ae9b57a4)
Change-Id: Ia8d5f68e044fde0ecf5c7b14e40f040ff42bc35d
@@ -21,19 +21,11 @@ | ||
21 | 21 | |
22 | 22 | #include "fs_mgr_priv.h" |
23 | 23 | |
24 | -// Tries to get the boot config value in properties, kernel cmdline and | |
25 | -// device tree (in that order). returns 'true' if successfully found, 'false' | |
26 | -// otherwise | |
27 | -bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val) { | |
24 | +// Tries to get the given boot config value from kernel cmdline. | |
25 | +// Returns true if successfully found, false otherwise. | |
26 | +bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::string* out_val) { | |
28 | 27 | FS_MGR_CHECK(out_val != nullptr); |
29 | 28 | |
30 | - // first check if we have "ro.boot" property already | |
31 | - *out_val = android::base::GetProperty("ro.boot." + key, ""); | |
32 | - if (!out_val->empty()) { | |
33 | - return true; | |
34 | - } | |
35 | - | |
36 | - // fallback to kernel cmdline, properties may not be ready yet | |
37 | 29 | std::string cmdline; |
38 | 30 | std::string cmdline_key("androidboot." + key); |
39 | 31 | if (android::base::ReadFileToString("/proc/cmdline", &cmdline)) { |
@@ -48,10 +40,29 @@ bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val) { | ||
48 | 40 | } |
49 | 41 | } |
50 | 42 | |
43 | + return false; | |
44 | +} | |
45 | + | |
46 | +// Tries to get the boot config value in properties, kernel cmdline and | |
47 | +// device tree (in that order). returns 'true' if successfully found, 'false' | |
48 | +// otherwise | |
49 | +bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val) { | |
50 | + FS_MGR_CHECK(out_val != nullptr); | |
51 | + | |
52 | + // first check if we have "ro.boot" property already | |
53 | + *out_val = android::base::GetProperty("ro.boot." + key, ""); | |
54 | + if (!out_val->empty()) { | |
55 | + return true; | |
56 | + } | |
57 | + | |
58 | + // fallback to kernel cmdline, properties may not be ready yet | |
59 | + if (fs_mgr_get_boot_config_from_kernel_cmdline(key, out_val)) { | |
60 | + return true; | |
61 | + } | |
62 | + | |
51 | 63 | // lastly, check the device tree |
52 | 64 | if (is_dt_compatible()) { |
53 | - std::string file_name = kAndroidDtDir + "/" + key; | |
54 | - // DT entries terminate with '\0' but so do the properties | |
65 | + std::string file_name = get_android_dt_dir() + "/" + key; | |
55 | 66 | if (android::base::ReadFileToString(file_name, out_val)) { |
56 | 67 | return true; |
57 | 68 | } |
@@ -29,6 +29,8 @@ | ||
29 | 29 | |
30 | 30 | #include "fs_mgr_priv.h" |
31 | 31 | |
32 | +const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android"); | |
33 | + | |
32 | 34 | struct fs_mgr_flag_values { |
33 | 35 | char *key_loc; |
34 | 36 | char *verity_loc; |
@@ -358,9 +360,26 @@ static int parse_flags(char *flags, struct flag_list *fl, | ||
358 | 360 | return f; |
359 | 361 | } |
360 | 362 | |
363 | +static std::string init_android_dt_dir() { | |
364 | + std::string android_dt_dir; | |
365 | + // The platform may specify a custom Android DT path in kernel cmdline | |
366 | + if (!fs_mgr_get_boot_config_from_kernel_cmdline("android_dt_dir", &android_dt_dir)) { | |
367 | + // Fall back to the standard procfs-based path | |
368 | + android_dt_dir = kDefaultAndroidDtDir; | |
369 | + } | |
370 | + return android_dt_dir; | |
371 | +} | |
372 | + | |
373 | +// FIXME: The same logic is duplicated in system/core/init/ | |
374 | +const std::string& get_android_dt_dir() { | |
375 | + // Set once and saves time for subsequent calls to this function | |
376 | + static const std::string kAndroidDtDir = init_android_dt_dir(); | |
377 | + return kAndroidDtDir; | |
378 | +} | |
379 | + | |
361 | 380 | static bool is_dt_fstab_compatible() { |
362 | 381 | std::string dt_value; |
363 | - std::string file_name = kAndroidDtDir + "/fstab/compatible"; | |
382 | + std::string file_name = get_android_dt_dir() + "/fstab/compatible"; | |
364 | 383 | if (read_dt_file(file_name, &dt_value)) { |
365 | 384 | if (dt_value == "android,fstab") { |
366 | 385 | return true; |
@@ -376,7 +395,7 @@ static std::string read_fstab_from_dt() { | ||
376 | 395 | return fstab; |
377 | 396 | } |
378 | 397 | |
379 | - std::string fstabdir_name = kAndroidDtDir + "/fstab"; | |
398 | + std::string fstabdir_name = get_android_dt_dir() + "/fstab"; | |
380 | 399 | std::unique_ptr<DIR, int (*)(DIR*)> fstabdir(opendir(fstabdir_name.c_str()), closedir); |
381 | 400 | if (!fstabdir) return fstab; |
382 | 401 |
@@ -447,7 +466,7 @@ static std::string read_fstab_from_dt() { | ||
447 | 466 | } |
448 | 467 | |
449 | 468 | bool is_dt_compatible() { |
450 | - std::string file_name = kAndroidDtDir + "/compatible"; | |
469 | + std::string file_name = get_android_dt_dir() + "/compatible"; | |
451 | 470 | std::string dt_value; |
452 | 471 | if (read_dt_file(file_name, &dt_value)) { |
453 | 472 | if (dt_value == "android,firmware") { |
@@ -113,6 +113,7 @@ | ||
113 | 113 | int fs_mgr_set_blk_ro(const char *blockdev); |
114 | 114 | int fs_mgr_test_access(const char *device); |
115 | 115 | bool fs_mgr_update_for_slotselect(struct fstab *fstab); |
116 | +const std::string& get_android_dt_dir(); | |
116 | 117 | bool is_dt_compatible(); |
117 | 118 | bool is_device_secure(); |
118 | 119 | int load_verity_state(struct fstab_rec* fstab, int* mode); |
@@ -20,8 +20,7 @@ | ||
20 | 20 | #include <sys/cdefs.h> |
21 | 21 | #include <string> |
22 | 22 | |
23 | -const std::string kAndroidDtDir("/proc/device-tree/firmware/android"); | |
24 | - | |
23 | +bool fs_mgr_get_boot_config_from_kernel_cmdline(const std::string& key, std::string* out_val); | |
25 | 24 | bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val); |
26 | 25 | |
27 | 26 | #endif /* __CORE_FS_MGR_PRIV_BOOTCONFIG_H */ |
@@ -489,7 +489,7 @@ static void process_kernel_dt() { | ||
489 | 489 | return; |
490 | 490 | } |
491 | 491 | |
492 | - std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(kAndroidDtDir.c_str()), closedir); | |
492 | + std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(init_get_android_dt_dir().c_str()), closedir); | |
493 | 493 | if (!dir) return; |
494 | 494 | |
495 | 495 | std::string dt_file; |
@@ -499,7 +499,7 @@ static void process_kernel_dt() { | ||
499 | 499 | continue; |
500 | 500 | } |
501 | 501 | |
502 | - std::string file_name = kAndroidDtDir + dp->d_name; | |
502 | + std::string file_name = init_get_android_dt_dir() + dp->d_name; | |
503 | 503 | |
504 | 504 | android::base::ReadFileToString(file_name, &dt_file); |
505 | 505 | std::replace(dt_file.begin(), dt_file.end(), ',', '.'); |
@@ -52,6 +52,8 @@ | ||
52 | 52 | #include "reboot.h" |
53 | 53 | #include "util.h" |
54 | 54 | |
55 | +const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android/"); | |
56 | + | |
55 | 57 | static unsigned int do_decode_uid(const char *s) |
56 | 58 | { |
57 | 59 | unsigned int v; |
@@ -422,10 +424,31 @@ std::ostream& operator<<(std::ostream& os, const Timer& t) { | ||
422 | 424 | return os; |
423 | 425 | } |
424 | 426 | |
425 | -// Reads the content of device tree file under kAndroidDtDir directory. | |
427 | +static std::string init_android_dt_dir() { | |
428 | + // Use the standard procfs-based path by default | |
429 | + std::string android_dt_dir = kDefaultAndroidDtDir; | |
430 | + // The platform may specify a custom Android DT path in kernel cmdline | |
431 | + import_kernel_cmdline(false, | |
432 | + [&](const std::string& key, const std::string& value, bool in_qemu) { | |
433 | + if (key == "androidboot.android_dt_dir") { | |
434 | + android_dt_dir = value; | |
435 | + } | |
436 | + }); | |
437 | + LOG(INFO) << "Using Android DT directory " << android_dt_dir; | |
438 | + return android_dt_dir; | |
439 | +} | |
440 | + | |
441 | +// FIXME: The same logic is duplicated in system/core/fs_mgr/ | |
442 | +const std::string& init_get_android_dt_dir() { | |
443 | + // Set once and saves time for subsequent calls to this function | |
444 | + static const std::string kAndroidDtDir = init_android_dt_dir(); | |
445 | + return kAndroidDtDir; | |
446 | +} | |
447 | + | |
448 | +// Reads the content of device tree file under the platform's Android DT directory. | |
426 | 449 | // Returns true if the read is success, false otherwise. |
427 | 450 | bool read_android_dt_file(const std::string& sub_path, std::string* dt_content) { |
428 | - const std::string file_name = kAndroidDtDir + sub_path; | |
451 | + const std::string file_name = init_get_android_dt_dir() + sub_path; | |
429 | 452 | if (android::base::ReadFileToString(file_name, dt_content)) { |
430 | 453 | if (!dt_content->empty()) { |
431 | 454 | dt_content->pop_back(); // Trims the trailing '\0' out. |
@@ -27,8 +27,6 @@ | ||
27 | 27 | |
28 | 28 | #define COLDBOOT_DONE "/dev/.coldboot_done" |
29 | 29 | |
30 | -const std::string kAndroidDtDir("/proc/device-tree/firmware/android/"); | |
31 | - | |
32 | 30 | using namespace std::chrono_literals; |
33 | 31 | |
34 | 32 | int create_socket(const char *name, int type, mode_t perm, |
@@ -82,7 +80,10 @@ bool expand_props(const std::string& src, std::string* dst); | ||
82 | 80 | |
83 | 81 | void panic() __attribute__((__noreturn__)); |
84 | 82 | |
85 | -// Reads or compares the content of device tree file under kAndroidDtDir directory. | |
83 | +// Returns the platform's Android DT directory as specified in the kernel cmdline. | |
84 | +// If the platform does not configure a custom DT path, returns the standard one (based in procfs). | |
85 | +const std::string& init_get_android_dt_dir(); | |
86 | +// Reads or compares the content of device tree file under the platform's Android DT directory. | |
86 | 87 | bool read_android_dt_file(const std::string& sub_path, std::string* dt_content); |
87 | 88 | bool is_android_dt_value_expected(const std::string& sub_path, const std::string& expected_content); |
88 | 89 |