1*288bf522SAndroid Build Coastguard Worker /*
2*288bf522SAndroid Build Coastguard Worker * Copyright (C) 2022 The Android Open Source Project
3*288bf522SAndroid Build Coastguard Worker *
4*288bf522SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*288bf522SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*288bf522SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*288bf522SAndroid Build Coastguard Worker *
8*288bf522SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*288bf522SAndroid Build Coastguard Worker *
10*288bf522SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*288bf522SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*288bf522SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*288bf522SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*288bf522SAndroid Build Coastguard Worker * limitations under the License.
15*288bf522SAndroid Build Coastguard Worker */
16*288bf522SAndroid Build Coastguard Worker
17*288bf522SAndroid Build Coastguard Worker #include <getopt.h>
18*288bf522SAndroid Build Coastguard Worker #include <unistd.h>
19*288bf522SAndroid Build Coastguard Worker
20*288bf522SAndroid Build Coastguard Worker #include <android-base/file.h>
21*288bf522SAndroid Build Coastguard Worker #include <android-base/logging.h>
22*288bf522SAndroid Build Coastguard Worker #include <android-base/properties.h>
23*288bf522SAndroid Build Coastguard Worker #include <android-base/strings.h>
24*288bf522SAndroid Build Coastguard Worker #include <android-base/unique_fd.h>
25*288bf522SAndroid Build Coastguard Worker #include <bootloader_message/bootloader_message.h>
26*288bf522SAndroid Build Coastguard Worker
27*288bf522SAndroid Build Coastguard Worker #include <functional>
28*288bf522SAndroid Build Coastguard Worker #include <iostream>
29*288bf522SAndroid Build Coastguard Worker
PrintUsage(const char * progname)30*288bf522SAndroid Build Coastguard Worker void PrintUsage(const char* progname) {
31*288bf522SAndroid Build Coastguard Worker std::cerr << "USAGE: " << progname << " get [PROPERTY]" << std::endl;
32*288bf522SAndroid Build Coastguard Worker std::cerr << " " << progname << " store [PROPERTY] [VALUE]" << std::endl;
33*288bf522SAndroid Build Coastguard Worker std::cerr << " " << progname << " update-props" << std::endl;
34*288bf522SAndroid Build Coastguard Worker }
35*288bf522SAndroid Build Coastguard Worker
UpdateProps()36*288bf522SAndroid Build Coastguard Worker int UpdateProps() {
37*288bf522SAndroid Build Coastguard Worker misc_kcmdline_message m = {.version = MISC_KCMDLINE_MESSAGE_VERSION,
38*288bf522SAndroid Build Coastguard Worker .magic = MISC_KCMDLINE_MAGIC_HEADER};
39*288bf522SAndroid Build Coastguard Worker std::string err;
40*288bf522SAndroid Build Coastguard Worker if (!ReadMiscKcmdlineMessage(&m, &err)) {
41*288bf522SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to read from misc: " << err;
42*288bf522SAndroid Build Coastguard Worker return 1;
43*288bf522SAndroid Build Coastguard Worker }
44*288bf522SAndroid Build Coastguard Worker
45*288bf522SAndroid Build Coastguard Worker // If invalid, treat it as-if all flags are zero.
46*288bf522SAndroid Build Coastguard Worker if (m.magic != MISC_KCMDLINE_MAGIC_HEADER || m.version != MISC_KCMDLINE_MESSAGE_VERSION) {
47*288bf522SAndroid Build Coastguard Worker m = {.version = MISC_KCMDLINE_MESSAGE_VERSION,
48*288bf522SAndroid Build Coastguard Worker .magic = MISC_KCMDLINE_MAGIC_HEADER,
49*288bf522SAndroid Build Coastguard Worker .kcmdline_flags = 0};
50*288bf522SAndroid Build Coastguard Worker }
51*288bf522SAndroid Build Coastguard Worker
52*288bf522SAndroid Build Coastguard Worker bool use_rust_binder = (m.kcmdline_flags & MISC_KCMDLINE_BINDER_RUST) != 0;
53*288bf522SAndroid Build Coastguard Worker android::base::SetProperty("kcmdline.binder", use_rust_binder ? "rust" : "c");
54*288bf522SAndroid Build Coastguard Worker
55*288bf522SAndroid Build Coastguard Worker android::base::SetProperty("kcmdline.loaded", "1");
56*288bf522SAndroid Build Coastguard Worker return 0;
57*288bf522SAndroid Build Coastguard Worker }
58*288bf522SAndroid Build Coastguard Worker
PrintProperty(const char * property_name)59*288bf522SAndroid Build Coastguard Worker int PrintProperty(const char* property_name) {
60*288bf522SAndroid Build Coastguard Worker misc_kcmdline_message m = {.version = MISC_KCMDLINE_MESSAGE_VERSION,
61*288bf522SAndroid Build Coastguard Worker .magic = MISC_KCMDLINE_MAGIC_HEADER};
62*288bf522SAndroid Build Coastguard Worker
63*288bf522SAndroid Build Coastguard Worker std::string err;
64*288bf522SAndroid Build Coastguard Worker if (!ReadMiscKcmdlineMessage(&m, &err)) {
65*288bf522SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to read from misc: " << err;
66*288bf522SAndroid Build Coastguard Worker return 1;
67*288bf522SAndroid Build Coastguard Worker }
68*288bf522SAndroid Build Coastguard Worker
69*288bf522SAndroid Build Coastguard Worker if (m.magic != MISC_KCMDLINE_MAGIC_HEADER || m.version != MISC_KCMDLINE_MESSAGE_VERSION) {
70*288bf522SAndroid Build Coastguard Worker std::cout << "kcmdline message is invalid, treating all flags as zero" << std::endl;
71*288bf522SAndroid Build Coastguard Worker m = {.version = MISC_KCMDLINE_MESSAGE_VERSION,
72*288bf522SAndroid Build Coastguard Worker .magic = MISC_KCMDLINE_MAGIC_HEADER,
73*288bf522SAndroid Build Coastguard Worker .kcmdline_flags = 0};
74*288bf522SAndroid Build Coastguard Worker }
75*288bf522SAndroid Build Coastguard Worker
76*288bf522SAndroid Build Coastguard Worker if (!strcmp(property_name, "binder")) {
77*288bf522SAndroid Build Coastguard Worker bool use_rust_binder = (m.kcmdline_flags & MISC_KCMDLINE_BINDER_RUST) != 0;
78*288bf522SAndroid Build Coastguard Worker const char* binder_value = use_rust_binder ? "rust" : "c";
79*288bf522SAndroid Build Coastguard Worker std::cout << "binder=" << binder_value << std::endl;
80*288bf522SAndroid Build Coastguard Worker return 0;
81*288bf522SAndroid Build Coastguard Worker } else {
82*288bf522SAndroid Build Coastguard Worker LOG(ERROR) << "Unknown property name: " << property_name;
83*288bf522SAndroid Build Coastguard Worker return 1;
84*288bf522SAndroid Build Coastguard Worker }
85*288bf522SAndroid Build Coastguard Worker }
86*288bf522SAndroid Build Coastguard Worker
StoreProperty(const char * property_name,const char * new_value)87*288bf522SAndroid Build Coastguard Worker int StoreProperty(const char* property_name, const char* new_value) {
88*288bf522SAndroid Build Coastguard Worker misc_kcmdline_message m = {.version = MISC_KCMDLINE_MESSAGE_VERSION,
89*288bf522SAndroid Build Coastguard Worker .magic = MISC_KCMDLINE_MAGIC_HEADER};
90*288bf522SAndroid Build Coastguard Worker
91*288bf522SAndroid Build Coastguard Worker std::string err;
92*288bf522SAndroid Build Coastguard Worker if (!ReadMiscKcmdlineMessage(&m, &err)) {
93*288bf522SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to read from misc: " << err;
94*288bf522SAndroid Build Coastguard Worker return 1;
95*288bf522SAndroid Build Coastguard Worker }
96*288bf522SAndroid Build Coastguard Worker
97*288bf522SAndroid Build Coastguard Worker if (m.magic != MISC_KCMDLINE_MAGIC_HEADER || m.version != MISC_KCMDLINE_MESSAGE_VERSION) {
98*288bf522SAndroid Build Coastguard Worker std::cout << "kcmdline message is invalid, resetting it" << std::endl;
99*288bf522SAndroid Build Coastguard Worker m = {.version = MISC_KCMDLINE_MESSAGE_VERSION,
100*288bf522SAndroid Build Coastguard Worker .magic = MISC_KCMDLINE_MAGIC_HEADER,
101*288bf522SAndroid Build Coastguard Worker .kcmdline_flags = 0};
102*288bf522SAndroid Build Coastguard Worker }
103*288bf522SAndroid Build Coastguard Worker
104*288bf522SAndroid Build Coastguard Worker if (!strcmp(property_name, "binder")) {
105*288bf522SAndroid Build Coastguard Worker if (!strcmp(new_value, "rust")) {
106*288bf522SAndroid Build Coastguard Worker m.kcmdline_flags |= MISC_KCMDLINE_BINDER_RUST;
107*288bf522SAndroid Build Coastguard Worker } else if (!strcmp(new_value, "c")) {
108*288bf522SAndroid Build Coastguard Worker m.kcmdline_flags &= !MISC_KCMDLINE_BINDER_RUST;
109*288bf522SAndroid Build Coastguard Worker } else {
110*288bf522SAndroid Build Coastguard Worker LOG(ERROR) << "Binder property can only be 'c' or 'rust', but got " << new_value;
111*288bf522SAndroid Build Coastguard Worker return 1;
112*288bf522SAndroid Build Coastguard Worker }
113*288bf522SAndroid Build Coastguard Worker } else {
114*288bf522SAndroid Build Coastguard Worker LOG(ERROR) << "Unknown property name: " << property_name;
115*288bf522SAndroid Build Coastguard Worker return 1;
116*288bf522SAndroid Build Coastguard Worker }
117*288bf522SAndroid Build Coastguard Worker
118*288bf522SAndroid Build Coastguard Worker if (!WriteMiscKcmdlineMessage(m, &err)) {
119*288bf522SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to write to misc: " << err;
120*288bf522SAndroid Build Coastguard Worker return 1;
121*288bf522SAndroid Build Coastguard Worker }
122*288bf522SAndroid Build Coastguard Worker
123*288bf522SAndroid Build Coastguard Worker return 0;
124*288bf522SAndroid Build Coastguard Worker }
125*288bf522SAndroid Build Coastguard Worker
main(int argc,char ** argv)126*288bf522SAndroid Build Coastguard Worker int main(int argc, char** argv) {
127*288bf522SAndroid Build Coastguard Worker char *action, *property_name, *new_value;
128*288bf522SAndroid Build Coastguard Worker
129*288bf522SAndroid Build Coastguard Worker if (argc == 2) {
130*288bf522SAndroid Build Coastguard Worker action = argv[1];
131*288bf522SAndroid Build Coastguard Worker property_name = NULL;
132*288bf522SAndroid Build Coastguard Worker new_value = NULL;
133*288bf522SAndroid Build Coastguard Worker } else if (argc == 3) {
134*288bf522SAndroid Build Coastguard Worker action = argv[1];
135*288bf522SAndroid Build Coastguard Worker property_name = argv[2];
136*288bf522SAndroid Build Coastguard Worker new_value = NULL;
137*288bf522SAndroid Build Coastguard Worker } else if (argc == 4) {
138*288bf522SAndroid Build Coastguard Worker action = argv[1];
139*288bf522SAndroid Build Coastguard Worker property_name = argv[2];
140*288bf522SAndroid Build Coastguard Worker new_value = argv[3];
141*288bf522SAndroid Build Coastguard Worker } else {
142*288bf522SAndroid Build Coastguard Worker PrintUsage(*argv);
143*288bf522SAndroid Build Coastguard Worker return 1;
144*288bf522SAndroid Build Coastguard Worker }
145*288bf522SAndroid Build Coastguard Worker
146*288bf522SAndroid Build Coastguard Worker if (!strcmp(action, "update-props") && property_name == NULL) {
147*288bf522SAndroid Build Coastguard Worker return UpdateProps();
148*288bf522SAndroid Build Coastguard Worker } else if (!strcmp(action, "get") && property_name != NULL && new_value == NULL) {
149*288bf522SAndroid Build Coastguard Worker return PrintProperty(property_name);
150*288bf522SAndroid Build Coastguard Worker } else if (!strcmp(action, "store") && property_name != NULL && new_value != NULL) {
151*288bf522SAndroid Build Coastguard Worker return StoreProperty(property_name, new_value);
152*288bf522SAndroid Build Coastguard Worker } else {
153*288bf522SAndroid Build Coastguard Worker PrintUsage(*argv);
154*288bf522SAndroid Build Coastguard Worker return 1;
155*288bf522SAndroid Build Coastguard Worker }
156*288bf522SAndroid Build Coastguard Worker }
157