updater-script脚本深入解析 Android系统Recovery工作原理之使用update
Android系统Recovery工作原理之使用update.zip升级过程分析(八)---升级程序update_binary的执行过程
一、update_binary的执行过程分析
上一篇幅中的子进程所执行的程序binary实际上就是update.zip包中的update-binary。我们在上文中也说过,Recovery服务在做这一部分工作的时候是先将包中update-binary拷贝到内存文件系统中的/tmp/update_binary,然后再执行的。update_binary程序的源码位于gingerbread0919/bootable/recovery/updater/updater.cupdater-script脚本深入解析,源码如下:
[cpp] view plain copy
1. /*
2. * Copyright (C) 2009 The Android Open Source Project
3. *
4. * Licensed under the Apache License, Version 2.0 (the "License");
5. * you may not use this file except in compliance with the License.
6. * You may obtain a copy of the License at
7. *
8. * http://www.apache.org/licenses/LICENSE-2.0
9. *
10. * Unless required by applicable law or agreed to in writing, software
11. * distributed under the License is distributed on an "AS IS" BASIS,
12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13. * See the License for the specific language governing permissions and
14. * limitations under the License.
15. */
16.
17. #include
18. #include
19. #include
20.
21. #include "edify/expr.h"
22. #include "updater.h"
23. #include "install.h"
24. #include "minzip/Zip.h"
25.
26. // Generated by the makefile, this function defines the
27. // RegisterDeviceExtensions() function, which calls all the
28. // registration functions for device-specific extensions.
29. #include "register.inc"
30.
31. // Where in the package we expect to find the edify script to execute.
32. // (Note it's "updateR-script", not the older "update-script".)
33. #define SCRIPT_NAME "META-INF/com/google/android/updater-script"
34.
35. int main(int argc, char** argv) {
36. // Various things log information to stdout or stderr more or less
37. // at random. The log file makes more sense if buffering is
38. // turned off so things appear in the right order.
39. setbuf(stdout, NULL);
40. setbuf(stderr, NULL);
41.
42. if (argc != 4) {
43. "unexpected number of arguments (%d)\n", argc);
44. return 1;
45. }
46.
47. char* version = argv[1];
48. if ((version[0] != '1' && version[0] != '2' && version[0] != '3') ||
49. '\0') {
50. // We support version 1, 2, or 3.
51. "wrong updater binary API; expected 1, 2, or 3; "
52. "got %s\n",
53. argv[1]);
54. return 2;
55. }
56.
57. // Set up the pipe for sending commands back to the parent process.
58.
59. int fd = atoi(argv[2]);
60. FILE* cmd_pipe = fdopen(fd, "wb");
61. setlinebuf(cmd_pipe);
62.
63. // Extract the script from the package.
64.
65. char* package_data = argv[3];
66. ZipArchive za;
67. int err;
68. err = mzOpenZipArchive(package_data, &za);
69. if (err != 0) {
70. "failed to open package %s: %s\n",
71. package_data, strerror(err));
72. return 3;
73. }
74.
75. const ZipEntry* script_entry = mzFindZipEntry(&za, SCRIPT_NAME);
76. if (script_entry == NULL) {
77. "failed to find %s in %s\n", SCRIPT_NAME, package_data);
78. return 4;
79. }
80.
81. char* script = malloc(script_entry->uncompLen+1);
82. if (!mzReadZipEntry(&za, script_entry, script, script_entry->uncompLen)) {
83. "failed to read script from package\n");
84. return 5;
85. }
86. '\0';
87.
88. // Configure edify's functions.
89.
90. RegisterBuiltins();
91. RegisterInstallFunctions();
92. RegisterDeviceExtensions();
93. FinishRegistration();
94.
95. // Parse the script.
96.
97. Expr* root;
98. int error_count = 0;
99. yy_scan_string(script);
100. int error = yyparse(&root, &error_count);
101. if (error != 0 || error_count > 0) {
102. "%d parse errors\n", error_count);
103. return 6;
104. }
105.
106. // Evaluate the parsed script.
107.
108. UpdaterInfo updater_info;
109. updater_info.cmd_pipe = cmd_pipe;
110. updater_info.package_zip = &za;
111. updater_info.version = atoi(version);
112.
113. State state;
114. state.cookie = &updater_info;
115. state.script = script;
116. state.errmsg = NULL;
117.
118. char* result = Evaluate(&state, root);
119. if (result == NULL) {
120. if (state.errmsg == NULL) {
121. "script aborted (no error message)\n");
122. "ui_print script aborted (no error message)\n");
123. else {
124. "script aborted: %s\n", state.errmsg);
125. char* line = strtok(state.errmsg, "\n");
126. while (line) {
127. "ui_print %s\n", line);
128. "\n");
129. }
130. "ui_print\n");
131. }
132. free(state.errmsg);
133. return 7;
134. else {
135. "script result was [%s]\n", result);
136. free(result);
137. }
138.
139. if (updater_info.package_zip) {
140. mzCloseZipArchive(updater_info.package_zip);
141. }
142. free(script);
143.
144. return 0;
145. }