fastboot 源码分析1

时间:2021-10-27 07:17:29
lk-refs-heads-master\app\aboot下的rules.mk可知
OBJS += \
$(LOCAL_DIR)/aboot.o \
$(LOCAL_DIR)/fastboot.o
主要包含aboot.c 和 fastboot.c
在aboot.c 中
APP_START(aboot)
.init = aboot_init,
APP_END
aboot_init的实现如下:
可知只要用户按下BACK按键就跳过boot_linux_from_flash,进入到fastboot.
void aboot_init(const struct app_descriptor *app)
{
if (keys_get_state(KEY_BACK) != 0)
goto fastboot;


boot_linux_from_flash();
dprintf(CRITICAL, "ERROR: Could not do normal boot. Reverting "
"to fastboot mode.\n");


fastboot:
udc_init(&surf_udc_device);


fastboot_register("boot", cmd_boot);
fastboot_register("erase:", cmd_erase);
fastboot_register("flash:", cmd_flash);
fastboot_register("continue", cmd_continue);
fastboot_publish("product", "swordfish");
fastboot_publish("kernel", "lk");


fastboot_init((void*) SCRATCH_ADDR, 100 * 1024 * 1024);
udc_start();
}
调用usb初始化,并注册fastboot的boot/erase/flash/continue/product/kernel等命令,并fastboot_init,新建thread来接受pc发过来的命令
int fastboot_init(void *base, unsigned size)
{
thread_t *thr;
dprintf(INFO, "fastboot_init()\n");


download_base = base;
download_max = size;


event_init(&usb_online, 0, EVENT_FLAG_AUTOUNSIGNAL);
event_init(&txn_done, 0, EVENT_FLAG_AUTOUNSIGNAL);


in = udc_endpoint_alloc(UDC_TYPE_BULK_IN, 512);
if (!in)
goto fail_alloc_in;
out = udc_endpoint_alloc(UDC_TYPE_BULK_OUT, 512);
if (!out)
goto fail_alloc_out;


fastboot_endpoints[0] = in;
fastboot_endpoints[1] = out;


req = udc_request_alloc();
if (!req)
goto fail_alloc_req;


if (udc_register_gadget(&fastboot_gadget))
goto fail_udc_register;


fastboot_register("getvar:", cmd_getvar);
fastboot_register("download:", cmd_download);
fastboot_publish("version", "0.5");


thr = thread_create("fastboot", fastboot_handler, 0, DEFAULT_PRIORITY, 4096);
thread_resume(thr);
return 0;


fail_udc_register:
udc_request_free(req);
fail_alloc_req:
udc_endpoint_free(out);
fail_alloc_out:
udc_endpoint_free(in);
fail_alloc_in:
return -1;
}
这个函数又注册getvar/download命令,并建立thread接受pc发过来的执行,thread的callback函数是fastboot_handler
static int fastboot_handler(void *arg)
{
for (;;) {
event_wait(&usb_online);
fastboot_command_loop();
}
return 0;
}
这个函数是循环,如果usb接收到命令,就调用fastboot_command_loop来解析命令并调用命令的执行函数
static void fastboot_command_loop(void)
{
struct fastboot_cmd *cmd;
int r;
dprintf(INFO,"fastboot: processing commands\n");


again:
while (fastboot_state != STATE_ERROR) {
r = usb_read(buffer, 64);
if (r < 0) break;
buffer[r] = 0;
dprintf(INFO,"fastboot: %s\n", buffer);


for (cmd = cmdlist; cmd; cmd = cmd->next) {
if (memcmp(buffer, cmd->prefix, cmd->prefix_len))
continue;
fastboot_state = STATE_COMMAND;
cmd->handle((const char*) buffer + cmd->prefix_len,
   (void*) download_base, download_size);
if (fastboot_state == STATE_COMMAND)
fastboot_fail("unknown reason");
goto again;
}


fastboot_fail("unknown command");

}
fastboot_state = STATE_OFFLINE;
dprintf(INFO,"fastboot: oops!\n");
}

所有的命令都在cmdlist 这个列表中,调用memcmp来比较pc发的命令和fastboot的命令是否相等,如果相等就调用handle处理,

也就是我们fastboot_register 时候的第二个参数.