avb校验相关与块校验原理

文章详细阐述了Linux系统在启动过程中针对块设备的校验流程,涉及到VerifiedBoot.c和LinuxLoader.c等关键组件。通用块设备层处理I/O请求,包括扇区、块、段和数据页的概念。动态校验流程中,verity_end_io函数用于处理错误并触发工作队列进行校验。dm-verity用于保证数据完整性,通过创建哈希树并配置目标表来验证块设备上的数据。此外,文章还提到了init用户态流程和清除panic标识的方法。

一、启动校验流程

edk2/QcomModulePkg/Library/avb/VerifiedBoot.c
DEBUG ((EFI_D_ERROR, "LoadImageAndAuth failed %r\n", Status)); in LoadImageAndAuth()

edk2/QcomModulePkg/Application/LinuxLoader/LinuxLoader.c
DEBUG ((EFI_D_ERROR, "LoadImageAndAuth failed: %r\n", Status));

BootLib/PartitionTableUpdate.c
/QcomModulePkg/Library/avb/libavb/avb_slot_verify.c
LinuxLoaderEntry
    Status = GetRebootReason (&BootReason);
    校验启动原因
    EnumeratePartitions()
    FindPtnActiveSlot
    UpdatePartitionEntries()   -----   加载avb分区
    LoadImageAndAuth      ---------------                  VerifiedBoot.c 
        FindBootableSlot    --------------         PartitionTableUpdate.c//error
            GetBootPartitionEntry 
            HandleActiveSlotUnbootable          //一直返回错误
                GetBootPartitionEntry             // BootEntry       检测没过
                GetActiveSlot                     //success
                    GetBootPartitionEntry    -----    for()
        LoadImageAndAuthVB2  ---------------           VerifiedBoot.c 
            avb_should_update_rollback
                IsCurrentSlotBootable
            avb_slot_verify    ------------------      avb_slot_verify.c
                load_and_verify_vbmeta
                    ops->read_from_partition(ops,  
                        AvbReadFromPartition
                           "Load Image %a total time: %lu ms \n"
                    avb_vbmeta_image_verify
                        avb_rsa_verify
                            iavb_parse_key_data                 //Unexpected key length
                avb_manage_hashtree_error_mode
                avb_append_options   //avb 根据resolved_hashtree_error_mode 设置verity_mode
                    cmdline_append_option    //设置verity_mode到slot_data->cmdline
                avb_sub_cmdline
            HandleActiveSlotUnbootable                //当前槽置为unbootable
            AppendVBCmdLine      //cmdline赋值到VBCmdLine
        DisplayVerifiedBootScreen
            DisplayVerifiedBootMenu
    BootLinux (&Info);
         UpdateCmdLine
             AddtoBootConfigList   //gBS = SystemTable->BootServices;这里会利用uefi boot服务记录map

二、通用块设备层对请求的处理

2.1 块设备概述

在这里插入图片描述

在这里插入图片描述
• 块设备的控制器传输的固定数据单元大小称为扇区(sector)。因此I/O调度器
和块设备驱动必须以扇区为单位管理数据。
• 虚拟文件系统、映射层(mapping layer)管理磁盘数据的逻辑单元大小称为块
(block)。对于文件系统来说,块是最小的磁盘数据存储单元。
• 前面在分散/聚合DMA中,我们提到块设备驱动应该能够处理称为“段”的数据
单元;每个“段”是内存中的一页或页的一部分,“段”中的数据在磁盘上是
连续的。
• 磁盘缓冲区处理的数据单元大小为“页”,每个对应一个页帧。(注1)
• 通用块设备层粘合所有上层和底层的部分,这样它就知道扇区、块、段和数据
页。

在这里插入图片描述
bi_io_vecs指向一个bio_vec结构体数组,该结构体链表包含了一个特定I/O操作所需要
使用到的所有段(segment)。每个bio_vec结构都是一个形式为<page, offset, len>的向量,
它描述的是一个特定的段:段所在的物理页、块在物理页中的偏移量、从给定偏移量开始的
块长度。整个bio_io_vec结构体数组表示了一个完整的缓冲区。bio_vec结构体定义在文件
include/linux/bio.h中。

内核使用gendisk结构,定义在include/linux/genhd.h中,来表示一个独立的磁盘设备。
实际上内核还使用gendisk表示分区,但是驱动程序不需要了解这些。在gendisk结构中的许
多成员必须由驱动程序进行初始化。
物理磁盘通常被分成多个逻辑分区。每个块设备文件可以表示一个整个物理磁盘或者其
中的一个分区。如/dev/sda、/dev/sda1、/dev/sda2等。若一个物理磁盘有多个分区,则磁
盘的布局保存在hd_struct数据结构数组中,数组的地址由gendisk结构体中的part成员保存。
hd_struct数据结构的定义在文件include/linux/genhd.h中。
在这里插入图片描述
当内核在系统中发现一个新磁盘时,调用alloc_disk()分配相关数据结构,如gendisk,
hd_struct等,然后调用add_disk()将磁盘添加到系统中。注意:一旦调用了add_disk,
磁盘设备就被“激活“,表示可以使用,并随时会调用它们提供的方法。

2.2向通用块设备层发送请求

  1. 上层下发磁盘数据请求
  2. 通用块层申请bio结构,将请求的数据分段记录到bio中
  3. 如果请求的数据大于一个bio允许的最大数据量,则将请求分成多个bio
  4. 调用submit_bio提交bio请求
  5. submit_bio函数经过层层调用,最终调用块设备请求队列中的make_request_fn成员函数将bio提交给I/O调度层进行处理

generic_make_request函数将bio连接到current->bio_list链表中,并调用__generic_make_request函数提交链表中所有的bio。
在这里插入图片描述
__generic_make_request函数最终会调用块设备的请求队列中的make_request_fn成员函数将bio请求发送给I/O调度层,至此对磁盘的数据请求离开通用块层,进入下一层——I/O调度层

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值