技术笔记20230716 rBoot学习1

技术笔记20230716

  今天我准备找一款适用于ESP8266的bootloader来学习一下。于是,我在github上找到了一个名为raburton/rboot的开源项目。首先看一下它的readme。

rBoot的背景

  rBoot-一款用于ESP8266的开源bootloader。作者是Richard A Burton,一位80后英国老哥。Richard A Burton有一个网站,地址为:http://richard.burtons.org/。
  下面介绍一下readme中技术相关的内容。rBoot是为替代乐鑫官方提供的SDK中的bootloader而设计的。相比于官方SDK不公开源代码中的二进制bootloader文件,rBoot开源并且灵活。相比于乐鑫SDK库中的Espressif bootloader,rBoot拥有许多优点:①使用C语言编写并且开源。②支持256个ROM分区。③ROM分区的大小可以自由定义。④能够测试多个ROM分区来找到有效的备份而无需重置。⑤Flash的布局可以随时改变,rBoot能够合理链接分散于不同区块的img。⑥可以使用GPIO来选择使用哪些ROM分区来启动。⑦rBoot不浪费栈空间,而官方SDK中的bootloader需要占用144个字节的栈空间。⑧文档化的配置结构方便用户更改配置。⑨可以验证带有校验信息的.irom0.text段。⑩可以临时选择next-boot rom==(暂时不知道是什么意思)==。

相关限制

  ESP8266只能将1MB的Flash映射到内存中,但是可以选择需要映射的Flash扇区。这就允许单个ROM扇区的大小达到1MB,但是这1MB不能跨越Flash中1MB的边界。这意味着我们可以在一个4MB的Flash上划分出4个1MB的ROM或者8个512KB的ROM,或者二者的结合。但是,需要注意的是,不能在一个512KB的ROM后面紧跟着一个1MB的ROM,那样的话第二个ROM就会跨过1MB的边界。默认情况下,rBoot禁止使用Flash前1MB之后的空间,因为需要几个步骤才能使其工作。详细说明请参见下面的说明。

创建工程

  rBoot包含一个Makefile,它需要与gcc Xtensa交叉编译器一同使用。rBoot包含两个源文件,第一个被编译并且作为数据被包含在第二个文件中。当代码运行时,这段代码会被复制到内存中并执行。这样做有一个很好的理由,可以从Richard A Burton的博客中找到解释。make文件可以管理rBoot工程,但需要Richard A Burton的esptool2。
  需要将Makefile中的变量SDK_BASE的值设为Espressif SDK的根目录,并且将变量XTENSA_BINDIR的值设为xtensa-gcc的bin目录或者将其包含在PATH中。可以将这些设置加入环境变量之中也可以通过编辑Makefile来设置。
  两个小的汇编存根(stub)函数允许bootloader启动用户代码而不保留bootloader在栈中所占用的空间。官方SDK的bootloader会永久占用栈上的144个字节的空间。这在GCC中可以正常编译,但如果使用其他编译器,rBoot可能无法编译或工作。这时可以取消rboot.h中的#define BOOT_NO_ASM注释,来使用这些函数的C语言实现版本。但这将会占用32字节的栈空间。
  以上介绍使用SDK v2.2和GCC v4.8.5进行了测试。

烧录

  只需要将boot.bin写入Flash的第一个扇区即可。烧录时需要检查所使用的Flash工具是否正确设置了Flash的大小。运行时,rBoot将在第二扇区的开始处创建相关配置,用于一个简单的双磁盘(rom)系统。然后,我们可以将两个系统写进Flash的地址0x2000和(Flash大小的一半+0x2000)。例如,使用1MB大小的Flash可以使用:esptool.py write_flash -fs 8m 0x0000 rboot.bin 0x2000 user1.bin 0x82000 user2.bin
  注意:我们烧录设备可能需要指定其他选项。例如,-fm dio选项。
  想要获取更有趣的空间布局,我们需要手动编写rBoot配置扇区,具体方法参见下一步。
  项目中有两个名为testload的bin文件可以烧录进普通的用户空间来测试rBoot。我们正常使用时不需要用到。

配置

typedef struct {
	uint8_t magic;           // our magic
	uint8_t version;         // config struct version
	uint8_t mode;            // boot loader mode
	uint8_t current_rom;     // currently selected rom
	uint8_t gpio_rom;        // rom to use for gpio boot
	uint8_t count;           // number of roms in use
	uint8_t unused[2];       // padding
	uint32_t roms[MAX_ROMS]; // flash addresses of the roms
#ifdef BOOT_CONFIG_CHKSUM
	uint8_t chksum;          // boot config chksum
#endif
} rboot_config;

你可能感兴趣的:(技术笔记,笔记,学习,mcu,开源软件)