3.6.5. SPI NOR 加载
common/spl/spl_spi.c 中通过宏注册了 SPI NOR 的程序加载器。
SPL_LOAD_IMAGE_METHOD("SPI", 1, BOOT_DEVICE_SPI, spl_spi_load_image);
在 SPL 初始化过程中,通过 boot_from_devices(spl_boot_list)
函数调用,检查当前项目
所支持的 SPL 读取的存储介质类型,然后依次检查是否存在对应的程序加载器。
board_init_r() // common/spl/spl.c
|-> boot_from_devices(spl_boot_list)
|-> spl_ll_find_loader() // 根据boot device找到spl_load_image指针
// 这里可能是各种介质的 load image 函数
// SPL_LOAD_IMAGE_METHOD() 定义的 Loader
// 可能是 MMC/SPI/BROM/...
找到 SPL SPI NOR Loader 之后,从项目配置的指定位置读取数据。
SPI NOR 加载器需要编译时配置所用的 SPI 信息:
CONFIG_SF_DEFAULT_BUS
CONFIG_SF_DEFAULT_CS
CONFIG_SF_DEFAULT_SPEED
CONFIG_SF_DEFAULT_MODE
读取数据的位置通过下面的配置指定:
CONFIG_SYS_SPI_U_BOOT_OFFS
boot_from_devices(spl_boot_list); // common/spl/spl.c
|-> spl_ll_find_loader() // 根据boot device找到spl_load_image指针
| // 此处通过遍历固件的 .u_boot_list_2_spl_image_loader_* 段
| // 找到当前支持的存储介质,然后逐个尝试
|
|-> spl_load_image(loader);
|-> loader->load_image(spl_image, &bootdev);
spl_spi_load_image(); // common/spl/spl_spi.c
|-> spi_flash_probe();
|-> spl_get_load_buffer(-sizeof(*header), sizeof(*header));
|-> spi_flash_read(header);
|-> spl_parse_image_header();
|-> spi_flash_read();
|-> spi_flash_read_dm(flash->dev, offset, len, buf);
|-> sf_get_ops(dev)->read(dev, offset, len, buf);
spi_flash_std_read(dev, offset, len, buf);
| // drivers/mtd/spi/sf_probe.c
|-> mtd->_read(mtd, offset, len, &retlen, buf);
spi_flash_mtd_read(mtd, offset, len, &retlen, buf);
// drivers/mtd/spi/sf_mtd.c