Edit online

SPI NOR 加载

4 Dec 2024
Read time: 2 minute(s)

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()  // 根据 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()  // 根据 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