1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| + void *main_task(void* param) \ -- struct ota_manager* this = (struct ota_manager*) param; "保存ota_manager的实例" | -- this->sh->set_signal_handler(this->sh, SIGALRM, signal_handler); "设置了 `SIGALRM` 的信号处理函数为 ota_manager的 `signal_handler` 函数, 处理超时消息" | -- alarm(ALARM_TIME_OUT); "设置超时线" 30*60 s, 如果升级时长超过30 min, alarm的signal_handler 会进行处理 | -- update_stages(UPDATE_START, NULL); "打印log 开始升级" | -- this->uf = _new(struct update_file, update_file); "调用update_file构造函数, 安装对应的函数指针" | -- ping_ota_server_success = try_ping_server(this, this->cf->server_ip); "ping 升级服务器. 是否能ping 通, 否则停止" | -- this->ni->icmp_echo(this->ni, this->cf->server_ip, 30000) "发包, 检查服务器是否有回包, 无回包, 停止" | -- this->cf->parse_current_version(this->cf); "解析 server ip url" | -+ update_devices(this) \ - creat_unzip_dir() "创建解压路径 /tmp/update" | -+ download_and_create_sha1_table(this) \ - download_file(path, prefix_local_update_path) "下载 server_url/sha1Tab 到 /tmp/update/ 下" | - this->uf->create_sha1_table(this->uf, path) "update_file 类从sha1Tab 文件读出 sha_count个sha result entry, 保存到update_file 类的 sha1_table 数组中" | -+ download_and_parse_global_conf(this) "global.xml 示例 <global><device type="opaque">nor</device></global>" \ - download_file(path, prefix_local_update_path) "下载 server_url/global.xml 到 /tmp/update/ 下" | -+ this->uf->parse_global_xml(this->uf, path) "解析global.xml 文件, 这一步主要是解析出block_device的flash 类型, 是nor nand mmc" \ -+ for (node = mxmlFindElement(node, tree, "device")... \ - const char* devtype = mxmlGetOpaque(node); | - device_type_list[i++] = devtype; | - strcpy(device_info->type, devtype); | - list_add_tail(&device_info->head, &this->device_list); "挂入update_file的 device_list链表" | - strcpy(update_info->devtype, devtype); | - list_add_tail(&update_info->head, &this->update_list); "挂入update_file的 update_list链表" | - const char** device_type_list = this->uf->get_device_type_list(this->uf); | -+ for (int i = 0; device_type_list[i]; i++) "获取 parse_global_xml阶段挂入的device_list链表的数据" \ - struct device_info* device_info = this->uf->get_device_info_by_devtype(this->uf, devtype); | - struct update_info* update_info = this->uf->get_update_info_by_devtype(this->uf, devtype); | -+ download_and_parse_update_conf(this, device_info, update_info, devtype) \ - download_file(path, prefix_local_update_path) "下载server_url/<dev_type>/update000.zip 到/tmp/update/下" | -+ check_device_update_info(this, path, device_info, update_info) "检查校验/tmp/update/update000.zip" \ -+ check_pkg_sha1(this, path, 0) \ - buff = "sha1sum path" | - strncmp(buff, this->uf->sha1_table[index], 40) "与前面从sha1Tab 读出的count个entry的 第一个entry 比较是否一致, 一致表明 sha1 校验通过" | -+ verify_update_pkg(this, path) \ - load_keys(g_data.public_key_path, &nkeys) "加载rsa公钥 /usr/data/ota_res/key/key.pub, 公钥有nkeys个, 挨个试, 有一个能验签通过即可" | -+ verify_file(path, keys, nkeys) \ - fseek(f, -FOOTER_SIZE, SEEK_END) "读文件尾" | - fread(footer, 1, FOOTER_SIZE, f) != FOOTER_SIZE) "读update000.zip的最后6个字节" | - footer[2] != 0xff || footer[3] != 0xff) "校验 footer 第3 和 第4 字节" 如果不全为1, 校验失败 | - comment_size = footer[4] + (footer[5] << 8); "comment_size 第6个字节 high, 第5个字节low, 即16 字节" | - eocd_size = comment_size + EOCD_HEADER_SIZE; | - signature_start = footer[0] + (footer[1] << 8); "sinature_start 的位置" | - fseek(f, -eocd_size, SEEK_END) "EOCD recorder 块" | - signed_len = ftell(f) + EOCD_HEADER_SIZE - 2; "获取一共多少字节被签名了" | - sha(f, 0, signed_len) "获取该文件的被签名保护的文件块的 hash" | -+ for (i = 0; i < numKeys; ++i) "挨个pubkey 校验" \ - RSA_verify(pKeys+i, eocd + eocd_size - 6 - RSANUMBYTES, RSANUMBYTES, sha1) "signature 存放的位置: eocd + eocd_size - 6 - RSANUMBYTES" | -- unzip(path, prefix_local_update_path, NULL, 1) "zlib 的minizip 方案解压 update000.zip 到 /tmp/update/下" | - sprintf(local_path, "%s/%s", prefix_local_update_path, prefix_device_xml); "/tmp/update/device.xml" | -+ this->uf->parse_device_xml(this->uf, local_path, device_info) "解析device.xml", 查看示例 device.xml \ -+ for (node = mxmlFindElement(node, tree, "item") ... \ - struct part_info* partition = calloc(1, sizeof(struct part_info)); | - memcpy(partition->name, name, strlen(name)); | - partition->offset = strtoull(offset_str, NULL, 0); | - partition->size = strtoull(size_str, NULL, 0); | - memcpy(partition->block_name, block_name, strlen(block_name)); | - list_add_tail(&partition->head, &device_info->list); "partion的信息挂到 device_info->list下" | -+ check_device_info(this, device_info) "仅支持nor 和 nand 类型的rom" \ -+ list_for_each(pos, &device_info->list) "遍历device_info.xml中的 partition信息" \ - offset = this->mtd_bm->get_partition_start_by_name(this->mtd_bm, blkname); | - size = this->mtd_bm->get_partition_size_by_name(this->mtd_bm, blkname); | - (offset != info->offset) || (size != info->size) "device_info.xml中的partition的信息与前面/sys/class/mtd下扫描出的各block_device即partition的信息进行比对, offset 和 size 一致才可以" | -- sprintf(local_path, "%s/%s", prefix_local_update_path, prefix_update_xml); "/tmp/update/update.xml" | -+ this->uf->parse_update_xml(this->uf, local_path, update_info) "解析升级包中的update.xml 查看示例 update.xml" \ -+ for (node = mxmlFindElement(node, tree, "image")...) \ - memcpy(image->name, name, strlen(name)); | - memcpy(image->fs_type, fs_type, strlen(fs_type)); | - image->offset = strtoull(offset_str, NULL, 0); | - image->size = strtoull(size_str, NULL, 0); | - image->update_mode = mxmlGetInteger(sub_node); | - image->chunksize = mxmlGetInteger(sub_node); | - image->chunkcount = mxmlGetInteger(sub_node); | - list_add_tail(&image->head, &update_info->list); "解析各字段信息后以image为单位, 将升级信息挂入到update_info->list 链表" | -+ merge_imginfo_into_partinfo(this, device_info, update_info) \ -+ list_for_each(pos_devinfo, &device_info->list) \ - part_info *part_info = list_entry(pos_devinfo, struct part_info, head); "在 parse_device_xml 阶段扫描出的各device下的所有的partition分区信息, 遍历" | -+ list_for_each(pos_update, &update_info->list) "遍历所有待升级的分区镜像" \ - image_info* image_info = list_entry(pos_update, struct image_info, head); | - image_info->offset > part_info_left_boundary && image_info->offset <= part_info_right_boundary "image_info的offset 落在 partition的 size 范围内, 说明该镜像是属于该分区的" | - list_add_tail(&image_info->head_part, &part_info->list); "镜像挂入分区的链表" | - part_info->image_count++; "一个分区有多个镜像, 这里的镜像可以理解为镜像的分片, 并不一定说明分区可以有多个镜像, 这里的image 概念是针对升级来说的" | - part_info->total_chunks += image_info->chunkcount; "待升级的总chunk"
|