xref: /aosp_15_r20/system/extras/kcmdlinectrl/kcmdlinectrl.cc (revision 288bf5226967eb3dac5cce6c939ccc2a7f2b4fe5)
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