bootloader启动流程(4)

2020-05-01 10:43

(2) 调用target_volume_down()和target_volume_up()函数判断音量+-按键是否按下,如果按下,就设置key_bitmap[]对应的位为1,比如key_bitmap[KEY_VOLUMEDOWN]=1,这为后面进入线刷、recovery、还是正常启动模式做好判断依据。

这里音量+-是根据GPIO_90和GPIO_91的引脚来判断的。

1.3 target_sdc_init()

调用platform_boot_dev_isemmc()判断启动设备是否是EMMC,如果是就调用target_sdc_init()来初始化SDC(Secure digital controller)控制器接口 Sdc:Secure digital controllerinterface-supports EMMC

1.4 partition_read_table()

先读取MMC的MBR分区,如果是PMBR分区就读取GPT分区信息。 MBR(Master Boot Record)和GPT(GUID Partition Table).

《MBR和GPT概要学习》:

http://www.voidcn.com/blog/LoongEmbedded/article/p-6072230.html

1.4.1 mmc_get_device_blocksize() 获取EMMC的块大小,为512个字节。 1.4.2 mmc_boot_read_mbr() 读取EMMC的MBR

(1) 调用mmc_read()从0地址开始读取512字节的数据到buff中。

(2) partition_verify_mbr_signature()对读取出来数据的进行MBR签名核查。

如果buff[510]不等于0x55,或是buff[511]不等于0xAA,就说明MBR signature不匹配 (3) 在MBR中读取4个分区信息到我们的MBR表

EMMC的MBR由4部分组成,这里是要读分区表信息,其中包含4个分区项,偏移地址是01BEH--01FDH,每个分区表项长16个字节,共64字节为分区项1、分区项2、分区项3、分区项4

读取每个16字节的分区项时,先读取第5个字节对应的分区类型,如果为0xEE 表示该分区表是PMBR,紧随其后的应该是GPT分区表头和GPT分区表,因此这是一块GPT硬盘。 这里读取出来的值就是0xEE,表示此MMC采用GPT分区结构,如果不是,就按照MBR分区结构读取后面的分区信息

1.4.3 mmc_boot_read_gpt(),从MMC中读取GPT信息并填充分区表

GPT分区全名为GloballyUnique Identifier Partition Table Format,即全局唯一标示磁盘分区表格式

(1) mmc_get_device_capacity()获取MMC设备的密度,其值为1 (2) mmc_read()读取第1个扇区内容(第0个扇区是PMBR)。

(3) partition_parse_gpt_header()解析GPT分区表头,如果解析失败再去读取备份GPT分区表头

先读取和解析GPT分区表头,因为GPT分区表信息没有被破坏,就没有去读取备份分区表头信息。

1) 判断GPT头的大小,92个字节。

2) 计算GPT头的CRC并和之前写入的GPT头的CRC对比。 3) 读取GPT头的LBA和分区表项值 具体信息如下:

偏移地址24:当前的LBA(这个GPT头的位),这里为1

偏移地址40:第一个可用于分区的LBA(主分区表的最后一个LBA+1)

偏移地址48:最有一个可用于分区的LBA(备份分区表的第一个LBA-1) 偏移地址80:分区表项的数量,这里为32个

偏移地址84:一个分区表项的大小(通常为128),这里为128

分区表头的格式

起始长度 内容 字节 0

8字签名(\PART\) 节 8

4字修订 节

12 4字分区表头的大小

16 4字分区表头(第0-91字节)的CRC32校验,在计算时,把这个字段作为0处理,

节 需要计算出分区串行的CRC32校验后再计算本字段 20 4字保留,必须是 0

24 8字当前LBA(这个分区表头的位置)

32 8字备份LBA(另一个分区表头的位置)

40 8字第一个可用于分区的LBA(主分区表的最后一个LBA + 1)

48 8字最后一个可用于分区的LBA(备份分区表的第一个LBA ? 1)

56 16字硬盘GUID(在类UNIX系统中也叫UUID)

72 8字分区表项的起始LBA(在主分区表中是2)

80 4字分区表项的数量

84 4字一个分区表项的大小(通常是128)

88 4字分区串行的CRC32校验

节 92

(4) 读取GPT分区表中的分区信息,从第2~9个block读取,然后写入到记录分区信息的全局数组中partition_entrie[]

每个entry(分区表项)占128字节,所以一个block包含4个分区表项,而我们分区表项数量是32个,需要32/4=8个block。

GPT分区表项的格式

起始字节 长度

内容

* 保留,剩余的字节必须是0(对于512字节LBA的硬盘即是420个字节)

16字节 分区类型GUID 0

分区GUID 161 6字节

起始LBA(小端格式) 32 8字节 末尾LBA 40 8字节

属性标签(如:60表示\只读\) 48 8字节

分区名(可以包括36个UTF-16(小端格式)字符) 567 2字节

对应的结构体定义如下

/* Unified mbr and gpt entry types */struct partition_entry {

unsignedchar type_guid[PARTITION_TYPE_GUID_SIZE]; unsigneddtype;

unsignedchar unique_partition_guid[UNIQUE_PARTITION_GUID_SIZE];

unsignedlong long first_lba; unsignedlong long last_lba; unsignedlong long size;

unsignedlong long attribute_flag; unsignedchar name[MAX_GPT_NAME_SIZE]; uint8_tlun; };

到此partition_entry关于GPT分区表项的信息已获知。 1.5 shutdown_detect() #if LONG_PRESS_POWER_ON

shutdown_detect();#endif

如果开启长按power按键开机(大概2~3s)机制,就会调用此函数,如果按power按键时间短于这个时间,就会关机。

1.6 target_use_signed_kernel() if (target_use_signed_kernel())

target_crypto_init_params();

target_use_signed_kernel()函数在bootloader/lk/target/init.c实现 __WEAK booltarget_use_signed_kernel(void){#if _SIGNED_KERNEL return1;#else return0;#endif }

没有定义_SIGNED_KERNEL,所以直接返回0,也就没调用target_crypto_init_params()。

1.7 rpm_smd_init() #if SMD_SUPPORT

rpm_smd_init();#endif


bootloader启动流程(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:第十章 中央银行货币政策工具与业务操作(中央银行学,王广谦)

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: