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…...

如何写出高质量的代码
背景说明: 你是否曾经为自己写的代码而感到懊恼?你是否想过如何才能写出高质量代码?那就不要错过这个话题!在这里,我们可以讨论什么是高质量代码,如何写出高质量代码等问题。无论你是初学者还是资深开发人…...

15.基于主从博弈的智能小区代理商定价策略及电动汽车充电管理
说明书 MATLAB代码:基于主从博弈的智能小区代理商定价策略及电动汽车充电管理 关键词:电动汽车 主从博弈 动态定价 智能小区 充放电优化 参考文档:《基于主从博弈的智能小区代理商定价策略及电动汽车充电管理》基本复现 仿真平台&#…...

ChatGPT实现多语种翻译
语言翻译 多语种翻译是 NLP 领域的经典话题,也是过去很多 AI 研究的热门领域。一般来说,我们认为主流语种的互译一定程度上属于传统 AI 已经能较好完成的任务。比如谷歌翻译所采用的的神经机器翻译(NMT, Neural Machine Translation)技术就一度让世人惊…...

volatile关键字原理的使用介绍和底层原理解析和使用实例
文章目录 volatile关键字原理的使用介绍和底层原理解析和使用实例1. volatile 关键字的作用2. volatile 的底层原理3. volatile 的使用案例4. volatile 的原子性问题5. 如何解决 volatile 的原子性问题6. volatile 的实现原理7. 小结8. volatile的最佳实践9. 案例:使用volatile…...

【软件下载】换新电脑记录下下载的软件时所需地址
1.idea https://www.jetbrains.com/zh-cn/idea/download/other.html 2.oracle官方(下载jdk时找的) https://www.oracle.com/ 3.jdk8 https://www.oracle.com/java/technologies/downloads/ 下拉找到jdk8 切换windows (需要注册个oracle账…...

【10.HTML入门知识-CSS元素定位】
1 标准流(Normal Flow) 默认情况下,元素都是按照normal flow(标准流、常规流、正常流、文档流【document flow】)进行排布 从左到右、从上到下按顺序摆放好 默认情况下,互相之间不存在层叠现象 1.1…...

LeetCode_贪心算法_简单_455.分发饼干
目录 1.题目2.思路3.代码实现(Java) 1.题目 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的…...

HashMap
目录 HashMap是什么? 为什么要使用HashMap? HashMap存储元素原理(put⽅法) 扰动函数 前置知识 异或运算 &运算 为什么使用扰动函数 实验验证扰动函数 常见问题 HashMap的默认长度是多少? HashMap是先扩…...

数据结构初阶 —— 树(堆)
目录 一,堆 堆的概念 向下调整法(数组) 向上调整法(数组) 堆的创建(建堆) 堆的实现 一,堆 堆的概念 如有个关键码的集合K{,,,...…...

一文看懂低代码,5分钟从入门到原理全搞定
全球低代码市场已经走过了近20年,中国低代码市场近5年经历了百花齐放的广泛探索阶段,更旺盛的市场需求逐步在被激发。现在,让我们按下暂停键,看看这些产品给我们呈现了低代码市场一幅怎样的百景图。 低代码平台简介 广义上的低代…...