seo优化方案案例/seo教程 百度网盘

seo优化方案案例,seo教程 百度网盘,网站建设有云端吗,网站设计的目的为什么我们要解析环境变量bootcmd? 承接博文 https://blog.csdn.net/wenhao_ir/article/details/145902134 继续解析u-boot的环境变量bootcmd。 为什么要解析u-boot的这个环境变量bootcmd?因为如果u-boot在倒计时完后,首先执行的是就是下面这条命令&am…

为什么我们要解析环境变量bootcmd

承接博文 https://blog.csdn.net/wenhao_ir/article/details/145902134 继续解析u-boot的环境变量bootcmd

为什么要解析u-boot的这个环境变量bootcmd?因为如果u-boot在倒计时完后,首先执行的是就是下面这条命令:

run_command(env_get("bootcmd"), 0);

其中 env_get("bootcmd") 取出 bootcmd 环境变量的内容,并将其传递给 run_command() 执行。

所以我们有必要去解析环境变量bootcmd的内容。

打印出u-boot的环境变量的具体内容

说明:本文使用的u-boot是博文 https://blog.csdn.net/wenhao_ir/article/details/145662136 中经过我修改移植后的u-boot。在博文 https://blog.csdn.net/wenhao_ir/article/details/145662136 中有烧写方法和它的百度网盘下载地址。

u-boot运行后,可用下面的命令单独打印出变量 bootcmd 的内容:

printenv bootcmd

这里,由于各环境变量之间有依赖关系,所以需要用下面的命令完整打印出所有环境变量的内容:

printenv

在这里插入图片描述

baudrate=115200
board_name=EVK
board_rev=14X14
boot_fdt=try
bootcmd=run findfdt;run findtee;mmc dev ${mmcdev};mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else run netboot; fi
bootcmd_mfg=run mfgtool_args;if iminfo ${initrd_addr}; then if test ${tee} = yes; then bootm ${tee_addr} ${initrd_addr} ${fdt_addr}; else bootz ${loadaddr} ${initrd_addr} ${fdt_addr}; fi; else echo "Run fastboot ..."; fastboot 0; fi;
bootdelay=3
bootscript=echo Running bootscript from mmc ...; source
console=ttymxc0
emmc_ack=1
emmc_dev=1
eth1addr=00:01:3f:2d:3e:4d
ethact=ethernet@20b4000
ethprime=eth1
fastboot_dev=mmc1
fdt_addr=0x83000000
fdt_file=undefined
fdt_high=0xffffffff
fdtcontroladdr=9df6d770
findfdt=if test $fdt_file = undefined; then if test $board_name = ULZ-EVK && test $board_rev = 14X14; then setenv fdt_file imx6ulz-14x14-evk.dtb; fi; if test $board_name = EVK && test $board_rev = 9X9; then setenv fdt_file imx6ull-9x9-evk.dtb; fi; if test $board_name = EVK && test $board_rev = 14X14; then setenv fdt_file imx6ull-14x14-evk.dtb; fi; if test $fdt_file = undefined; then echo WARNING: Could not determine dtb to use; fi; fi;
findtee=if test $tee_file = undefined; then if test $board_name = ULZ-EVK && test $board_rev = 14X14; then setenv tee_file uTee-6ulzevk; fi; if test $board_name = EVK && test $board_rev = 9X9; then setenv tee_file uTee-6ullevk; fi; if test $board_name = EVK && test $board_rev = 14X14; then setenv tee_file uTee-6ullevk; fi; if test $tee_file = undefined; then echo WARNING: Could not determine tee to use; fi; fi;
image=zImage
initrd_addr=0x86800000
initrd_high=0xffffffff
ip_dyn=yes
kboot=bootz 
loadaddr=0x80800000
loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}
loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
loadtee=fatload mmc ${mmcdev}:${mmcpart} ${tee_addr} ${tee_file}
mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc clk_ignore_unused 
mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}
mmcautodetect=yes
mmcboot=echo Booting from mmc ...; run mmcargs; if test ${tee} = yes; then run loadfdt; run loadtee; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi; fi;
mmcdev=1
mmcpart=1
mmcroot=/dev/mmcblk1p2 rootwait rw
netargs=setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp
netboot=echo Booting from net ...; ${usb_net_cmd}; run netargs; if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; ${get_cmd} ${image}; if test ${tee} = yes; then ${get_cmd} ${tee_addr} ${tee_file}; ${get_cmd} ${fdt_addr} ${fdt_file}; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_file}; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi; fi;
script=boot.scr
sd_dev=1
serial#=2e1181d769237caa
splashimage=0x8c000000
tee=no
tee_addr=0x84000000
tee_file=undefinedEnvironment size: 3388/8188 bytes

从中可见环境变量bootcmd的具体内容为:

bootcmd=run findfdt;run findtee;mmc dev ${mmcdev};mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else run netboot; fi

接下来我们需要对环境变量bootcmd中的语句进行分析,并理出我们这里的执行流程。

对环境变量bootcmd的内容进行分行和缩进处理

环境变量 bootcmd 的内容如下:

bootcmd=run findfdt;run findtee;mmc dev ${mmcdev};mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else run netboot; fi

全写在一行中,对我们阅读很不友好,不妨先利用chatgpt将其进行分行和缩进处理,分行和缩进处理后如下:

bootcmd=run findfdt;run findtee;mmc dev ${mmcdev};mmc dev ${mmcdev};  # 重复执行了一次,可能是为了确保正确切换到目标 mmc 设备if mmc rescan; thenif run loadbootscript; thenrun bootscript;elseif run loadimage; thenrun mmcboot;elserun netboot;fi;fi;elserun netboot;fi;

对环境变量bootcmd的每一条语句的解析

所有环境变量及环境变量bootcmd的内容在上面的内容中已经给出,在开始分析环境变量bootcmd中的各语句的意义,当知道其每条语句的意义后,也就知道了其执行流程了。

环境变量 bootcmd 的内容如下:

bootcmd=run findfdt;run findtee;mmc dev ${mmcdev};mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else run netboot; fi

分行和缩进处理后如下:

bootcmd=run findfdt;run findtee;mmc dev ${mmcdev};mmc dev ${mmcdev};  # 重复执行了一次,可能是为了确保正确切换到目标 mmc 设备if mmc rescan; thenif run loadbootscript; thenrun bootscript;elseif run loadimage; thenrun mmcboot;elserun netboot;fi;fi;elserun netboot;fi;

以下是对 bootcmd 中每一句语句的解析:

分析前,先了解下这个 bootcmd 主要完成的任务,如下:

  1. 查找设备树(FDT)文件
  2. 查找 TEE(可信执行环境)文件
  3. 选择 eMMC/SD 设备
  4. 尝试从 MMC 设备加载 U-Boot 启动脚本 boot.scr
  5. 如果 boot.scr 不存在,则尝试直接加载 Linux 内核
  6. 如果 MMC 启动失败,则回退到网络启动

1. 运行 findfdt 以确定设备树(DTB)文件的名字

run findfdt;
  • findfdt 变量的内容:
    findfdt=if test $fdt_file = undefined; then \if test $board_name = ULZ-EVK && test $board_rev = 14X14; then \setenv fdt_file imx6ulz-14x14-evk.dtb; \fi; \if test $board_name = EVK && test $board_rev = 9X9; then \setenv fdt_file imx6ull-9x9-evk.dtb; \fi; \if test $board_name = EVK && test $board_rev = 14X14; then \setenv fdt_file imx6ull-14x14-evk.dtb; \fi; \if test $fdt_file = undefined; then \echo WARNING: Could not determine dtb to use; \fi; \
    fi;
    
  • 作用:根据 board_nameboard_rev 确定要使用的设备树文件,并存储到 fdt_file 变量中。
  • 具体在这里,由于环境变量 board_name 的值为board_name=EVK,环境变量board_rev的值为14X14,所以环境变量fdt_file的值被设为imx6ull-14x14-evk.dtb,即内核的设备树文件的名字为imx6ull-14x14-evk.dtb

2. 运行 findtee 以确定 TEE 镜像的文件名

关于TEE 镜像是什么东西,请参考我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/146054128

run findtee;
  • findtee 变量的内容:
    findtee=if test $tee_file = undefined; then \if test $board_name = ULZ-EVK && test $board_rev = 14X14; then \setenv tee_file uTee-6ulzevk; \fi; \if test $board_name = EVK && test $board_rev = 9X9; then \setenv tee_file uTee-6ullevk; \fi; \if test $board_name = EVK && test $board_rev = 14X14; then \setenv tee_file uTee-6ullevk; \fi; \if test $tee_file = undefined; then \echo WARNING: Could not determine tee to use; \fi; \
    fi;
    
  • 作用:根据 board_nameboard_rev 确定 TEE 镜像文件(如 OP-TEE),并存储到 tee_file 变量中。
  • 具体在这里,由于环境变量 board_name 的值为board_name=EVK,环境变量board_rev的值为14X14,所以环境变量tee_file的值被设为uTee-6ullevk

3. 选择 eMMC 设备

mmc dev ${mmcdev};
mmc dev ${mmcdev};
  • mmcdev=1,表示默认使用 mmc1(可能是 eMMC)。可以用命令mmc list查看eMMC设备在u-boot中的编号,详情见我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/146016551 【搜索“利用MMC子系统查看和修改”】
  • 这里调用 mmc dev 两次,可能是为了确保设备切换正确。
  • 关于这个命令的详情,见我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/146016551

4. 重新扫描 MMC 设备

if mmc rescan; then
  • 作用:检查 eMMC/SD 设备是否可用,并更新分区信息。
  • 如果成功(即 MMC 设备存在),则继续执行下面的加载步骤。
  • 如果失败(即 MMC 设备不可用),则跳过直接进入 netboot

5. 尝试加载 U-Boot 启动脚本(boot.scr)

在这里插入图片描述

if run loadbootscript; then run bootscript;
  • loadbootscript 变量的内容:
    loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};
    
    • 尝试从 MMC 设备 加载 boot.scr 文件loadaddr(0x80800000)。
    • 在这里,由于mmcdev的值为1mmcpart的值为1loadaddr的值为0x80800000script的内容为boot.scr,所以这里实际上尝试把存储在eMMC的boot1(Boot partition 1)中的文件boot.scr加载到内存的0x80800000位置。同时由于命令是fatload,所以boot1(Boot partition 1)中的文件系统的格式为FAT。如果加载成功,再执行环境变量 bootscript 中的内容。
  • bootscript 变量的内容如下:
    bootscript=echo Running bootscript from mmc ...; source
    
    • echo Running bootscript from mmc ...; :这部分只是打印信息,告诉用户 “正在从 MMC 运行 bootscript…”。
    • source :这个命令的作用是 执行存储在 RAM 中的 boot.scr 脚本。u-boot的source 命令会解析 loadaddr 处的 boot.scr 并执行其中的 U-Boot 命令。
    • boot.scr 是一个预编译的 U-Boot 脚本,里面可能会定义更详细的启动过程,如:加载内核、加载设备树、设定 bootargs、执行 bootzbootm等。
  • 具体在这里,由于我们并不会向boot1(Boot partition 1)中写入文件boot.scr,即文件boot.scr并不存在,所以并不会执行这个分支。

6. 如果 boot.scr 不存在,则直接加载 Linux 内核

在这里插入图片描述

else if run loadimage; then run mmcboot;

加载内核镜像zImage到内存

  • loadimage 变量的内容:
    loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}
    
    • 尝试从 MMC 设备加载 zImageloadaddr(0x80800000)。
    • 在这里,由于mmcdev的值为1mmcpart的值为1loadaddr的值为0x80800000image的内容为zImage,所以这里实际上尝试把存储在eMMC的boot1(Boot partition 1)中的内核镜像文件zImage加载到内存的0x80800000位置。同时由于命令是fatload,所以boot1(Boot partition 1)中的文件系统的格式为FAT。如果加载成功,再执行环境变量 mmcboot 中的内容。
  • mmcboot 变量的内容:
    mmcboot=echo Booting from mmc ...; run mmcargs; \if test ${tee} = yes; then \run loadfdt; run loadtee; \bootm ${tee_addr} - ${fdt_addr}; \else \if test ${boot_fdt} = yes || test ${boot_fdt} = try; then \if run loadfdt; then \bootz ${loadaddr} - ${fdt_addr}; \else \if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; \fi; \else \bootz; \fi; \fi;
    

首先打印输出信息Booting from mmc ...

传递给内核的环境变量bootargs的设置(根文件系统的挂载)

然后执行环境变量mmcargs中的内容,环境变量mmcargs的内容为:

mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}

可见在这里设置了u-boot传递给内核的环境变量bootargs的值:
console的值为ttymxc0,所以内核启动后选择的当前终端为设备节点名为ttymxc0的终端,这实际上就是IMX6ULL的串口形成的终端。又由于baudrate的值为115200,所以这个终端所使用的串口的波特率被设置为115200
mmcroot的值为mmcroot=/dev/mmcblk1p2 rootwait rw,它的作用是指定 根文件系统(rootfs)的位置和挂载选项,具体解释如下:

字段解析

参数作用
/dev/mmcblk1p2指定根文件系统所在的 设备节点,即 mmcblk1(eMMC/SD 设备 1)的 第 2 分区(用户数据区的逻辑分区的第2个分区)
rootwait等待根文件系统设备准备好,用于 eMMC/SD 设备启动时可能的延迟问题。
rw以读写模式(read-write)挂载根文件系统
  1. /dev/mmcblk1p2(根文件系统路径)
    • /dev/mmcblk1p2 代表 eMMC 或 SD 设备 mmcblk1用户数据区的逻辑分区的第2个分区p2)。
    • 设备名称:
      • mmcblk0 → 这是Linux系统启动后第一个 eMMC/SD 设备的名字。
      • mmcblk1 → 这是Linux系统启动后第二个 eMMC/SD 设备的名字。
    • 分区编号:
      • mmcblk1p1 →用户数据区的逻辑分区的第1个分区,注意不是eMMC设备的Boot partition 1分区。
      • mmcblk1p2 → 用户数据区的逻辑分区的第2个分区,注意不是eMMC设备的Boot partition 2分区。
      • mmcblk1boot0-eMMC设备的Boot partition 1分区。
      • mmcblk1boot1-eMMC设备的Boot partition 2分区。

关于上面这些设备名称和分区编号名是如何获取的,即eMMC各分区在Linux内核中的名字,请参看我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145967306 【搜索“可以使用以下命令查看eMMC的分区信息”】

  1. rootwait(等待设备就绪)

    • eMMC/SD 设备在 U-Boot 交权给 Linux 内核后,可能需要时间初始化
    • rootwait 让内核 无限等待根文件系统设备出现(而不是直接报错)。
  2. rw(读写挂载根文件系统)

    • rw 让 Linux 以读写模式 挂载根文件系统
    • 如果使用 ro(read-only),根文件系统会以只读模式挂载,适用于只读系统(如某些嵌入式设备)。
  3. 注:默认情况下,Linux启动后init 进程可能会重新挂载根文件系统,原因见博文 https://blog.csdn.net/wenhao_ir/article/details/146067376

传递给内核的环境变量bootargs设置完后,即run mmcargs执行完后,再执行后面的代码加载设备树文件。

设置

  mmcboot=echo Booting from mmc ...; run mmcargs; \if test ${tee} = yes; then \run loadfdt; run loadtee; \bootm ${tee_addr} - ${fdt_addr}; \else \if test ${boot_fdt} = yes || test ${boot_fdt} = try; then \if run loadfdt; then \bootz ${loadaddr} - ${fdt_addr}; \else \if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; \fi; \else \bootz; \fi; \fi;
  • 如果 tee=yes,则先加载 TEE 并使用 bootm 命令引导。由于这里tee的值为no,所以不会执行这个分支,所以本博文中不去仔细分析这个分支。
  • 读下面的内容前,前先阅读博文 https://blog.csdn.net/wenhao_ir/article/details/146068588 了解命令 bootz的详细情况。
  • 否则,尝试加载设备树(DTB)并使用命令 bootz 启动。
  • 如果 DTB 加载失败(但 boot_fdt=try),则直接 bootz 继续引导内核。注意:命令 bootz不加参数时,默认从环境变量loadaddr中去获取内核在内存中的地址。
  • 如果boot_fdt的值既不为yes也不为try,则不加载设备树,直接用命令 bootz 启动内核。注意:命令 bootz不加参数时,默认从环境变量loadaddr中去获取内核在内存中的地址。

具体到这里来说,由于boot_fdt的值为try,所以执行下面红框中的分支:
在这里插入图片描述
语句run loadfdt;表示加载设备树文件到内存中,环境变量loadfdt的内容如下:

loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}

在这里,由于mmcdev的值为1mmcpart的值为1fdt_addrr的值为0x83000000fdt_file的内容之前已经通过运行命令run findfdt设置为了imx6ull-14x14-evk.dtb,所以这里实际上尝试把存储在eMMC的boot1(Boot partition 1)中的设备树文件imx6ull-14x14-evk.dtb加载到内存的为0x83000000的位置。同时由于命令是fatload,所以boot1(Boot partition 1)中的文件系统的格式为FAT。

这里:我们可以顺便算下内核镜像和设备树文件在内存中相隔多远:
0x83000000-0x80800000=0x2800000=Dec2800000B=2800000KB=40MB,即二者在内存中相隔了40MB。

如果设置树文件加载成功,再执行下面这条命令:

bootz ${loadaddr} - ${fdt_addr};

关于bootz命令的详解,见博文 https://blog.csdn.net/wenhao_ir/article/details/146068588

这样 bootz 会按下面的参数启动Linux内核:

  1. 从内存的 loadaddr(0x80800000) 位置加载 zImage
  2. - 表示 不使用bootz命令的第2个参数 ramdisk
  3. 从内存的 fdt_addr(0x83000000) 加载内核需要的设备树(DTB)文件。

7. 如果 MMC 设备启动失败,则进行网络启动

else run netboot;
fi; fi; else run netboot; fi
  • netboot 变量的内容:
    netboot=echo Booting from net ...; ${usb_net_cmd}; run netargs; \if test ${ip_dyn} = yes; then \setenv get_cmd dhcp; \else \setenv get_cmd tftp; \fi; \${get_cmd} ${image}; \if test ${tee} = yes; then \${get_cmd} ${tee_addr} ${tee_file}; \${get_cmd} ${fdt_addr} ${fdt_file}; \bootm ${tee_addr} - ${fdt_addr}; \else \if test ${boot_fdt} = yes || test ${boot_fdt} = try; then \if ${get_cmd} ${fdt_addr} ${fdt_file}; then \bootz ${loadaddr} - ${fdt_addr}; \else \if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; \fi; \else \bootz; \fi; \fi;
    
  • 尝试从网络(TFTP/NFS)加载内核和设备树,并执行启动。
  • 关于上面这些从网络启动的命令的详细解释,见我的另一篇博文 https://blog.csdn.net/wenhao_ir/article/details/145902134

8.小结

  • 优先使用 MMC 启动
  • 如果 boot.scr 存在,则执行 boot.scr
  • 如果 boot.scr 不存在,则直接加载 zImage 并启动
  • 如果 MMC 启动失败,则使用网络启动

对我们有重要作用的信息汇总

关于内核镜像文件的说明

①内核镜像文件存储在eMMC的boot1(Boot partition 1)中,其文件名为zImage,加载到内存中的位置为:0x80800000位置,要求boot1(Boot partition 1)的文件系统为FAT。

关于设备树文件的说明

②设置树文件存储在eMMC的boot1(Boot partition 1)中,其文件名为imx6ull-14x14-evk.dtb,加载到内存中的位置为:0x83000000位置,要求boot1(Boot partition 1)的文件系统为FAT。

关于根文件系统挂载的说明

③根文件系统的挂载位置在设备节点/dev/mmcblk1p2,mmcblk1p2 的1代表eMMC设备的编号为1,p2代表用户数据区的第2个逻辑分区。由于根文件系统的挂载是在内核启动后进行的,所以挂载位置的设备节点的名字是Linux系统中的名字。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/71471.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NSSCTF [SWPUCTF 2024 秋季新生赛]金丝雀

5948.[SWPUCTF 2024 秋季新生赛]金丝雀 canary绕过和64位的ret2libc(格式化字符串泄露) (1) motalymotaly-VMware-Virtual-Platform:~/桌面$ file xn xn: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.…

koa-session设置Cookie后获取不到

在谷歌浏览器中请求获取不到cookie问题之一(谷歌安全策略) 场景 前端使用 axios 请求,项目地址:http://192.168.8.1:5173 import axios from axiosconst request axios.create({baseURL: http://127.0.0.1:3001/,timeout: 60000,…

FusionInsight MRS云原生数据湖

FusionInsight MRS云原生数据湖 1、FusionInsight MRS概述2、FusionInsight MRS解决方案3、FusionInsight MRS优势4、FusionInsight MRS功能 1、FusionInsight MRS概述 1.1、数据湖概述 数据湖是一个集中式存储库,允许以任意规模存储所有结构化和非结构化数据。可以…

推荐几款优秀的PDF转电子画册的软件

当然可以!以下是几款优秀的PDF转电子画册的软件推荐,内容简洁易懂,这些软件都具有易用性和互动性,适合不同需求的用户使用。​ ❶ FLBOOK|在线创作平台 支持PDF直接导入生成仿真翻页电子书。提供15主题模板与字体库&a…

【GoTeams】-2:项目基础搭建(下)

本文目录 1. 回顾2. Zap日志3. 配置4. 引入gprc梳理gRPC思路优雅关闭gRPC 1. 回顾 上篇文章我们进行了路由搭建,引入了redis,现在来看看对应的效果。 首先先把前端跑起来,然后点击注册获取验证码。 再看看控制台输出和redis是否已经有记录&…

深度学习反向传播

一、白话解释 梯度其实就是导数,除了用符号求导也可以用近似求导: 然后更新ww-学习率*导数 反向传播就是链式求导 向前计算:对每个节点求偏导 在前向传播的时候,进行一次前向计算的时候就可以把每一条线的偏导数都知道 前向传…

JavaWeb-HttpServletRequest请求域接口

文章目录 HttpServletRequest请求域接口HttpServletRequest请求域接口简介关于请求域和应用域的区别 请求域接口中的相关方法获取前端请求参数(getParameter系列方法)存储请求域名参数(Attribute系列方法)获取客户端的相关地址信息获取项目的根路径 关于转发和重定向的细致剖析…

deepseek在pycharm 中的配置和简单应用

对于最常用的调试python脚本开发环境pycharm,如何接入deepseek是我们窥探ai代码编写的第一步,熟悉起来总没坏处。 1、官网安装pycharm社区版(免费),如果需要安装专业版,需要另外找破解码。 2、安装Ollama…

动态规划01背包问题系列一>最后一块石头的重量II

这里写目录标题 题目分析:状态表示:状态转移方程:初始化:填表顺序:返回值:代码呈现:优化版本:代码呈现: 题目分析: 状态表示: 状态转移方程&#…

逐行拆解 C 语言:数据类型、变量

今日,我们即将踏上一段充满趣味与挑战的学习之旅,深度钻研数据类型的多样奥秘,解锁变量创建的实用技巧。不仅如此,还会邂逅两个实用的基础库函数,探索它们在程序中穿针引线的奇妙作用。同时,几个简洁却强大…

【音视频】ffplay简单过滤器

一、ffplay简单过滤器 视频旋转:借助transpose滤镜 ffplay -i 1.mp4 -vf transpose1这里选择不同的数字是不同的方向: 视频翻转:借助hflip/vflip实现水平和垂直翻转: 水平翻转 ffplay 1.mp4 -vf hflip垂直翻转 ffplay 1.mp4 …

4G工业路由器在公交充电桩中的应用与优势

随着电动公交车的普及,公交充电桩的稳定运行和高效管理是交通营运部门最关心的问题。4G工业路由器凭借其卓越的数据采集和通讯能力,成为实现充电桩智能化管理的关键。 公交充电桩运维管理需求概述: 1.实时性:实时监控充电状态、剩…

【LangChain 数据连接封装】 文档加载器、文档处理器

小结: 文档处理部分,建议在实际应用中详细测试后使用与向量数据库的链接部分本质是接口封装,向量数据库需要自己选型类似 LlamaIndex,LangChain 也提供了丰富的 Document Loaders DocumentLoaders和 Text Splitters Text Splitte…

Springboot集成dubbo完整过程(三)

准备工作 1,准备mysql服务环境2,准备redis服务环境3,准备zookeeper服务环境4,准备逆向生成bean的xml配置文件5,准备slf4j日志xml配置文件6,准备一个sql脚本 1,搭建创建服务工程 1,创…

电池管理系统(BMS)架构详细解析:原理与器件选型指南

BMS(电池管理系统)架构详细讲解 从你提供的BMS(Battery Management System)架构图来看,主要涉及到电池监控模块、通信模块、功率控制模块等部分。下面我将详细讲解该架构的各个功能模块及其工作原理。 1. 电池管理核…

决策树(Decision Tree)基础知识

目录 一、回忆1、*机器学习的三要素:1)*函数族2)*目标函数2.1)*模型的其他复杂度参数 3)*优化算法 2、*前处理/后处理1)前处理:特征工程2)后处理:模型选择和模型评估 3、…

Git 批量合并 Commit 并且保留之前的 Commit 快速实现的思路

文章目录 需求Rebase / Pick / squashVim 的快速全局字符串替换 需求 我想把如下的提交 commit,变成一个 Commit,并且合并这些 Commit 的消息到一个节点 Rebase / Pick / squash 我合并到 5e59217 这个hash 上,这样合并后会保留两个 Commit…

基于海思soc的智能产品开发(芯片sdk和linux开发关系)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 随着国产化芯片的推进,在soc领域,越来越多的项目使用国产soc芯片。这些soc芯片,通常来说运行的os不是linux&…

论坛系统测试报告

目录 一、项目背景二、论坛系统测试用例思维导图三、论坛系统测试3.1界面测试3.2登陆测试3.3主页测试3.4个人中心测试 四、自动化测试脚本4.1配置驱动4.2创建浏览器类4.3功能测试4.3.1登陆测试4.3.2注册测试4.3.3主页测试4.3.4帖子编辑4.3.5运行主代码 五、BUG分析六、测试总结…

python量化交易——金融数据管理最佳实践——使用qteasy大批量自动拉取金融数据

文章目录 使用数据获取渠道自动填充数据QTEASY数据拉取功能数据拉取接口refill_data_source()数据拉取API的功能特性多渠道拉取数据实现下载流量控制实现错误重试日志记录其他功能 qteasy是一个功能全面且易用的量化交易策略框架, Github地址在这里。使用它&#x…