• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/core


Commit MetaInfo

Revision85f2319b3b1562b50d95f2d4078043bbbf6957a1 (tree)
Zeit2017-09-21 12:37:47
AutorYu Ning <yu.ning@inte...>
CommiterChih-Wei Huang

Log Message

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:

init: First stage mount skipped (missing/incompatible fstab in
device tree)

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

Goldfish 3.18 x86 kernel in patched Android Emulator, verify
the "init: First stage mount skipped" warning no longer shows
in dmesg.

Signed-off-by: Yu Ning <yu.ning@intel.com>

(cherry picked from commit c08d2cb0fb7ce470e128c7571553aa12ae9b57a4)

Change-Id: Ia8d5f68e044fde0ecf5c7b14e40f040ff42bc35d

Ändern Zusammenfassung

Diff

--- a/fs_mgr/fs_mgr_boot_config.cpp
+++ b/fs_mgr/fs_mgr_boot_config.cpp
@@ -21,19 +21,11 @@
2121
2222 #include "fs_mgr_priv.h"
2323
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) {
2827 FS_MGR_CHECK(out_val != nullptr);
2928
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
3729 std::string cmdline;
3830 std::string cmdline_key("androidboot." + key);
3931 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) {
4840 }
4941 }
5042
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+
5163 // lastly, check the device tree
5264 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;
5566 if (android::base::ReadFileToString(file_name, out_val)) {
5667 return true;
5768 }
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -29,6 +29,8 @@
2929
3030 #include "fs_mgr_priv.h"
3131
32+const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android");
33+
3234 struct fs_mgr_flag_values {
3335 char *key_loc;
3436 char *verity_loc;
@@ -358,9 +360,26 @@ static int parse_flags(char *flags, struct flag_list *fl,
358360 return f;
359361 }
360362
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+
361380 static bool is_dt_fstab_compatible() {
362381 std::string dt_value;
363- std::string file_name = kAndroidDtDir + "/fstab/compatible";
382+ std::string file_name = get_android_dt_dir() + "/fstab/compatible";
364383 if (read_dt_file(file_name, &dt_value)) {
365384 if (dt_value == "android,fstab") {
366385 return true;
@@ -376,7 +395,7 @@ static std::string read_fstab_from_dt() {
376395 return fstab;
377396 }
378397
379- std::string fstabdir_name = kAndroidDtDir + "/fstab";
398+ std::string fstabdir_name = get_android_dt_dir() + "/fstab";
380399 std::unique_ptr<DIR, int (*)(DIR*)> fstabdir(opendir(fstabdir_name.c_str()), closedir);
381400 if (!fstabdir) return fstab;
382401
@@ -447,7 +466,7 @@ static std::string read_fstab_from_dt() {
447466 }
448467
449468 bool is_dt_compatible() {
450- std::string file_name = kAndroidDtDir + "/compatible";
469+ std::string file_name = get_android_dt_dir() + "/compatible";
451470 std::string dt_value;
452471 if (read_dt_file(file_name, &dt_value)) {
453472 if (dt_value == "android,firmware") {
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -113,6 +113,7 @@
113113 int fs_mgr_set_blk_ro(const char *blockdev);
114114 int fs_mgr_test_access(const char *device);
115115 bool fs_mgr_update_for_slotselect(struct fstab *fstab);
116+const std::string& get_android_dt_dir();
116117 bool is_dt_compatible();
117118 bool is_device_secure();
118119 int load_verity_state(struct fstab_rec* fstab, int* mode);
--- a/fs_mgr/fs_mgr_priv_boot_config.h
+++ b/fs_mgr/fs_mgr_priv_boot_config.h
@@ -20,8 +20,7 @@
2020 #include <sys/cdefs.h>
2121 #include <string>
2222
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);
2524 bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val);
2625
2726 #endif /* __CORE_FS_MGR_PRIV_BOOTCONFIG_H */
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -489,7 +489,7 @@ static void process_kernel_dt() {
489489 return;
490490 }
491491
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);
493493 if (!dir) return;
494494
495495 std::string dt_file;
@@ -499,7 +499,7 @@ static void process_kernel_dt() {
499499 continue;
500500 }
501501
502- std::string file_name = kAndroidDtDir + dp->d_name;
502+ std::string file_name = init_get_android_dt_dir() + dp->d_name;
503503
504504 android::base::ReadFileToString(file_name, &dt_file);
505505 std::replace(dt_file.begin(), dt_file.end(), ',', '.');
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -52,6 +52,8 @@
5252 #include "reboot.h"
5353 #include "util.h"
5454
55+const std::string kDefaultAndroidDtDir("/proc/device-tree/firmware/android/");
56+
5557 static unsigned int do_decode_uid(const char *s)
5658 {
5759 unsigned int v;
@@ -422,10 +424,31 @@ std::ostream& operator<<(std::ostream& os, const Timer& t) {
422424 return os;
423425 }
424426
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.
426449 // Returns true if the read is success, false otherwise.
427450 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;
429452 if (android::base::ReadFileToString(file_name, dt_content)) {
430453 if (!dt_content->empty()) {
431454 dt_content->pop_back(); // Trims the trailing '\0' out.
--- a/init/util.h
+++ b/init/util.h
@@ -27,8 +27,6 @@
2727
2828 #define COLDBOOT_DONE "/dev/.coldboot_done"
2929
30-const std::string kAndroidDtDir("/proc/device-tree/firmware/android/");
31-
3230 using namespace std::chrono_literals;
3331
3432 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);
8280
8381 void panic() __attribute__((__noreturn__));
8482
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.
8687 bool read_android_dt_file(const std::string& sub_path, std::string* dt_content);
8788 bool is_android_dt_value_expected(const std::string& sub_path, const std::string& expected_content);
8889