九出十三归指什么生肖| 38线是什么意思| 复合维生素b片主治什么病| 钡餐检查能查出什么| 为什么会血压高| 周杰伦为什么喜欢昆凌| 清新的什么| 注明是什么意思| 朝野是什么意思| 芸豆是什么| 吕洞宾是什么生肖| 五指毛桃长什么样子| 琴酒是什么酒| 什么是聚酯纤维| 卵巢结节是什么意思| 直男什么意思| 云南小黄姜有什么功效| nothomme什么牌子| 梅毒早期什么症状| 消石灰是什么| 巨蟹座女和什么座最配| 手脚心发热是什么原因| 心包积液是什么意思| 脚抽筋吃什么钙片好| 验光挂什么科| 黄喉是什么动物身上的| 茅庐是什么意思| 转的第四笔是什么| 心猿意马是什么意思| hmo是什么| 手臂内侧是什么经络| 不孕为什么要查胰岛素| 脾大吃什么可以缩脾| 做乳腺彩超挂什么科| 嚷能组什么词| 冒昧是什么意思| 甲减的原因是什么引起的| 验孕棒两条杠什么意思| 什么是g点| 婴儿坐飞机需要什么证件| 己巳是什么意思| 锚什么意思| 天荒地老是什么生肖| 防代表什么生肖| 舌头破了是什么原因| 随笔是什么意思| 动人是什么意思| 值是什么意思| 辐射是什么| 优生四项是检查什么| 请柬写伉俪什么意思| 低脂高钙牛奶适合什么人群| 铁锈色痰见于什么病| 豆油什么牌子的好| 补办手机卡需要什么| 羊肉馅饺子配什么菜好| 床上放什么可以驱蟑螂| 性生活出血是什么原因| 凌迟是什么意思| hrd阳性是什么意思| 糖尿病都有什么症状| 肚脐下四指是什么位置| 12月6号是什么星座| 复方丹参片治什么病| 最难写的字是什么| 可遇不可求是什么意思| 金木水火土各代表什么| 炎症是什么意思| 尿酸高是为什么| 圣杯是什么意思| 娘是什么意思| 什么鱼红烧最好吃| 骨盐量偏高代表什么| 荨麻疹长什么样| 什么是人设| 人参归脾丸适合什么人吃| 欲仙欲死是什么意思| 爷爷的妹妹叫什么| 荷花是什么形状的| inr医学上是什么意思| 夏天手脱皮是什么原因| 龋齿挂什么科| 微信拥抱表情什么意思| 95属什么生肖| 海带是什么植物| 肾积水挂什么科| apm是什么牌子| 水镜先生和司马懿是什么关系| 什么是力量训练| 腋下检查挂什么科| 珀莱雅属于什么档次| 艾灸有什么好处| 有什么好看的国漫| 朱砂痣什么意思| 风雨雷电代表什么生肖| 男人吃女人有什么好处| 耳膜穿孔吃什么长得快| 眼睛肿是什么问题| 水浒传是什么朝代| 酸西地那非片是什么药| afp是什么意思| 湖北属于什么地区| 葫芦什么时候成熟| 头晕四肢无力是什么原因| 晚上睡不着白天睡不醒是什么原因| 熬夜后吃什么恢复元气| 吃什么食物能升白细胞| 六字真言是什么意思| 樱桃是什么季节的水果| 摇头是什么病| 脚肿吃什么消肿最快| 指奸是什么意思| 三体是什么意思| 什么的列车| 什么体质的人才有季经| 嘴唇肿了是什么原因| 煮牛肉放什么容易烂| 梦见别人开车撞死人是什么意思| 喜欢的反义词是什么| pp和ppsu有什么区别| 什么的雷雨| 壬水命是什么意思| 耳浴10分钟什么意思| 额娘是什么意思| 73岁属什么| 头痒用什么东西洗头最好| 格力空调睡眠模式1234什么意思| 孛儿只斤现在姓什么| 仪态什么什么| 根管治疗是什么意思| 为什么可乐能溶解鱼刺| 验大便能查出什么| 茹毛饮血什么意思| 胃寒吃什么| giordano是什么牌子| 蜻蜓点水的目的是什么| 三月20号是什么星座| 被动是什么意思| 绝育是什么意思| 白细胞酯酶是什么意思| 痛风什么东西不可以吃| 共情能力是什么意思| 桃花依旧笑春风什么意思| 36是什么意思| 血糖高吃什么水果好| 秦皇岛为什么叫秦皇岛| 喝酒之前吃什么保护胃| 风声鹤唳什么意思| 万马奔腾是什么生肖| 再生聚酯纤维是什么面料| 小便黄是什么病症| 莲蓬吃了有什么好处| 鳄鱼怕什么| 肛门痒擦什么药| 胃不好吃什么养胃水果| 补气养阴是什么意思| 化疗中的病人应该吃什么| 婴儿什么时候开始说话| 蛀牙是什么样子的| 喝鲜羊奶有什么好处和坏处| 基因突变是什么意思| 天秤座什么象星座| 半月板损伤有什么症状| 眩晕是什么原因| 端庄是什么意思| 请辞是什么意思| 为什么清真不吃猪肉| 头部挂什么科| 属蛇和什么属相相冲| 秒男是什么意思| 婴儿老打嗝是什么原因| 孕期不能吃什么| 梦到自己牙齿掉了是什么意思| 中华文化的精髓是什么| 炖羊汤放什么调料| 吃大米配什么菜| 中国精神是什么| 湿气重看中医挂什么科| 比五行属什么| 尿碱是什么| 乳腺导管扩张是什么意思| 名列前茅是什么生肖| 髋关节积液是什么原因造成的| 菠萝炒什么好吃| 什么克火| 疯狂动物城狐狸叫什么| 为什么飞机起飞降落要打开遮光板| 内膜薄是什么意思| 代价是什么意思| 五月二十二是什么星座| 天庭是什么意思| 疣是什么意思| 骨折线模糊什么意思| 乙肝检查挂什么科| 均一性红细胞什么意思| 为什么一吃完饭就肚子疼| 油腻是什么意思| 桃李满天下的桃李是什么意思| 一身傲骨是什么意思| 喝茶水对身体有什么好处| 结界是什么意思| 后中长是什么意思| 乾隆是什么生肖| 下午6点半是什么时辰| 安乃近是什么药| 为什么乳头会痒| 青少年腰疼是什么原因引起的| 怀孕血糖高有什么症状| 四次元是什么意思| 女性私处长痘痘是什么原因| 羟氯喹是什么药| 练八段锦有什么好处| 醍醐灌顶什么意思| p53阳性是什么意思| 一个月一个泉是什么字| 蓝色的猫是什么品种| 心肌缺血吃什么药效果最好| 孕妇可以喝什么茶| 什么山| 春回大地是指什么生肖| 网名取什么好听| 立刀旁与什么有关| 一什么树干| 典型是什么意思| 心血管疾病做什么检查| 附件炎有什么症状| 慢性荨麻疹是什么原因引起的| 为什么小腿肌肉酸痛| 弯男是什么意思| crt是什么意思| 三伏贴能治什么病| 丨是什么意思| 鼻子经常流鼻涕是什么原因| 花朵像什么| 马太效应什么意思| 百脚虫的出现意味什么| 什么药退烧快| 白细胞低吃什么食物好| 营养不良吃什么| 菜板什么材质的好| 胃出血大便是什么颜色| 颖五行属什么| 阴囊潮湿是什么原因造成的| 吃什么补维生素d| 左侧肋骨疼是什么原因| 张飞的兵器是什么| 做胃镜之前需要注意什么| 胃疼吃什么食物对胃好| 什么弟什么兄| 什么叫阈值| 人参果长什么样| 胃溃疡吃什么药| 珞字五行属什么| 核素是什么| 6月24什么星座| mankind是什么意思| 什么叫败血症| 油菜花是什么颜色| 常规血检能查出什么| 18k是什么金| 烫伤用什么药好| 秦始皇是芈月的什么人| 女人梦见老虎是什么预兆| 戒烟为什么会长胖| 百度
打印
[麦麦茶水间]

恐怖新作《与世隔绝》公布 堪称第一人称版寂静岭!

[复制链接]
19024|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hbzjt2011|  楼主 | 2025-6-21 18:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 hbzjt2011 于 2025-6-21 19:00 编辑

重新定义嵌入式固件管理
在物联网时代,传统的Bootloader设计已经无法满足现代嵌入式系统的需求。作为一名在嵌入式领域深耕8年的工程师,我经历过无数次因为固件升级失败导致的设备"变砖"事故。在最近的智能门锁项目中,我们面临着传统的固件升级方式成本极高且风险巨大。基于这些现实需求,重新设计了一套智能化的Bootloader架构,实现了从"引导程序"到"系统管家"的转变。
这套方案的核心理念是将Bootloader从简单的启动工具升级为具备智能决策、故障自愈、安全防护等高级特性的系统管理中心。通过A/B双分区设计、增量更新算法、多重安全验证等技术手段,尽可能将设备"变砖"的概率降低。

架构设计哲学从单分区到双分区的革命性转变
传统的单分区设计就像走钢丝,没有任何容错空间。一旦升级过程中出现断电、网络中断或数据错误,设备就会彻底无法启动。我们的双分区设计彻底改变了这一局面,就像给系统装上了"降落伞",确保任何时候都有一个可用的固件副本。
在实际的Flash布局中,我们将1MB的存储空间精心规划为六个功能区域。Bootloader占用64KB,这部分代码必须绝对稳定可靠,采用特殊的写保护机制确保不会被意外修改。两个应用分区各占384KB,功能完全对等,可以相互备份。更新缓冲区128KB专门用于存储增量更新包,配置日志区域32KB记录系统运行状态,备份Bootloader区域32KB提供终极保障。
这种布局设计的精妙之处在于平衡了可靠性、效率和成本。通过精确的容量规划,我们既保证了双分区的完整功能,又为增量更新和系统监控预留了充足空间,还控制了整体的Flash需求。
智能启动决策机制
启动分区的选择是整个系统的核心决策点。我们摒弃了传统的简单标志位判断,开发了一套基于多维度评分的智能决策系统。这个系统就像一个经验丰富的系统管理员,会综合考虑各种因素来做出最优选择。
评分算**考虑固件完整性、历史运行稳定性、硬件兼容性、版本新旧程度等多个维度。比如一个分区的固件版本较新,会获得额外的加分;如果某个分区曾经出现过启动失败,会被扣除相应分数;系统还会根据硬件健康状况调整评分权重。这种设计让系统具备了"学习"能力,能够根据历史经验优化启动策略。
// 智能启动决策的核心评分算法
int calculate_partition_score(partition_info_t *partition) {
    int score = 0;
   
    // 基础状态评分
    switch (partition->status) {
        case PARTITION_ACTIVE: score += 100; break;
        case PARTITION_READY: score += 80; break;
        case PARTITION_FAILED: score -= 80; break;
        case PARTITION_CORRUPTED: score -= 100; break;
    }
   
    // 健康评分加权 (0-100转换为-20到+20)
    score += (partition->health_score - 50) * 0.4;
   
    // 版本新旧程度考量
    if (partition->firmware_version > get_other_partition_version(partition)) {
        score += 10;
    }
   
    // 历史启动失败惩罚
    if (partition->boot_count > max_boot_attempts) {
        score -= 30;
    }
   
    return score;
}



增量更新技术突破二进制差分算法的工程实现
增量更新是这套方案的核心亮点之一。在物联网设备的实际应用中,网络带宽往往是稀缺资源,传输512KB的完整固件可能需要15-20分钟,而且网络不稳定时失败率很高。通过增量更新,我们只需要传输新旧版本之间的差异数据,通常只有原来的10-30%。
二进制差分算法的基本思路是分析新旧两个固件版本,找出其中的差异部分,生成包含操作指令的补丁包。这些操作指令包括三种基本类型:ADD操作表示添加新数据,COPY操作表示从旧版本复制数据,SKIP操作表示保持不变。通过这三种操作的组合,可以高效地描述任意两个版本之间的差异。
算法的关键在于如何最优化地分割数据块。我们采用滑动窗口和哈希匹配的方法,寻找新旧版本中相同的数据块,然后用COPY操作来复用这些数据。对于确实需要更新的部分,则用ADD操作添加新数据。这种方法不仅减少了传输数据量,还提高了更新过程的可靠性。

// 增量更新的核心应用函数
int apply_delta_update(uint32_t old_partition, uint32_t new_partition,
                      const uint8_t *delta_data, uint32_t delta_size) {
    delta_header_t *header = (delta_header_t*)delta_data;
    delta_block_t *blocks = (delta_block_t*)(delta_data + sizeof(delta_header_t));
   
    printf("应用增量更新: %u个数据块\n", header->patch_count);
   
    for (uint32_t i = 0; i < header->patch_count; i++) {
        delta_block_t *block = &blocks[i];
        uint32_t target_addr = get_partition_address(new_partition) + block->offset;
        
        switch (block->type) {
            case DELTA_OP_ADD:
                // 直接写入新数据
                flash_write(target_addr, patch_data + patch_offset, block->size);
                patch_offset += block->size;
                break;
               
            case DELTA_OP_COPY:
                // 从旧版本复制数据
                copy_flash_data(old_partition + block->source_offset,
                               target_addr, block->size);
                break;
               
            case DELTA_OP_SKIP:
                // 跳过,保持原有数据
                break;
        }
        
        // 验证每个块的完整性
        uint32_t actual_crc = calculate_flash_crc32(target_addr, block->size);
        if (actual_crc != block->checksum) {
            printf("数据块%u校验失败\n", i);
            return -1;
        }
    }
   
    return 0;
}


压缩优化与传输效率
在增量更新的基础上,我们还加入了数据压缩技术进一步优化传输效率。对于ADD操作的新增数据,我们使用LZ77压缩算法进行压缩,通常能够获得额外20-40%的空间节省。压缩算法的选择考虑了嵌入式系统的资源限制,既要保证压缩效果,又要控制解压缩的内存和计算开销。
传输协议层面,我们实现了断点续传和错误重试机制。当网络中断时,系统会记录已传输的数据位置,网络恢复后可以从中断点继续传输,避免重新开始。同时,我们还加入了传输质量评估,根据网络状况动态调整传输策略,在网络条件较差时降低传输速度以提高成功率。

多重安全防护体系RSA数字签名与完整性验证
安全性是现代嵌入式系统不可忽视的重要方面。我们构建了一套完整的安全防护体系,从固件签名、传输安全到安装验证,每个环节都有相应的安全措施。
数字签名验证是第一道防线。我们采用RSA-2048算法对固件进行签名,私钥严格保密存储在硬件安全模块中,设备内部只保存用于验证的公钥。每个固件包都包含完整的签名信息,系统会在安装前进行严格的签名验证,确保固件来源的合法性和完整性。

// 多层安全验证的综合检查函数
security_check_result_t comprehensive_security_check(const firmware_header_t *header,
                                                    const uint8_t *firmware_data) {
    security_check_result_t result = {0};
   
    // 魔术字检查 - 基础格式验证
    if (header->magic != FIRMWARE_MAGIC) {
        result.magic_check_failed = 1;
        return result;
    }
   
    // CRC32快速校验 - 检测传输错误
    uint32_t firmware_crc = calculate_crc32(firmware_data, header->firmware_size);
    if (firmware_crc != header->firmware_crc32) {
        result.firmware_crc_failed = 1;
        return result;
    }
   
    // SHA256哈希验证 - 强完整性保证
    uint8_t calculated_hash[32];
    mbedtls_sha256(firmware_data, header->firmware_size, calculated_hash, 0);
    if (memcmp(calculated_hash, header->firmware_sha256, 32) != 0) {
        result.hash_check_failed = 1;
        return result;
    }
   
    // RSA数字签名验证 - 来源合法性确认
    if (verify_firmware_signature(header, firmware_data) != 0) {
        result.signature_check_failed = 1;
        return result;
    }
   
    result.all_passed = 1;
    return result;
}


除了数字签名,我们还建立了多层的完整性验证机制。CRC32校验提供快速的数据完整性检查,适合实时验证;SHA256哈希提供更强的完整性保证,能够检测恶意篡改;分块验证机制对大型固件进行分段校验,可以快速定位损坏的数据块。
版本管理与回滚保护
版本管理不仅仅是简单的版本号比较,还涉及到硬件兼容性、API兼容性、配置兼容性等多个方面。我们建立了一套完整的版本兼容性检查机制,确保新固件能够在当前硬件环境下正常运行。
系统会检查固件的硬件兼容性标识,确保固件版本与设备型号匹配。对于API接口的变化,系统会进行向前兼容性检查,确保现有的配置和数据能够正常迁移。当检测到不兼容的版本时,系统会拒绝升级并记录详细的错误信息。

故障自愈与健康监控系统健康评估机制
故障自愈是这套方案的另一个重要特性。我们开发了一套全面的系统健康评估机制,能够实时监控系统的运行状态,及时发现潜在问题并采取相应的修复措施。
健康评估涵盖了多个维度,包括Flash完整性、内存使用情况、外设状态、系统响应性等。系统会定期执行这些检查,并为每个分区计算综合健康评分。当健康评分低于阈值时,系统会触发相应的修复策略。
Flash完整性检查通过读取验证和ECC错误检测来评估存储器的健康状况。内存使用检查监控栈空间使用率,防止栈溢出导致的系统崩溃。外设状态检查验证关键硬件模块的功能是否正常。系统响应性测试通过测量中断响应时间来评估系统的实时性能。

// 系统健康检查的核心实现
int perform_health_check(partition_info_t *partition) {
    int overall_score = 100;
   
    // Flash完整性检查
    if (verify_flash_integrity(partition_address, partition_size) != 0) {
        overall_score -= 30;
        printf("Flash完整性检查失败\n");
    }
   
    // 关键外设功能测试
    if (test_critical_peripherals() != 0) {
        overall_score -= 20;
        printf("外设功能测试失败\n");
    }
   
    // 栈使用情况检查
    uint32_t stack_usage = get_stack_usage_percentage();
    if (stack_usage > 80) {
        overall_score -= 15;
        printf("栈使用率过高: %u%%\n", stack_usage);
    }
   
    // 系统响应性测试
    uint32_t response_time = measure_interrupt_response_time();
    if (response_time > 100) {
        overall_score -= 10;
        printf("中断响应时间过长: %uus\n", response_time);
    }
   
    partition->health_score = (overall_score > 0) ? overall_score : 0;
    return (overall_score >= 60) ? 0 : -1;
}

自动修复策略
当系统检测到故障时,会根据故障的严重程度和类型选择相应的修复策略。修复策略按照影响程度从小到大分为几个级别:软重启、分区切换、固件重载、出厂重置等。
软重启是最轻量的修复方式,适用于临时性的软件故障。分区切换会将系统从当前分区切换到备份分区,适用于当前分区出现问题但备份分区正常的情况。固件重载会从备份存储中恢复固件,适用于固件损坏但系统结构完整的情况。出厂重置是最后的手段,会清除所有用户数据并恢复到出厂状态。
这种分级修复策略的设计思路是尽可能地保留用户数据和配置,只有在必要时才采用更激进的修复方式。系统会记录每次修复操作的结果,形成修复历史数据库,为后续的故障预测和预防提供参考。

实战效果与性能分析部署效果统计
经过在多个商业项目中的实际部署,这套智能Bootloader方案取得了显著的效果提升。在智能门锁项目中,我们对设备进行了固件升级,升级成功率从传统方案的92%提升到了99.8%,设备"变砖"率从千分之八降低到了万分之一以下。
增量更新技术的效果尤其明显。在典型的版本升级中,增量更新包的大小只有全量更新的15-25%,升级时间从平均18分钟缩短到5分钟,大大降低了因网络中断导致的升级失败概率。同时,减少的网络流量也为客户节省了可观的通信成本。
故障自愈功能在实际运行中也发挥了重要作用。系统自动检测并修复了大约0.3%的设备故障,这些故障如果没有自动修复,很可能会发展成为需要人工干预的严重问题。健康监控系统还提前预警了约0.5%的潜在故障,让我们能够提前采取预防措施。
性能优化总结
整个系统的性能优化体现在多个方面。启动时间通过智能分区选择和并行验证算法优化,从原来的8秒缩短到3秒。内存使用通过精心的数据结构设计和内存池管理,将峰值内存使用量控制在64KB以内。Flash磨损通过负载均衡和磨损均衡算法,将Flash的使用寿命延长了40%以上。
这些优化不仅提升了系统性能,更重要的是提高了整体的可靠性和用户体验。用户不再需要担心固件升级失败,设备能够自动处理各种异常情况,真正实现了"智能化"的固件管理。

未来展望与技术演进
随着边缘计算和人工智能技术的发展,未来的Bootloader将会更加智能化。我们正在研究基于机器学习的故障预测算法,通过分析设备的历史运行数据,提前预测可能出现的故障并采取预防措施。
另一个重要的发展方向是支持多固件并行运行。通过虚拟化技术,单个设备可以同时运行多个固件实例,实现更复杂的功能分离和故障隔离。这对于安全要求较高的应用场景具有重要意义。
云端协同也是未来的重要趋势。Bootloader将不再是一个独立的系统,而是整个设备管理生态系统的一部分。通过与云端服务的深度集成,可以实现更智能的版本管理、更精确的故障诊断和更高效的批量升级。
这套智能Bootloader方案已经在多个商业项目中得到验证,相信能为更多的嵌入式项目提供可靠的固件管理解决方案。在物联网设备日益普及的今天,这种高可靠性、智能化的固件管理能力将成为产品竞争力的重要组成部分。

沙发
Chad1989| | 2025-7-9 08:55 | 只看该作者
大而空,请分享你的git代码
板凳
hbzjt2011|  楼主 | 2025-7-9 10:51 | 只看该作者
Chad1989 发表于 2025-7-9 08:55
大而空,请分享你的git代码

请分享您的存款
地板
zjsx8192| | 2025-7-13 09:23 | 只看该作者
好像还没有这样开源的东东
5
Richard-jws| | 2025-7-16 14:52 | 只看该作者
要学习一下············
6
小涛DZGZS| | 2025-7-22 17:07 | 只看该作者
学习了
7
星辰伴梦| | 2025-7-23 13:41 | 只看该作者
非常佩服作者在嵌入式领域的深耕和创新,双分区设计和增量更新技术听起来非常前沿,能否分享一些实际应用案例?
8
脑洞星球居民| | 2025-7-23 20:58 | 只看该作者
非常详细的Bootloader设计分享,尤其是增量更新和故障自愈部分,对于我们这些嵌入式开发者来说非常有价值。期待看到更多的实战案例分析!
9
脑洞星球居民| | 2025-7-24 14:05 | 只看该作者
非常详尽的分享,智能Bootloader的设计思路和实现细节都很有前瞻性,特别是增量更新和故障自愈部分,这对于提升物联网设备的可靠性和用户体验至关重要。期待看到更多实际应用案例。
10
cooldog123pp| | 2025-7-24 16:07 | 只看该作者
楼主讲的很清晰很明确,受教了,mark一下以后经常来学习。
11
xixi2017| | 2025-7-26 11:54 | 只看该作者
学习一下如何实现。
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:欢迎参与LabVIEW版块的讨论学习! 点我一键即达

256

主题

2828

帖子

44

粉丝
3.22什么星座 中央民族大学什么档次 智障什么意思 喝什么可以排便通畅 低压高吃什么降压药
双侧附睾头囊肿是什么意思 为什么会得腱鞘炎 6月14号什么星座 紫癜吃什么好得快 alba手表是什么牌子
匿名是什么意思 茯苓有什么作用 红颜知己的意思是什么 天数是什么意思 香茗是什么意思
6.19什么星座 脾胃气滞吃什么中成药 大枣枸杞泡水喝有什么好处 过敏涂什么药膏 玉仁玫白膏有什么功效
8月26是什么星座hcv9jop8ns2r.cn 县委副书记是什么级别helloaicloud.com 木薯淀粉可以用什么代替zsyouku.com 糖醇是什么意思hcv8jop5ns1r.cn 左胸下方是什么部位hcv9jop2ns7r.cn
嗓子痒痒吃什么药0735v.com 缺钾是什么原因引起的mmeoe.com 小孩吃鼻屎是什么原因hcv7jop4ns5r.cn 鱼翅是什么东西hcv8jop6ns4r.cn 肠道痉挛吃什么药hcv9jop7ns1r.cn
速度是70迈心情是自由自在什么歌hcv7jop5ns1r.cn 第二性征是什么意思hcv9jop4ns0r.cn 天梭手表属于什么档次hcv8jop6ns8r.cn 1月11是什么星座jasonfriends.com 大姨妈是黑色是什么原因hcv9jop4ns7r.cn
什么是无性婚姻hcv8jop6ns3r.cn 走马观花的走什么意思hcv8jop0ns8r.cn 什么季节喝白茶hcv7jop5ns6r.cn 右眼皮跳什么预兆hcv8jop2ns6r.cn 梦见好多鱼是什么意思hcv7jop6ns9r.cn
百度