andorid recovery源码分析
recovery 源码分析——图形篇
参考文章:
http://blog.csdn.net/wanggp_2007/article/details/6253858
http://blog.csdn.net/windskier/article/details/7030732
recovery的主函数在recovery.c中.
1 main(int argc, char **argv) { 2 3 if (argc == 2 && strcmp(argv[1], "adbd") == 0) { 4 adb_main(); 5 return 0; 6 } 7 8 // Recovery needs to install world-readable files, so clear umask 9 // set by init 10 umask(0); 11 12 char* command = argv[0]; 13 char* stripped = strrchr(argv[0], '/'); 14 if (stripped) 15 command = stripped + 1; 16 17 if (strcmp(command, "recovery") != 0) 18 { 19 struct recovery_cmd cmd = get_command(command); 20 if (cmd.name) 21 return cmd.main_func(argc, argv); 22 23 #ifdef BOARD_RECOVERY_HANDLES_MOUNT 24 if (!strcmp(command, "mount") && argc == 2) 25 { 26 load_volume_table(); 27 return ensure_path_mounted(argv[1]); 28 } 29 #endif 30 if (!strcmp(command, "setup_adbd")) { 31 load_volume_table(); 32 setup_adbd(); 33 return 0; 34 } 35 if (!strcmp(command, "start")) { 36 property_set("ctl.start", argv[1]); 37 return 0; 38 } 39 if (!strcmp(command, "stop")) { 40 property_set("ctl.stop", argv[1]); 41 return 0; 42 } 43 return busybox_driver(argc, argv); 44 } 45 __system("/sbin/postrecoveryboot.sh"); 46 47 int is_user_initiated_recovery = 0; 48 time_t start = time(NULL); 49 50 // If these fail, there's not really anywhere to complain... 51 freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL); 52 freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL); 53 printf("Starting recovery on %s\n", ctime(&start)); 54 55 device_ui_init(&ui_parameters); 56 ui_init(); 57 ui_print(EXPAND(RECOVERY_VERSION)"\n"); 58 59 #ifdef BOARD_RECOVERY_SWIPE 60 #ifndef BOARD_TOUCH_RECOVERY 61 //display directions for swipe controls 62 ui_print("Swipe up/down to change selections.\n"); 63 ui_print("Swipe to the right for enter.\n"); 64 ui_print("Swipe to the left for back.\n"); 65 #endif 66 #endif 67 68 load_volume_table(); 69 process_volumes(); 70 vold_client_start(&v_callbacks, 0); 71 vold_set_automount(1); 72 setup_legacy_storage_paths(); 73 LOGI("Processing arguments.\n"); 74 ensure_path_mounted(LAST_LOG_FILE); 75 rotate_last_logs(5); 76 get_args(&argc, &argv); 77 78 int previous_runs = 0; 79 const char *send_intent = NULL; 80 const char *update_package = NULL; 81 int wipe_data = 0, wipe_cache = 0; 82 int sideload = 0; 83 int headless = 0; 84 85 LOGI("Checking arguments.\n"); 86 int arg; 87 while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) { 88 switch (arg) { 89 case 'p': previous_runs = atoi(optarg); break; 90 case 's': send_intent = optarg; break; 91 case 'u': update_package = optarg; break; 92 case 'w': 93 #ifndef BOARD_RECOVERY_ALWAYS_WIPES 94 wipe_data = wipe_cache = 1; 95 #endif 96 break; 97 case 'h': 98 ui_set_background(BACKGROUND_ICON_CID); 99 ui_show_text(0); 100 headless = 1; 101 break; 102 case 'c': wipe_cache = 1; break; 103 case 't': ui_show_text(1); break; 104 case 'l': sideload = 1; break; 105 case '?': 106 LOGE("Invalid command argument\n"); 107 continue; 108 } 109 } 110 111 struct selinux_opt seopts[] = { 112 { SELABEL_OPT_PATH, "/file_contexts" } 113 }; 114 115 sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); 116 117 if (!sehandle) { 118 fprintf(stderr, "Warning: No file_contexts\n"); 119 ui_print("Warning: No file_contexts\n"); 120 } 121 122 LOGI("device_recovery_start()\n"); 123 device_recovery_start(); 124 125 printf("Command:"); 126 for (arg = 0; arg < argc; arg++) { 127 printf(" \"%s\"", argv[arg]); 128 } 129 printf("\n"); 130 131 if (update_package) { 132 // For backwards compatibility on the cache partition only, if 133 // we're given an old 'root' path "CACHE:foo", change it to 134 // "/cache/foo". 135 if (strncmp(update_package, "CACHE:", 6) == 0) { 136 int len = strlen(update_package) + 10; 137 char* modified_path = malloc(len); 138 strlcpy(modified_path, "/cache/", len); 139 strlcat(modified_path, update_package+6, len); 140 printf("(replacing path \"%s\" with \"%s\")\n", 141 update_package, modified_path); 142 update_package = modified_path; 143 } 144 } 145 printf("\n"); 146 147 property_list(print_property, NULL); 148 printf("\n"); 149 150 int status = INSTALL_SUCCESS; 151 152 if (update_package != NULL) { 153 status = install_package(update_package); 154 if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n"); 155 } else if (wipe_data) { 156 if (device_wipe_data()) status = INSTALL_ERROR; 157 ignore_data_media_workaround(1); 158 if (erase_volume("/data")) status = INSTALL_ERROR; 159 ignore_data_media_workaround(0); 160 if (has_datadata() && erase_volume("/datadata")) status = INSTALL_ERROR; 161 if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; 162 if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n"); 163 } else if (wipe_cache) { 164 if (wipe_cache && erase_volume("/cache")) status = INSTALL_ERROR; 165 if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n"); 166 } else { 167 LOGI("Checking for extendedcommand...\n"); 168 status = INSTALL_ERROR; // No command specified 169 // we are starting up in user initiated recovery here 170 // let's set up some default options 171 signature_check_enabled = 0; 172 script_assert_enabled = 0; 173 is_user_initiated_recovery = 1; 174 if (!headless) { 175 ui_set_show_text(1); 176 ui_set_background(BACKGROUND_ICON_CLOCKWORK); 177 } 178 179 if (extendedcommand_file_exists()) { 180 LOGI("Running extendedcommand...\n"); 181 int ret; 182 if (0 == (ret = run_and_remove_extendedcommand())) { 183 status = INSTALL_SUCCESS; 184 ui_set_show_text(0); 185 } 186 else { 187 handle_failure(ret); 188 } 189 } else { 190 LOGI("Skipping execution of extendedcommand, file not found...\n"); 191 } 192 } 193 194 if (sideload) { 195 signature_check_enabled = 0; 196 if (!headless) 197 ui_set_show_text(1); 198 if (0 == apply_from_adb()) { 199 status = INSTALL_SUCCESS; 200 ui_set_show_text(0); 201 } 202 } 203 204 if (headless) { 205 headless_wait(); 206 } 207 if (status != INSTALL_SUCCESS && !is_user_initiated_recovery) { 208 ui_set_show_text(1); 209 ui_set_background(BACKGROUND_ICON_ERROR); 210 } 211 else if (status != INSTALL_SUCCESS || ui_text_visible()) { 212 prompt_and_wait(); 213 } 214 215 // We reach here when in main menu we choose reboot main system or for some wipe commands on start 216 // If there is a radio image pending, reboot now to install it. 217 maybe_install_firmware_update(send_intent); 218 219 // Otherwise, get ready to boot the main system... 220 finish_recovery(send_intent); 221 ui_print("Rebooting...\n"); 222 reboot_main_system(ANDROID_RB_RESTART, 0, 0); 223 224 return EXIT_SUCCESS; 225 }
图形熏染从device_ui_init(&ui_parameters);函数开始。主要初始化整个图形所需要的内存空间,初始化UIParameters结构体。UIParameters结构体如下。
1 typedef struct { 2 // number of frames in indeterminate progress bar animation 3 int indeterminate_frames; 4 5 // number of frames per second to try to maintain when animating 6 int update_fps; 7 8 // number of frames in installing animation. may be zero for a 9 // static installation icon. 10 int installing_frames; 11 12 // the install icon is animated by drawing images containing the 13 // changing part over the base icon. These specify the 14 // coordinates of the upper-left corner. 15 int install_overlay_offset_x; 16 int install_overlay_offset_y; 17 18 } UIParameters;
其初始化内容的值为:
1 UIParameters ui_parameters = { 2 6, // indeterminate progress bar frames 3 20, // fps 4 7, // installation icon frames (0 == static image) 5 13, 190, // installation icon overlay offset 6 };
初始化完毕之后,调用ui_init()函数,其主要充初始化字体。字体空间分配。
在 ui_init中调用函数gr_init();
gglInit(&gr_context);
1 ssize_t gglInit(GGLContext** context) 2 { 3 void* const base = malloc(sizeof(context_t) + 32); 4 if (base) { 5 // always align the context on cache lines 6 context_t *c = (context_t *)((ptrdiff_t(base)+31) & ~0x1FL); 7 ggl_init_context(c); 8 c->base = base; 9 *context = (GGLContext*)c; 10 } else { 11 return -1; 12 } 13 return 0; 14 }
gglInit(&gr_context);中有几个重要的结构体:
1 typedef struct { 2 // immediate rendering 3 void (*pointx)(void *con, const GGLcoord* v, GGLcoord r); 4 void (*linex)(void *con, 5 const GGLcoord* v0, const GGLcoord* v1, GGLcoord width); 6 void (*recti)(void* c, GGLint l, GGLint t, GGLint r, GGLint b); 7 void (*trianglex)(void* c, 8 GGLcoord const* v0, GGLcoord const* v1, GGLcoord const* v2); 9 10 // scissor 11 void (*scissor)(void* c, GGLint x, GGLint y, GGLsizei width, GGLsizei height); 12 13 // Set the textures and color buffers 14 void (*activeTexture)(void* c, GGLuint tmu); 15 void (*bindTexture)(void* c, const GGLSurface* surface); 16 void (*colorBuffer)(void* c, const GGLSurface* surface); 17 void (*readBuffer)(void* c, const GGLSurface* surface); 18 void (*depthBuffer)(void* c, const GGLSurface* surface); 19 void (*bindTextureLod)(void* c, GGLuint tmu, const GGLSurface* surface); 20 21 // enable/disable features 22 void (*enable)(void* c, GGLenum name); 23 void (*disable)(void* c, GGLenum name); 24 void (*enableDisable)(void* c, GGLenum name, GGLboolean en); 25 26 // specify the fragment's color 27 void (*shadeModel)(void* c, GGLenum mode); 28 void (*color4xv)(void* c, const GGLclampx* color); 29 // specify color iterators (16.16) 30 void (*colorGrad12xv)(void* c, const GGLcolor* grad); 31 32 // specify Z coordinate iterators (0.32) 33 void (*zGrad3xv)(void* c, const GGLfixed32* grad); 34 35 // specify W coordinate iterators (16.16) 36 void (*wGrad3xv)(void* c, const GGLfixed* grad); 37 38 // specify fog iterator & color (16.16) 39 void (*fogGrad3xv)(void* c, const GGLfixed* grad); 40 void (*fogColor3xv)(void* c, const GGLclampx* color); 41 42 // specify blending parameters 43 void (*blendFunc)(void* c, GGLenum src, GGLenum dst); 44 void (*blendFuncSeparate)(void* c, GGLenum src, GGLenum dst, 45 GGLenum srcAlpha, GGLenum dstAplha); 46 47 // texture environnement (REPLACE / MODULATE / DECAL / BLEND) 48 void (*texEnvi)(void* c, GGLenum target, 49 GGLenum pname, 50 GGLint param); 51 52 void (*texEnvxv)(void* c, GGLenum target, 53 GGLenum pname, const GGLfixed* params); 54 55 // texture parameters (Wrapping, filter) 56 void (*texParameteri)(void* c, GGLenum target, 57 GGLenum pname, 58 GGLint param); 59 60 // texture iterators (16.16) 61 void (*texCoord2i)(void* c, GGLint s, GGLint t); 62 void (*texCoord2x)(void* c, GGLfixed s, GGLfixed t); 63 64 // s, dsdx, dsdy, scale, t, dtdx, dtdy, tscale 65 // This api uses block floating-point for S and T texture coordinates. 66 // All values are given in 16.16, scaled by 'scale'. In other words, 67 // set scale to 0, for 16.16 values. 68 void (*texCoordGradScale8xv)(void* c, GGLint tmu, const int32_t* grad8); 69 70 void (*texGeni)(void* c, GGLenum coord, GGLenum pname, GGLint param); 71 72 // masking 73 void (*colorMask)(void* c, GGLboolean red, 74 GGLboolean green, 75 GGLboolean blue, 76 GGLboolean alpha); 77 78 void (*depthMask)(void* c, GGLboolean flag); 79 80 void (*stencilMask)(void* c, GGLuint mask); 81 82 // alpha func 83 void (*alphaFuncx)(void* c, GGLenum func, GGLclampx ref); 84 85 // depth func 86 void (*depthFunc)(void* c, GGLenum func); 87 88 // logic op 89 void (*logicOp)(void* c, GGLenum opcode); 90 91 // clear 92 void (*clear)(void* c, GGLbitfield mask); 93 void (*clearColorx)(void* c, 94 GGLclampx r, GGLclampx g, GGLclampx b, GGLclampx a); 95 void (*clearDepthx)(void* c, GGLclampx depth); 96 void (*clearStencil)(void* c, GGLint s); 97 98 // framebuffer operations 99 void (*copyPixels)(void* c, GGLint x, GGLint y, 100 GGLsizei width, GGLsizei height, GGLenum type); 101 void (*rasterPos2x)(void* c, GGLfixed x, GGLfixed y); 102 void (*rasterPos2i)(void* c, GGLint x, GGLint y); 103 } GGLContext;
1 struct context_t { 2 GGLContext procs; 3 state_t state; 4 shade_t shade; 5 iterators_t iterators; 6 generated_vars_t generated_vars __attribute__((aligned(32))); 7 uint8_t ditherMatrix[GGL_DITHER_SIZE] __attribute__((aligned(32))); 8 uint32_t packed; 9 uint32_t packed8888; 10 const GGLFormat* formats; 11 uint32_t dirty; 12 texture_t* activeTMU; 13 uint32_t activeTMUIndex; 14 15 void (*init_y)(context_t* c, int32_t y); 16 void (*step_y)(context_t* c); 17 void (*scanline)(context_t* c); 18 void (*span)(context_t* c); 19 void (*rect)(context_t* c, size_t yc); 20 21 void* base; 22 Assembly* scanline_as; 23 GGLenum error; 24 };
context_t 结构体又包含GGLContext结构体。
而在gglInit(&gr_context) 中调用的ggl_init_context(c)函数,主要用来填补context_t的初始化值,一般属于固定值,还有初始化一些函数。
1 void ggl_init_context(context_t* c) 2 { 3 memset(c, 0, sizeof(context_t)); 4 ggl_init_procs(c);//把函数名都加上ggl_前缀。 5 ggl_init_trap(c); 6 ggl_init_scanline(c); 7 ggl_init_texture(c); 8 ggl_init_picker(c); 9 ggl_init_raster(c); 10 c->formats = gglGetPixelFormatTable(); /颜色模式选择 rgb565/RGBA_8888/BGRA_8888.返回的结果是所有格式,支持格式的个数在*numEntries 变量中保存。*numEntries 是静态函数中的一个变量。 11 c->state.blend.src = GGL_ONE; 12 c->state.blend.dst = GGL_ZERO; 13 c->state.blend.src_alpha = GGL_ONE; 14 c->state.blend.dst_alpha = GGL_ZERO; 15 c->state.mask.color = 0xF; 16 c->state.mask.depth = 0; 17 c->state.mask.stencil = 0xFFFFFFFF; 18 c->state.logic_op.opcode = GGL_COPY; 19 c->state.alpha_test.func = GGL_ALWAYS; 20 c->state.depth_test.func = GGL_LESS; 21 c->state.depth_test.clearValue = FIXED_ONE; 22 c->shade.w0 = FIXED_ONE; 23 memcpy(c->ditherMatrix, gDitherMatrix, sizeof(gDitherMatrix)); 24 }
总结:gglInit(&gr_context);主要就是初始化了GGLContext** context。最后赋值给全局变量GGLContext *gl = gr_context;
在 ui_init中调用函数gr_init();
gglInit(&gr_context);
gr_init_font();主要对字体初始化,在内存中分配内存。
1 typedef struct { 2 GGLsizei version; // always set to sizeof(GGLSurface) 3 GGLuint width; // width in pixels 4 GGLuint height; // height in pixels 5 GGLint stride; // stride in pixels 6 GGLubyte* data; // pointer to the bits 7 GGLubyte format; // pixel format 8 GGLubyte rfu[3]; // must be zero 9 // these values are dependent on the used format 10 union { 11 GGLint compressedFormat; 12 GGLint vstride; 13 }; 14 void* reserved; 15 } GGLSurface;
1 typedef struct { 2 GGLSurface texture; 3 unsigned cwidth; 4 unsigned cheight; 5 unsigned ascent; 6 } GRFont;
GRFont 包含,GGLSurface 结构体。
gr_init_font()函数初始化了GRFont *gr_font 结构体。
在 ui_init中调用函数gr_init();
gglInit(&gr_context);
gr_init_font();
gr_fb_fd = get_framebuffer(gr_framebuffer);获取framebuffer信息。初始化 static GGLSurface gr_framebuffer[NUM_BUFFERS];结构体,并返回/dev/graphics/fb0路径句柄。赋值给static int gr_fb_fd变量。
framebuffer两个重要的结构体
1 struct fb_var_screeninfo { 2 __u32 xres; /* visible resolution */ 3 __u32 yres; 4 __u32 xres_virtual; /* virtual resolution */ 5 __u32 yres_virtual; 6 __u32 xoffset; /* offset from virtual to visible */ 7 __u32 yoffset; /* resolution */ 8 9 __u32 bits_per_pixel; /* guess what */ 10 __u32 grayscale; /* 0 = color, 1 = grayscale, */ 11 /* >1 = FOURCC */ 12 struct fb_bitfield red; /* bitfield in fb mem if true color, */ 13 struct fb_bitfield green; /* else only length is significant */ 14 struct fb_bitfield blue; 15 struct fb_bitfield transp; /* transparency */ 16 17 __u32 nonstd; /* != 0 Non standard pixel format */ 18 19 __u32 activate; /* see FB_ACTIVATE_* */ 20 21 __u32 height; /* height of picture in mm */ 22 __u32 width; /* width of picture in mm */ 23 24 __u32 accel_flags; /* (OBSOLETE) see fb_info.flags */ 25 26 /* Timing: All values in pixclocks, except pixclock (of course) */ 27 __u32 pixclock; /* pixel clock in ps (pico seconds) */ 28 __u32 left_margin; /* time from sync to picture */ 29 __u32 right_margin; /* time from picture to sync */ 30 __u32 upper_margin; /* time from sync to picture */ 31 __u32 lower_margin; 32 __u32 hsync_len; /* length of horizontal sync */ 33 __u32 vsync_len; /* length of vertical sync */ 34 __u32 sync; /* see FB_SYNC_* */ 35 __u32 vmode; /* see FB_VMODE_* */ 36 __u32 rotate; /* angle we rotate counter clockwise */ 37 __u32 colorspace; /* colorspace for FOURCC-based modes */ 38 __u32 reserved[4]; /* Reserved for future compatibility */ 39 };
1 struct fb_fix_screeninfo { 2 char id[16]; /* identification string eg "TT Builtin" */ 3 unsigned long smem_start; /* Start of frame buffer mem */ 4 /* (physical address) */ 5 __u32 smem_len; /* Length of frame buffer mem */ 6 __u32 type; /* see FB_TYPE_* */ 7 __u32 type_aux; /* Interleave for interleaved Planes */ 8 __u32 visual; /* see FB_VISUAL_* */ 9 __u16 xpanstep; /* zero if no hardware panning */ 10 __u16 ypanstep; /* zero if no hardware panning */ 11 __u16 ywrapstep; /* zero if no hardware ywrap */ 12 __u32 line_length; /* length of a line in bytes */ 13 unsigned long mmio_start; /* Start of Memory Mapped I/O */ 14 /* (physical address) */ 15 __u32 mmio_len; /* Length of Memory Mapped I/O */ 16 __u32 accel; /* Indicate to driver which */ 17 /* specific chip/card we have */ 18 __u16 capabilities; /* see FB_CAP_* */ 19 __u16 reserved[2]; /* Reserved for future compatibility */ 20 };

浙公网安备 33010602011771号