bootloaders
什么是BootLoader?
一般来说,bootloader是一种软件/固件,它在SoC上电后立即运行。bootloader的主要职责是启动软件的后续部分,例如操作系统、baremetal应用程序或在某些情况下另一个bootloader。当涉及到嵌入式时,bootloader通常与底层SoC体系结构密切相关。bootloader通常存储在一个受保护的、非易失性的片上存储器中。通常bootloader执行各种硬件检查,初始化处理器和配置SoC寄存器等。由于bootloader的主要目的是加载下一个软件,因此它需要与外部通信以接收此固件/应用程序映像。这可以通过许多协议- USB, UART, SPI, I2C,外部闪存,内部闪存,SD卡,以太网,can等。bootloader也是嵌入式安全性中的一个关键组件。硬件信任根通常被传递到bootloader,并沿着线路传递。
在MCU+SDK支持的设备中,第一bootloader被刻录到设备的只读存储器中,被认为是设备固件/ ROM。在MCU+SDK中,所说的“bootloader”大多指的是二级bootloader,或SBL。
Multi-Stage Bootloader
出于安全考虑,第一个bootloader通常保存在安全的只读内存中,并且在应用程序软件启动之前总是有一个已知的状态。因此,保持这个bootloader的简单性并让它只执行所需的最低配置是有意义的。这个辅助引导加载程序可以很复杂,也可以进行配置,以满足应用程序的需要。与第一阶段bootloader相比,这也可以很容易地更新。事实上,对于MCU+SDK中的设备,我们有两个阶段的引导加载程序——第一个阶段的bootloader称为ROM bootloader (RBL),第二个阶段的bootloader称为Secondary bootloader (SBL)。
Multi-Core BootLoading
当有多阶段引导加载时,多核引导加载几乎总是一个后续。在这种情况下,第一个bootloader技术上可能甚至不知道其他核心,它只会引导下一个阶段的bootloader,而第二个阶段的bootloader将负责不同核心上的复杂引导加载。
加载多核应用程序比加载单核应用程序稍微复杂一些。在映像准备、共享内存访问等方面存在一些问题。大多数情况下,会有一种特定的格式来创建各个核心图像,然后它们可能会/可能不会被连接到单个图像中供SBL加载。无论应用程序图像的格式是什么,SBL都应该知道它,以便正确地解析和加载图像。
Hit any key to stop autoboot: 0
=> mmc list
mmc@fa10000: 0
mmc@fa00000: 1 (SD)
=> printenv partitions
partitions=name=rootfs,start=0,size=-,uuid=${uuid_gpt_rootfs}
=> uuidgen
Unknown command 'uuidgen' - try 'help'
=> uuidgen -try
Unknown command 'uuidgen' - try 'help'
=> mmc partPartition Map for MMC device 0 -- Partition Type: DOSPart Start Sector Num Sectors UUID Type1 1 522240 f9b70d9c-01 0c Boot2 522241 4700160 f9b70d9c-02 83
=>
=> mmc dev
switch to partitions #0, OK
mmc0(part 0) is current device
=> mmc list
mmc@fa10000: 0 (eMMC)
mmc@fa00000: 1 (SD)
=> mmc dev
switch to partitions #0, OK
mmc0(part 0) is current device
=> mmc read
mmc - MMC sub systemUsage:
mmc info - display info of the current MMC device
mmc read addr blk# cnt
mmc write addr blk# cnt
mmc erase blk# cnt
mmc rescan [mode]
mmc part - lists available partition on current mmc device
mmc dev [dev] [part] [mode] - show or set current mmc device [partition] and set mode- the required speed mode is passed as the index from the following list[MMC_LEGACY, MMC_HS, SD_HS, MMC_HS_52, MMC_DDR_52, UHS_SDR12, UHS_SDR25,UHS_SDR50, UHS_DDR50, UHS_SDR104, MMC_HS_200, MMC_HS_400, MMC_HS_400_ES]
mmc list - lists available devices
mmc wp - power on write protect boot partitions
mmc hwpartition [args...] - does hardware partitioningarguments (sizes in 512-byte blocks):[user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes[gp1|gp2|gp3|gp4 cnt [enh] [wrrel {on|off}]] - general purpose partition[check|set|complete] - mode, complete set partitioning completedWARNING: Partitioning is a write-once setting once it is set to complete.Power cycling is required to initialize partitions after set to complete.
mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode- Set the BOOT_BUS_WIDTH field of the specified device
mmc bootpart-resize <dev> <boot part size MB> <RPMB part size MB>- Change sizes of boot and RPMB partitions of specified device
mmc partconf dev [boot_ack boot_partition partition_access]- Show or change the bits of the PARTITION_CONFIG field of the specified device
mmc rst-function dev value- Change the RST_n_FUNCTION field of the specified deviceWARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.
mmc setdsr <value> - set DSR register value=> printenv
addr_fit=0x90000000
arch=arm
args_all=setenv optargs ${optargs} earlycon=ns16550a,mmio32,0x02800000 ${mtdparts}
args_mmc=run finduuid;setenv bootargs console=${console} ${optargs} root=PARTUUID=${uuid} rw rootfstype=${mmcrootfstype}
args_nand=setenv bootargs console=${console} ${optargs} ubi.mtd=${nbootpart} root=${nbootvolume} rootfstype=ubifs
args_usb=run finduuid;setenv bootargs console=${console} ${optargs} root=PARTUUID=${uuid} rw rootfstype=${mmcrootfstype}
baudrate=115200
board=am64x
board_name=am64x_gpevm
board_rev=A
board_serial=0230
board_software_revision=01
boot=mmc
boot_fdt=try
boot_fit=0
bootcmd=run findfdt; run envboot; run init_${boot}; if test ${boot_fit} -eq 1; then run get_fit_${boot}; run get_overlaystring; run run_fit; else; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern; fi;
bootdelay=2
bootdir=/boot
bootenvfile=uEnv.txt
bootm_size=0x10000000
bootpart=1:2
bootscript=echo Running bootscript from mmc${mmcdev} ...; source ${loadaddr}
console=ttyS2,115200n8
cpu=armv8
dfu_alt_info_emmc=rawemmc raw 0 0x800000 mmcpart 1;rootfs part 0 1 mmcpart 0;tiboot3.bin.raw raw 0x0 0x800 mmcpart 1;tispl.bin.raw raw 0x800 0x1000 mmcpart 1;u-boot.img.raw raw 0x1800 0x2000 mmcpart 1;u-env.raw raw 0x3800 0x100 mmcpart 1
dfu_alt_info_mmc=boot part 1 1;rootfs part 1 2;tiboot3.bin fat 1 1;tispl.bin fat 1 1;u-boot.img fat 1 1;uEnv.txt fat 1 1;sysfw.itb fat 1 1
dfu_alt_info_ospi=tiboot3.bin raw 0x0 0x100000;tispl.bin raw 0x100000 0x200000;u-boot.img raw 0x300000 0x400000;u-boot-env raw 0x700000 0x020000;rootfs raw 0x800000 0x3800000
dfu_alt_info_ram=tispl.bin ram 0x80080000 0x200000;u-boot.img ram 0x81000000 0x400000
dtboaddr=0x89000000
envboot=mmc dev ${mmcdev}; if mmc rescan; then echo SD/MMC found on device ${mmcdev};if run loadbootscript; then run bootscript;else if run loadbootenv; then echo Loaded env from ${bootenvfile};run importbootenv;fi;if test -n $uenvcmd; then echo Running uenvcmd ...;run uenvcmd;fi;fi;fi;
eth1addr=70:ff:76:1e:28:b8
eth2addr=70:ff:76:1e:28:b9
ethaddr=f4:84:4c:f9:7d:05
fdt_addr_r=0x88000000
fdtaddr=0x88000000
fdtcontroladdr=edeb7880
fdtoverlay_addr_r=0x80200000
findfdt=if test $board_name = am64x_gpevm; then setenv fdtfile k3-am642-evm.dtb; fi; if test $board_name = am64x_skevm; then setenv fdtfile k3-am642-sk.dtb; fi;if test $fdtfile = undefined; then echo WARNING: Could not determine device tree to use; fi;
finduuid=part uuid ${boot} ${bootpart} uuid
get_fdt_mmc=load mmc ${bootpart} ${fdtaddr} ${bootdir}/${fdtfile}
get_fdt_nand=ubifsload ${fdtaddr} ${bootdir}/${fdtfile};
get_fdt_usb=load usb ${bootpart} ${fdtaddr} ${bootdir}/${fdtfile}
get_fit_mmc=load mmc ${bootpart} ${addr_fit} ${bootdir}/${name_fit}
get_fit_nand=ubifsload ${addr_fit} ${bootdir}/${name_fit}
get_fit_usb=load usb ${bootpart} ${addr_fit} ${bootdir}/${name_fit}
get_kern_mmc=load mmc ${bootpart} ${loadaddr} ${bootdir}/${name_kern}
get_kern_nand=ubifsload ${loadaddr} ${bootdir}/${name_kern}
get_kern_usb=load usb ${bootpart} ${loadaddr} ${bootdir}/${name_kern}
get_overlay_mmc=fdt address ${fdtaddr};fdt resize 0x100000;for overlay in $name_overlays;do;load mmc ${bootpart} ${dtboaddr} ${bootdir}/${overlay} && fdt apply ${dtboaddr};done;
get_overlay_nand=fdt address ${fdtaddr};fdt resize 0x100000;for overlay in $name_overlays;do;ubifsload ${dtboaddr} ${bootdir}/${overlay} && fdt apply ${dtboaddr};done;
get_overlay_usb=fdt address ${fdtaddr};fdt resize 0x100000;for overlay in $name_overlays;do;load usb ${bootpart} ${dtboaddr} ${bootdir}/${overlay} && fdt apply ${dtboaddr};done;
get_overlaystring=for overlay in $name_overlays;do;setenv overlaystring ${overlaystring}'#'${overlay};done;
importbootenv=echo Importing environment from mmc${mmcdev} ...; env import -t ${loadaddr} ${filesize}
init_mmc=run args_all args_mmc
init_nand=run args_all args_nand ubi_init
init_usb=run args_all args_usb
kernel_addr_r=0x82000000
loadaddr=0x82000000
loadbootenv=fatload mmc ${mmcdev} ${loadaddr} ${bootenvfile}
loadbootscript=load mmc ${mmcdev} ${loadaddr} boot.scr
loadfdt=load ${devtype} ${bootpart} ${fdtaddr} ${bootdir}/${fdtfile}
loadimage=load ${devtype} ${bootpart} ${loadaddr} ${bootdir}/${bootfile}
mmcboot=mmc dev ${mmcdev}; devnum=${mmcdev}; devtype=mmc; if mmc rescan; then echo SD/MMC found on device ${mmcdev};if run loadimage; then run args_mmc; if test ${boot_fit} -eq 1; then run run_fit; else run mmcloados;fi;fi;fi;
mmcdev=1
mmcloados=if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdtaddr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
mmcrootfstype=ext4 rootwait
mtdids=nor0=fc40000.spi.0,nand0=omap2-nand.0
mtdparts=mtdparts=fc40000.spi.0:1m(ospi.tiboot3),2m(ospi.tispl),4m(ospi.u-boot),256k(ospi.env),256k(ospi.env.backup),57088k@8m(ospi.rootfs),256k(ospi.phypattern);omap2-nand.0:2m(NAND.tiboot3),2m(NAND.tispl),2m(NAND.tiboot3.backup),4m(NAND.u-boot),256k(NAND.u-boot-env),256k(NAND.u-boot-env.backup),-(NAND.file-system)
name_fit=fitImage
name_kern=Image
nbootpart=NAND.file-system
nbootvolume=ubi0:rootfs
partitions=name=rootfs,start=0,size=-,uuid=${uuid_gpt_rootfs}
pxefile_addr_r=0x80100000
ramdisk_addr_r=0x88080000
rd_spec=-
rdaddr=0x88080000
run_fit=bootm ${addr_fit}#${fdtfile}${overlaystring}
run_kern=booti ${loadaddr} ${rd_spec} ${fdtaddr}
scriptaddr=0x80000000
serial#=0000000000000230
soc=k3
stderr=serial@2800000
stdin=serial@2800000
stdout=serial@2800000
ubi_init=ubi part ${nbootpart}; ubifsmount ${nbootvolume};
update_to_fit=setenv loadaddr ${addr_fit}; setenv bootfile ${name_fit}
usbboot=setenv boot usb;setenv bootpart 0:2;usb start;run findfdt;run init_usb;run get_kern_usb;run get_fdt_usb;run run_kern
vendor=tiEnvironment size: 5742/131068 bytes
错误记录:以下流程并不能成功的从eMMC启动,分区存在问题,应按照Flash Linux to eMMc进行
root@am64xx-evm:~# uuidgen
b8988730-0989-4d66-9951-175b5874a726
root@am64xx-evm:~# uuidgen
7d70f57d-5c14-4264-a117-354ab179f85a
Partitioning eMMC from U-Boot
=> printenv partitions
partitions=name=rootfs,start=0,size=-,uuid=${uuid_gpt_rootfs}
=> setenv uuid_gpt_disk b8988730-0989-4d66-9951-175b5874a726
=> setenv uuid_gpt_disk 7d70f57d-5c14-4264-a117-354ab179f85a
=> mmc list
mmc@fa10000: 0
mmc@fa00000: 1 (SD)=> gpt write mmc 0 ${partitions}
Writing GPT: success!=> mmc partPartition Map for MMC device 0 -- Partition Type: EFIPart Start LBA End LBA NameAttributesType GUIDPartition GUID1 0x00000022 0x01da3fde "rootfs"attrs: 0x0000000000000000type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7guid: 76a96b6e-570c-2344-96f9-059fa509c224
=> setenv uuid_gpt_disk b8988730-0989-4d66-9951-175b5874a726
=> setenv uuid_gpt_rootfs 7d70f57d-5c14-4264-a117-354ab179f85a
=> gpt write mmc 0 ${partitions}
Writing GPT: success!
=> mmc partPartition Map for MMC device 0 -- Partition Type: EFIPart Start LBA End LBA NameAttributesType GUIDPartition GUID1 0x00000022 0x01da3fde "rootfs"attrs: 0x0000000000000000type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7guid: 7d70f57d-5c14-4264-a117-354ab179f85a
=> printenv dfu_alt_info_mmc
dfu_alt_info_mmc=boot part 1 1;rootfs part 1 2;tiboot3.bin fat 1 1;tispl.bin fat 1 1;u-boot.img fat 1 1;uEnv.txt fat 1 1;sysfw.itb fat 1 1
=> mmc dev 0
switch to partitions #0, OK
mmc0(part 0) is current device
=> printenv dfu_alt_info_mmc
dfu_alt_info_mmc=boot part 1 1;rootfs part 1 2;tiboot3.bin fat 1 1;tispl.bin fat 1 1;u-boot.img fat 1 1;uEnv.txt fat 1 1;sysfw.itb fat 1 1
=> mmc dev 1
switch to partitions #0, OK
mmc1 is current device
=> printenv dfu_alt_info_mmc
dfu_alt_info_mmc=boot part 1 1;rootfs part 1 2;tiboot3.bin fat 1 1;tispl.bin fat 1 1;u-boot.img fat 1 1;uEnv.txt fat 1 1;sysfw.itb fat 1 1
=> setenv dfu_alt_info ${dfu_alt_info_mmc}
=> dfu 0 mmc 0
Couldn't find part #2 on mmc device #1
DFU entities configuration failed!
(partition table does not match dfu_alt_info?)
dfu - Device Firmware UpgradeUsage:
dfu <USB_controller> [<interface> <dev>] [list]- device firmware upgrade via <USB_controller>on device <dev>, attached to interface<interface>[list] - list available alt settings=> mmc dev 0
switch to partitions #0, OK
mmc0(part 0) is current device
=> setenv dfu_alt_info ${dfu_alt_info_mmc}
=> dfu 0 mmc 0
Couldn't find part #2 on mmc device #1
DFU entities configuration failed!
(partition table does not match dfu_alt_info?)
dfu - Device Firmware UpgradeUsage:
dfu <USB_controller> [<interface> <dev>] [list]- device firmware upgrade via <USB_controller>on device <dev>, attached to interface<interface>[list] - list available alt settings=> mmc dev 0 1
switch to partitions #1, OK
mmc0(part 1) is current device
=> fatload mmc 1 ${loadaddr} tispl.bin
855435 bytes read in 37 ms (22 MiB/s)
=> mmc write ${loadaddr} 0x0 0x800MMC write: dev # 0, block # 0, count 2048 ... 2048 blocks written: OK
=> fatload mmc 1 ${loadaddr} tiboot3.bin
563594 bytes read in 25 ms (21.5 MiB/s)
=> mmc write ${loadaddr} 0x0 0x800MMC write: dev # 0, block # 0, count 2048 ... 2048 blocks written: OK
=> fatload mmc 1 ${loadaddr} tispl.bin
855435 bytes read in 37 ms (22 MiB/s)
=> mmc write ${loadaddr} 0x800 0x1000MMC write: dev # 0, block # 2048, count 4096 ... 4096 blocks written: OK
=> fatload mmc 1 ${loadaddr} u-boot.img
1119679 bytes read in 49 ms (21.8 MiB/s)
=> mmc write ${loadaddr} 0x1800 0x2000MMC write: dev # 0, block # 6144, count 8192 ... 8192 blocks written: OK
=> mmc partPartition Map for MMC device 0 -- Partition Type: EFIGUID Partition Table Header signature is wrong: 0x32472641DEEE9E91 != 0x5452415020494645
find_valid_gpt: *** ERROR: Invalid GPT ***
GUID Partition Table Header signature is wrong: 0x0 != 0x5452415020494645
find_valid_gpt: *** ERROR: Invalid Backup GPT ***
=> mmc partconf 0 1 1 1
=> mmc bootbus 0 2 0 0
=> mmc partPartition Map for MMC device 0 -- Partition Type: EFIGUID Partition Table Header signature is wrong: 0x32472641DEEE9E91 != 0x5452415020494645
find_valid_gpt: *** ERROR: Invalid GPT ***
GUID Partition Table Header signature is wrong: 0x0 != 0x5452415020494645
find_valid_gpt: *** ERROR: Invalid Backup GPT ***
=> mmc info
Device: mmc@fa10000
Manufacturer ID: 13
OEM: 14e
Name: S0J56
Bus Speed: 200000000
Mode: HS400 (200MHz)
Rd Block Len: 512
MMC version 5.1
High Capacity: Yes
Capacity: 14.8 GiB
Bus Width: 8-bit DDR
Erase Group Size: 512 KiB
HC WP Group Size: 8 MiB
User Capacity: 14.8 GiB WRREL
Boot Capacity: 31.5 MiB ENH
RPMB Capacity: 4 MiB ENH
Boot area 0 is not write protected
Boot area 1 is not write protected
=> mmc list
mmc@fa10000: 0 (eMMC)
mmc@fa00000: 1 (SD)
=> mmc dev 1
switch to partitions #0, OK
mmc1 is current device
=> mmc info
Device: mmc@fa00000
Manufacturer ID: 3
OEM: 5344
Name: SB16G
Bus Speed: 50000000
Mode: SD High Speed (50MHz)
Rd Block Len: 512
SD version 3.0
High Capacity: Yes
Capacity: 14.8 GiB
Bus Width: 4-bit
Erase Group Size: 512 Bytes// fatinfo 命令用于查询指定 MMC 设置指定分区的文件系统信息,格式如下:
=> fatinfo mmc 1:1
Interface: MMCDevice 1: Vendor: Man 000003 Snr 4e29fe01 Rev: 10.4 Prod: SB16G▒Type: Removable Hard DiskCapacity: 15193.5 MB = 14.8 GB (31116288 x 512)
Filesystem: FAT16 "boot "// fatls 命令用于查询 FAT 格式设备的目录和文件信息,命令格式如下
=> fatls mmc 1:11490 uEnv.txt318 wificfgSystem Volume Information/131072 uboot.env1 .psdk_setup563594 tiboot3.bin855435 tispl.bin1119679 u-boot.img7 file(s), 1 dir(s)//fstype 用于查看 MMC 设备某个分区的文件系统格式,命令格式如下:
=> fstype mmc 1:1
fat
=> fstype mmc 1:2
ext4
=> mmc partPartition Map for MMC device 0 -- Partition Type: EFIPart Start LBA End LBA NameAttributesType GUIDPartition GUID1 0x00000022 0x01da3fde "rootfs"attrs: 0x0000000000000000type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7guid: 7d70f57d-5c14-4264-a117-354ab179f85a
=> mmc dev 1
switch to partitions #0, OK
mmc1 is current device
=> mmc partPartition Map for MMC device 1 -- Partition Type: DOSPart Start Sector Num Sectors UUID Type1 2048 275610 ade9031b-01 0c Boot2 278528 5151216 ade9031b-02 83
=> mmc dev 0
switch to partitions #0, OK
mmc0(part 0) is current device
=> mmc partPartition Map for MMC device 0 -- Partition Type: EFIPart Start LBA End LBA NameAttributesType GUIDPartition GUID1 0x00000022 0x01da3fde "rootfs"attrs: 0x0000000000000000type: ebd0a0a2-b9e5-4433-87c0-68b6b72699c7guid: 7d70f57d-5c14-4264-a117-354ab179f85a
=> printenv dfu_alt_info_mmc
dfu_alt_info_mmc=boot part 1 1;rootfs part 1 2;tiboot3.bin fat 1 1;tispl.bin fat 1 1;u-boot.img fat 1 1;uEnv.txt fat 1 1;sysfw.itb fat 1 1
=> mmc dev 1
switch to partitions #0, OK
mmc1 is current device
=> printenv dfu_alt_info_mmc
dfu_alt_info_mmc=boot part 1 1;rootfs part 1 2;tiboot3.bin fat 1 1;tispl.bin fat 1 1;u-boot.img fat 1 1;uEnv.txt fat 1 1;sysfw.itb fat 1 1
=> mmc dev 01
switch to partitions #0, OK
mmc1 is current device
=> mmc dev 0 1
switch to partitions #1, OK
mmc0(part 1) is current device
=> fatload mmc 1 ${loadaddr} tiboot3.bin
563594 bytes read in 26 ms (20.7 MiB/s)
=> mmc write ${loadaddr} 0x0 0x800MMC write: dev # 0, block # 0, count 2048 ... 2048 blocks written: OK
=> fatload mmc 1 ${loadaddr} tispl.bin
855435 bytes read in 37 ms (22 MiB/s)
=> mmc write ${loadaddr} 0x800 0x1000MMC write: dev # 0, block # 2048, count 4096 ... 4096 blocks written: OK
=> fatload mmc 1 ${loadaddr} u-boot.img
1119679 bytes read in 49 ms (21.8 MiB/s)
=> mmc write ${loadaddr} 0x1800 0x2000MMC write: dev # 0, block # 6144, count 8192 ... 8192 blocks written: OK
=> mmc partconf 0 1 1 1
=> mmc bootbus 0 2 0 0
=> saveenv
Saving Environment to FAT... OK
=> setenv mmcdev 0
=> setenv bootpart 0
=> saveenv
Saving Environment to FAT... OK
=> mmc partPartition Map for MMC device 0 -- Partition Type: EFIGUID Partition Table Header signature is wrong: 0x32472641DEEE9E91 != 0x5452415020494645
find_valid_gpt: *** ERROR: Invalid GPT ***
GUID Partition Table Header signature is wrong: 0x0 != 0x5452415020494645
find_valid_gpt: *** ERROR: Invalid Backup GPT ***=> boot
switch to partitions #0, OK
mmc0(part 0) is current device
SD/MMC found on device 0
** Unrecognized filesystem type **
** Unrecognized filesystem type **
** Unrecognized filesystem type **
** Unrecognized filesystem type **
libfdt fdt_check_header(): FDT_ERR_BADMAGIC
No FDT memory address configured. Please configure
the FDT address via "fdt addr <address>" command.
Aborting!
Bad Linux ARM64 Image magic!
相关文章:
bootloaders
什么是BootLoader? 一般来说,bootloader是一种软件/固件,它在SoC上电后立即运行。bootloader的主要职责是启动软件的后续部分,例如操作系统、baremetal应用程序或在某些情况下另一个bootloader。当涉及到嵌入式时,bootloader通常…...

PC或服务器装双系统
1. 准备工作 1.1U盘启动盘的制作 ①准备一个 4G 以上的 U 盘,备份好U盘资料,后面会对 U 盘进行格式化。 ②去CentOS官网下载你想要安装的 ISO 格式镜像文件,现在通常是CentOS6、7或者8。如果你英文不太好,可以选择使用edge浏览…...

嵌入式代码查看分析利器---Understand
平时在开发嵌入式程序的时候大多数使用的都是keil软件,一般小的工程使用keil没感觉到有什么问题,但是当工程比较大的时候,比如移植了FreeRTOS系统或者LWIP网络系统时,代码全部编译一次就要花费很长世间,特别是开启了点…...

人群计数经典方法Density Map Estimation,密度图估计
(3)Density Map Estimation(主流) 这是crowd counting的主流方法 传统方法不好在哪里?object detection-based method和regression-based method无法从图像中提取更抽象的有助于完成人群计数任务的语义特征 概况&…...
【华为】Smart-Link基础知识
Smark-Link技术 Smark-Link(灵活链路or备份链路,华为/华三 私有用) Smark-Link定义 Smark-Link,又叫备份链路。一个Smark Link由两个接口组组成,其中一个接口作为另一个的备份。Smark-Link常用于双上行组网,提供可靠高效的备份与…...

分享24个强大的HTML属性 —— 建议每位前端工程师都应该掌握
前期回顾 是不是在为 API 烦恼 ?好用免费的api接口大全呼之欲出_0.活在风浪里的博客-CSDN博客APi、常用框架、UI、文档—— 整理合并https://blog.csdn.net/m0_57904695/article/details/130459417?spm1001.2014.3001.5501 👍 本文专栏:…...

NIO基础 - 网络编程
non-blocking io 非阻塞 IO 1. 三大组件 1.1 Channel & Buffer channel 有一点类似于 stream,它就是读写数据的双向通道,可以从 channel 将数据读入 buffer,也可以将 buffer 的数据写入 channel,而之前的 stream 要么是输入…...
06.toRef 和 toRefs
学习要点: 1.toRef 和 toRefs 本节课我们来要了解一下 Vue3.x 中的 ref 两个周边 API 的用法; 一.toRef 和 toRefs 1. toRef 可以将源响应式对象上的 property 创建一个 ref 对象; const obj reactive({ name : Mr.Lee, age : 10…...

RabbitMq、Kafka、RocketMq整理
MQ的主要作用:异步提高性能、解耦提高扩展性、削峰。 一、常见中间件对比 Kafka、RocketMq和RabbitMq最大的区别就是:前两个是分布式存储。 1.1、ActiveMq 优点:1)完全支持jms规范的消息中间件 ,2)提供丰富的api, 3)多种集群构建模式。 缺点:)在高并发的场景下,性能可…...

Python多元线性回归预测模型实验完整版
多元线性回归预测模型 实验目的 通过多元线性回归预测模型,掌握预测模型的建立和应用方法,了解线性回归模型的基本原理 实验内容 多元线性回归预测模型 实验步骤和过程 (1)第一步:学习多元线性回归预测模型相关知识。 一元线性回归模型…...
C#基础 变量在内存中的存储空间
变量存储空间(内存中) // 1byte 8bit // 1KB 1024byte // 1MB 1024KB // 1GB 1024MB // 1TB 1024GB // 通过sizeof方法 可以获取变量类型所占的内存空间(单位:字节) 有…...

你最关心的4个零代码问题,ChatGPT 帮你解答了!
作为人工智能(AI)新型聊天机器人模型 ChatGPT,刚上线5天就突破100万用户,两个多月全球用户量破亿,不愧为业界最炙热的当红炸子鸡。 ChatGPT 是一种语言生成模型,由 OpenAI 开发和训练。它是基于 Transform…...
linux的环境变量
目录 一、自定义变量和环境变量的区别 二、自定义变量 三、环境变量 四、查看所有变量(自定义变量、环境变量) 五、记录环境变量到相关的系统文件 (1)为什么要这样做? (2)环境变量相关系统…...

openQA----基于openSUSE部署openQA
【原文链接】openQA----基于openSUSE部署openQA (1)下载 openqa-bootstrap 脚本并执行 cd /opt/ curl -s https://raw.githubusercontent.com/os-autoinst/openQA/master/script/openqa-bootstrap | bash -x(2)配置apache proxy…...

正则表达式基础一
BRE(basic regular expression):匹配数据流中的文本字符 普通文本匹配 特殊字符 正则表达式存在一些特殊字符,如需当成普通文本来匹配,必须加上转义,即反斜杠\,如下所示 .*[]^${}?|() 指定出现位置的字符 ^ 指定行首…...
Java中的内存泄露、内存溢出与栈溢出
内存泄露、内存溢出与栈溢出 1、概述2、内存泄漏、内存溢出和栈溢出2.1、内存泄漏2.2、内存溢出2.3、栈溢出 2、总结 1、概述 大家好,我是欧阳方超。本次就Java中几个相似而又不同的概念做一下介绍。内存泄漏、内存溢出和栈溢出都是与内存相关的问题,但…...

时序预测 | Matlab实现SSA-GRU、GRU麻雀算法优化门控循环单元时间序列预测(含优化前后对比)
时序预测 | Matlab实现SSA-GRU、GRU麻雀算法优化门控循环单元时间序列预测(含优化前后对比) 目录 时序预测 | Matlab实现SSA-GRU、GRU麻雀算法优化门控循环单元时间序列预测(含优化前后对比)预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现SSA-GRU、GRU麻雀算法…...

Java+springboot开发的医院HIS信息管理系统实现,系统部署于云端,支持多租户SaaS模式
一、项目技术框架 前端:AngularNginx 后台:JavaSpring,SpringBoot,SpringMVC,SpringSecurity,MyBatisPlus,等 数据库:MySQL MyCat 缓存:RedisJ2Cache 消息队列&…...
【前端面经】Vue-Vue中的 $nextTick 有什么作用?
Vue.js 是一个流行的 JavaScript 框架,它提供了许多实用的功能,其中之一就是 $nextTick 方法。 在 Vue.js 中, $nextTick 方法可以确保我们在更新 DOM 之后再去执行某些操作,从而避免由于 DOM 更新而导致的问题。这个方法非常实用…...

基于STATCOM的风力发电机稳定性问题仿真分析(Simulink)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...

消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...

02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...