fastboot

关于fastboot的使用方法,可以看看(/system/core/fastboot/fastboot.cpp)fastboot.cpp中的usage方法,里面讲的很详细.如果你用过fastboot 您才能知道我下文讲的是是什么。
首先看Android.mk,可以fastboot用的源文件protocol.c engine.c bootimg_utils.cpp fastboot.cpp util.c fs.c
这些源文件和lib会被build一个fastboot 的可执行bin档(include $(BUILD_HOST_EXECUTABLE)).

xref: /system/core/fastboot/Android.mk
1LOCAL_C_INCLUDES := $(LOCAL_PATH)/../mkbootimg \
22  $(LOCAL_PATH)/../../extras/ext4_utils \
23  $(LOCAL_PATH)/../../extras/f2fs_utils
24LOCAL_SRC_FILES := protocol.c engine.c bootimg_utils.cpp fastboot.cpp util.c fs.c
25LOCAL_MODULE := fastboot
26LOCAL_MODULE_TAGS := debug
27LOCAL_CONLYFLAGS += -std=gnu99
28LOCAL_CFLAGS += -Wall -Wextra -Werror -Wunreachable-code


由下面这段可以fastboot 可以support的host为linux/darwin/window.
32ifeq ($(HOST_OS),linux)
33  LOCAL_SRC_FILES += usb_linux.c util_linux.c
34endif
35
36ifeq ($(HOST_OS),darwin)
37  LOCAL_SRC_FILES += usb_osx.c util_osx.c
38  LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbon
39  LOCAL_CFLAGS += -Wno-unused-parameter
40endif
41
42ifeq ($(HOST_OS),windows)
43  LOCAL_SRC_FILES += usb_windows.c util_windows.c


有43行可以usb_windows.c util_windows.c 是用于通过usb 给板子发送命令的.
既然fastboot 是一个可以执行的bin,那我们来看看其main函数的实现。
xref: /system/core/fastboot/fastboot.cpp
int main(int argc, char **argv)
1006{
1114
1115    if (argc > 0 && !strcmp(*argv, "devices")) {
1116        skip(1);
1117        list_devices();
1118        return 0;
1119    }
1120
1121    if (argc > 0 && !strcmp(*argv, "help")) {
1122        usage();
1123        return 0;
1124    }
1125
1126    usb_handle* usb = open_device();
1127
1128    while (argc > 0) {
1129        if(!strcmp(*argv, "getvar")) {
1130            require(2);
1131            fb_queue_display(argv[1], argv[1]);
1132            skip(2);
1133        } else if(!strcmp(*argv, "erase")) {
1134            require(2);
1135
1136            if (fb_format_supported(usb, argv[1], NULL)) {
1137                fprintf(stderr, "******** Did you mean to fastboot format this partition?\n");
1138            }
1139
1140            fb_queue_erase(argv[1]);
1141            skip(2);
1142        } else if(!strncmp(*argv, "format", strlen("format"))) {
1143            char *overrides;
1144            char *type_override = NULL;
1145            char *size_override = NULL;
1146            require(2);
1156            overrides = strchr(*argv, ':');
1157            if (overrides) {
1158                overrides++;
1159                size_override = strchr(overrides, ':');
1160                if (size_override) {
1161                    size_override[0] = '\0';
1162                    size_override++;
1163                }
1164                type_override = overrides;
1165            }
1166            if (type_override && !type_override[0]) type_override = NULL;
1167            if (size_override && !size_override[0]) size_override = NULL;
1168            if (erase_first && needs_erase(usb, argv[1])) {
1169                fb_queue_erase(argv[1]);
1170            }
1171            fb_perform_format(usb, argv[1], 0, type_override, size_override);
1172            skip(2);
1173        } else if(!strcmp(*argv, "signature")) {
1174            require(2);
1175            data = load_file(argv[1], &sz);
1176            if (data == 0) die("could not load '%s': %s", argv[1], strerror(errno));
1177            if (sz != 256) die("signature must be 256 bytes");
1178            fb_queue_download("signature", data, sz);
1179            fb_queue_command("signature", "installing signature");
1180            skip(2);
1181        } else if(!strcmp(*argv, "reboot")) {
1182            wants_reboot = 1;
1183            skip(1);
1184            if (argc > 0) {
1185                if (!strcmp(*argv, "bootloader")) {
1186                    wants_reboot = 0;
1187                    wants_reboot_bootloader = 1;
1188                    skip(1);
1189                }
1190            }
1191            require(0);
1192        } else if(!strcmp(*argv, "reboot-bootloader")) {
1193            wants_reboot_bootloader = 1;
1194            skip(1);
1195        } else if (!strcmp(*argv, "continue")) {
1196            fb_queue_command("continue", "resuming boot");
1197            skip(1);
1198        } else if(!strcmp(*argv, "boot")) {
1199            char *kname = 0;
1200            char *rname = 0;
1201            skip(1);
1202            if (argc > 0) {
1203                kname = argv[0];
1204                skip(1);
1205            }
1206            if (argc > 0) {
1207                rname = argv[0];
1208                skip(1);
1209            }
1210            data = load_bootable_image(kname, rname, &sz, cmdline);
1211            if (data == 0) return 1;
1212            fb_queue_download("boot.img", data, sz);
1213            fb_queue_command("boot", "booting");
1214        } else if(!strcmp(*argv, "flash")) {
1215            char *pname = argv[1];
1216            char *fname = 0;
1217            require(2);
1218            if (argc > 2) {
1219                fname = argv[2];
1220                skip(3);
1221            } else {
1222                fname = find_item(pname, product);
1223                skip(2);
1224            }
1225            if (fname == 0) die("cannot determine image filename for '%s'", pname);
1226            if (erase_first && needs_erase(usb, pname)) {
1227                fb_queue_erase(pname);
1228            }
1229            do_flash(usb, pname, fname);


1294
1295    if (fb_queue_is_empty())
1296        return 0;
1297
1298    status = fb_execute_queue(usb);
1299    return (status) ? 1 : 0;
1300}


1126行是打开usb设备用于通讯,如我们所分析,因为我们用的host是window,所以实在usb_windows.c 实现.
H A D usb_windows.c 49 AdbWinApi.dll. This structure is returned from usb_open() routine and
376 usb_handle *usb_open(ifc_match_func callback) function 
从1128行开始就是fastboot的命令。
我们以fastboot flash命令为例。
会执行1214行的flash命令。最终调用1229行的do_flash函数。
xref: /system/core/fastboot/fastboot.cpp
720void do_flash(usb_handle *usb, const char *pname, const char *fname)
721{
722    struct fastboot_buffer buf;
723
724    if (load_buf(usb, fname, &buf)) {
725        die("cannot load '%s'", fname);
726    }
727    flash_buf(pname, &buf);
728}
 可见先调用724行的load_buf将数据读进来。下打开这个文件获取到fd,在根据fd来读文件.
687static int load_buf(usb_handle *usb, const char *fname,
688        struct fastboot_buffer *buf)
689{
690    int fd;
691
692    fd = open(fname, O_RDONLY | O_BINARY);
693    if (fd < 0) {
694        return -1;
695    }
696
697    return load_buf_fd(usb, fd, buf);
698}
其次调用来准备发送数据,可见支持FB_BUFFER_SPARSE 和  FB_BUFFER是(ext4 support的两种格式)
700static void flash_buf(const char *pname, struct fastboot_buffer *buf)
701{
702    sparse_file** s;
703
704    switch (buf->type) {
705        case FB_BUFFER_SPARSE:
706            s = reinterpret_cast<sparse_file**>(buf->data);
707            while (*s) {
708                int64_t sz64 = sparse_file_len(*s, true, false);
709                fb_queue_flash_sparse(pname, *s++, sz64);
710            }
711            break;
712        case FB_BUFFER:
713            fb_queue_flash(pname, buf->data, buf->sz);
714            break;
715        default:
716            die("unknown buffer type: %d", buf->type);
717    }
718}
我们以FB_BUFEER为例,调用fb_queue_flash(pname, buf->data, buf->sz); 来将要做的事情加入到列表中


175void fb_queue_flash(const char *ptn, void *data, unsigned sz)
176{
177    Action *a;
178
179    a = queue_action(OP_DOWNLOAD, "");
180    a->data = data;
181    a->size = sz;
182    a->msg = mkmsg("sending '%s' (%d KB)", ptn, sz / 1024);
183
184    a = queue_action(OP_COMMAND, "flash:%s", ptn);
185    a->msg = mkmsg("writing '%s'", ptn);
186}
在看queue_action的实现,将要写到板子里面的数据的size和data封装到Action中。
最后在fastboot.cpp 的1298行执行这些Action
1298    status = fb_execute_queue(usb);
int fb_execute_queue(usb_handle *usb)
368{
369    Action *a;
370    char resp[FB_RESPONSE_SZ+1];
371    int status = 0;
372
373    a = action_list;
374    if (!a)
375        return status;
376    resp[FB_RESPONSE_SZ] = 0;
377
378    double start = -1;
379    for (a = action_list; a; a = a->next) {
380        a->start = now();
381        if (start < 0) start = a->start;
382        if (a->msg) {
383            // fprintf(stderr,"%30s... ",a->msg);
384            fprintf(stderr,"%s...\n",a->msg);
385        }
386        if (a->op == OP_DOWNLOAD) {
387            status = fb_download_data(usb, a->data, a->size);
388            status = a->func(a, status, status ? fb_get_error() : "");
389            if (status) break;
390        } else if (a->op == OP_COMMAND) {
391            status = fb_command(usb, a->cmd);
392            status = a->func(a, status, status ? fb_get_error() : "");
393            if (status) break;
394        } else if (a->op == OP_QUERY) {
395            status = fb_command_response(usb, a->cmd, resp);
396            status = a->func(a, status, status ? fb_get_error() : resp);
397            if (status) break;
398        } else if (a->op == OP_NOTICE) {
399            fprintf(stderr,"%s\n",(char*)a->data);
400        } else if (a->op == OP_DOWNLOAD_SPARSE) {
401            status = fb_download_data_sparse(usb, a->data);
402            status = a->func(a, status, status ? fb_get_error() : "");
403            if (status) break;
404        } else if (a->op == OP_WAIT_FOR_DISCONNECT) {
405            usb_wait_for_disconnect(usb);
406        } else {
407            die("bogus action");
408        }
409    }
410
411    fprintf(stderr,"finished. total time: %.3fs\n", (now() - start));
412    return status;
413}


我们在fb_queue_flash中封装了两个ACTION,一个是OP_DOWNLOAD,一个是OP_COMMAND。这两个函数func是cb_default,仅仅是一个用于显示函数.
OP_DOWNLOAD就调用 fb_download_data->_command_send 通过usb将数据发送出去了
204int fb_download_data(usb_handle *usb, const void *data, unsigned size)
205{
206    char cmd[64];
207    int r;
208
209    sprintf(cmd, "download:%08x", size);
210    r = _command_send(usb, cmd, data, size, 0);
211
212    if(r < 0) {
213        return -1;
214    } else {
215        return 0;
216    }
217}
_command_send 实现如下:
161static int _command_send(usb_handle *usb, const char *cmd,
162                         const void *data, unsigned size,
163                         char *response)
164{
165    int r;
166    if (size == 0) {
167        return -1;
168    }
169
170    r = _command_start(usb, cmd, size, response);
171    if (r < 0) {
172        return -1;
173    }
174
175    r = _command_data(usb, data, size);
176    if (r < 0) {
177        return -1;
178    }
179
180    r = _command_end(usb);
181    if(r < 0) {
182        return -1;
183    }
184
185    return size;
186}
_command_start 实现如下:
109static int _command_start(usb_handle *usb, const char *cmd, unsigned size,
110                          char *response)
111{
112    int cmdsize = strlen(cmd);
113
114    if(response) {
115        response[0] = 0;
116    }
117
118    if(cmdsize > 64) {
119        sprintf(ERROR,"command too large");
120        return -1;
121    }
122
123    if(usb_write(usb, cmd, cmdsize) != cmdsize) {
124        sprintf(ERROR,"command write failed (%s)", strerror(errno));
125        usb_close(usb);
126        return -1;
127    }
128
129    return check_response(usb, size, response);
130}


在_command_start 中终于看到usb_write了,所以就是我们分析整个flash命令的执行过程。希望可以抛砖引玉.
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值