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

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

day36-多路IO复用
一、基本概念 (服务器多客户端模型) 定义:单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用:应用程序通常需要处理来自多条事件流中的事件,比如我现在用的电脑,需要同时处理键盘鼠标…...

Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...