arm系统移植

目录

    • 1. 流程
    • 2. 概念
      • 2.1 设备树
      • 2.2 根文件系统
      • 2.3 文件说明
    • 3. 交叉编译链
      • 3.1 作用
      • 3.2 在linux下配置
    • 4. tftp
      • 4.1 作用
      • 4.2 安装过程
    • 5. nfs
      • 5.1 作用
      • 5.2 安装过程
    • 6. 配置开发板
    • 7. linux下的uboot镜像烧写到SD卡中
      • 7.1 生成uboot二进制文件,二进制文件就是裸机程序。
      • 7.2 合成最终的uboot
      • 7.3 通过dd命令把u-boot-iTOP-4412.bin烧写到SD卡中
    • 8. 制作linux根文件系统
      • 8.1 busybox
      • 8.2 需要配置的软件环境
      • 8.3 配置busybox选项并编译
      • 8.4 制作根文件系统

1. 流程

在SD卡内烧写uboot,然后设置开发板,通过tftp把uimage和exynos.dtb下载到开发板,通过nfs挂载根文件系统。即可以在开发板上先启动uboot,然后在模拟linux环境。或者可以自由制作uboot和rootfs根文件系统。

2. 概念

2.1 设备树

Linux内核从3.x开始引入设备树的概念,用于实现驱动代码与设备信息相分离。在设备树出现以前,所有关于设备的具体信息都要写在驱动里,一旦外围设备变化,驱动代码就要重写。引入了设备树之后,驱动代码只负责处理驱动的逻辑,而关于设备的具体信息存放到设备树文件中,这样,如果只是硬件接口信息的变化而没有驱动逻辑的变化,驱动开发者只需要修改设备树文件信息,不需要改写驱动代码。比如在ARM Linux内,一个.dts(device tree source)文件对应一个ARM的machine,一般放置在内核的"arch/arm/boot/dts/“目录内,比如exynos4412参考板的板级设备树文件就是"arch/arm/boot/dts/exynos4412-origen.dts”。这个文件可以通过$make dtbs命令编译成二进制的.dtb文件供内核驱动使用。

2.2 根文件系统

根文件系统(root filesystem)是运行Linux系统所必须的各种工具软件、库文件、脚本、配置文件的一种特殊的文件目录结构。Linux内核要启动后要挂载一个文件系统才能运行。

2.3 文件说明

1.uImage : 编译好的Linux内核文件,它是专门给u-boot提供的,u-boot是用来引导linux的一个系统。

2.exynos4412-itop-elite.dtb:编译好的设备树文件,设备树中描述了硬件信息,如LED信息,网卡信息DM9606等等。

3.rootfs.tar.gz : 这是文件系统,Linux内核要运行必须挂载一个文件系统。

3. 交叉编译链

3.1 作用

ubuntu为x86环境,交叉编译链的作用是在x86的环境下模拟通过arm编译。

3.2 在linux下配置

  1. gcc-arm-8.3.tar.gz 放到 /opt目录下
sudo mv gcc-arm-8.3.tar.gz /opt
  1. 解压
sudo tar zxvf gcc-arm-8.3.tar.gz
  1. 解压后在 /opt 目录下会出现
    gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf
  2. 编辑环境变量加载文件
sudo vim /etc/profile#在文件尾部添加下面两行
export ARM_PATH=/opt/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin
export PATH=${PATH}:${ARM_PATH}
  1. 使 /etc/profile 生效: 在控制终端运行 source /etc/profile
  2. 测试交叉编译工具链有没有安装成功
在控制终端 输入 arm-linux-gnueabihf-gcc -v

7.若以上方法无法找到arm-linux-gnueabihf-gcc命令(可选)
vim ~/.bashrc .bashrc文件是在你的用户根目录下,即在/home/<用户名>目录下
在.bashrc末尾添加

export ARM_PATH=/opt/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin
export PATH=${PATH}:${ARM_PATH}

4. tftp

4.1 作用

(在这里的作用)把uimage和exynos.dtb下载到开发板

4.2 安装过程

1.安装tftp服务器及客户端

sudo apt-get install tftpd-hpa tftp-hpa

2.在 /home/[用户名]/路径下创建一个文件夹: tftpboot

mkdir ~/tftpboot

3.修改tftp的配置文件

sudo vi /etc/default/tftpd-hpaTFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/[用户名]/tftpboot"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-c -s -l"  

4.重启tftp服务器

sudo systemctl restart tftpd-hpa.service

5.启动成功
在这里插入图片描述
6.上传/下载文件测试
<1>上传文件到tftp服务器
在任意一个目录新建一个文件a.txt,并向其中写入任意内容,然后执行下面的命令

tftp 127.0.0.1
tftp> put a.txttftp配置文件 sudo vi /etc/default/tftpd-hpa 中的OPTIONS里要加上-c,才能新建文件
修改 /home/[用户名]/tftpboot  文件夹权限为777

<2>开发板测试tftp服务器功能
从开发板上传文件到tftp服务器目录 :

tftp 192.168.101.242 -p -l new_file.txt

从tftp服务器目录下载文件到开发板 :

tftp 192.168.101.242 -g -r a.txt

测试从tftp服务器下载文件:

tftp 127.0.0.1
tftp> get a.txt 

将uImage 和 exynos4412-itop-elite.dtb放在tftp服务器的配置目录下,如tftpboot目录下。

5. nfs

5.1 作用

在linux运行起来后,挂载根文件系统。linux内核在运行时支持通过网络挂载另一网络地址上的文件系统。将pc机上的目录共享给开发板使用,提高开发效率。

5.2 安装过程

1.在/home/[用户名]/目录下创建一个文件夹nfs,将根文件系统的压缩包rootfs.tar.gz拷贝至/home/[用户名]/nfs目录下,然后解压。解压后生成一个目录rootfs,然后修改rootfs权限。

mkdir ~/nfs
cp rootfs.tar.gz ~/nfs
cd nfs
tar -zxvf rootfs.tar.gz
chmod 777 rootfs

2.重新安装nfs服务器

sudo apt-get install nfs-kernel-server

3.配置NFS服务器

sudo vim /etc/exports在最末尾添加:
/home/[用户名]/nfs/rootfs *(rw,sync,no_subtree_check,no_root_squash)
选项可以参考 man 5 exports (/etc/exports注释中提示的)

4.重启NFS服务器

sudo service nfs-kernel-server restart 

5.查看状态

$ sudo systemctl status nfs-kernel-server.service

6.进行挂载测试

sudo mkdir /mnt/root_nfs 
sudo mount -t nfs localhost:/home/[用户名]/nfs/rootfs /mnt/root_nfs
ls -l /mnt/root_nfs 

7.卸载对rootfs的挂载(可选)

sudo umount /mnt/root_nfs

6. 配置开发板

1.设置开发板的IP地址,开发板通过USB转串口连接到电脑,通过SecureCRT打开串口,输入以下命令:

 setenv ipaddr 192.168.xx.xx

2.设置服务器的IP地址,就是虚拟机的地址

setenv serverip 192.168.xx.xx

3.设置网关ip

setenv gatewayip 192.168.101.1

4.设置网络掩码

setenv netmask 255.255.255.0

5.设置开发板启动linux启动的环境变量,设置从nfs挂载根文件系统

setenv bootargs root=/dev/nfs nfsroot=192.168.107.10:/home/[用户名]/nfs/rootfs,proto=tcp,nfsvers=3 rw console=ttySAC2,115200n8 init=/linuxrc ip=192.168.107.100:192.168.107.10:192.168.107.1:255.255.255.0::eth0:o
//bootargs 中的ip参数解释
//bootargs参数由linux内核运行到最后挂载根文件系统时使用
root=/dev/nfs	//使用的网络文件系统
nfsroot=192.168.x.x   //为虚拟机服务器的ip
nfsroot=192.168.107.10:/home/wyl/nfs/rootfs	//其中/home/wyl/nfs/rootfs 是Ubuntu上rootfs的真实路径
ip=192.168.x.x:192.168.x.x:192.168.x.1 //第一个ip为开发的ip,第二个是虚拟机的ip, 第三个是网关

6.下载kernel到内存

tftpboot 40008000 uImage
tftpboot 42000000 exynos4412-itop-elite.dtb 

7.手动启动

bootm 40008000 - 42000000 

8.如果上面的测试通过的话,可以把2,3中的命令写到bootcmd环境变量中,以后重启就是自动执行

setenv bootcmd tftpboot 40008000 uImage\;tftpboot 42000000 exynos4412-itop-elite.dtb\;bootm 40008000 - 42000000
1. 切换到 u-boot 运行环境下,设置以下环境变量
setenv bootcmd tftpboot 40008000 uImage\;tftpboot 42000000 exynos4412-itop-elite.dtb\;bootm 40008000 - 42000000
再用 saveenv 命令保存u-boot下的环境变量,重启开发板,u-boot倒计时结束 后会自动启动linux

9.保存

saveenv

10.若开发板挂载根文件系统太慢,则可以在Ubuntu上 用ping命令,去ping开发板的IP地址。

7. linux下的uboot镜像烧写到SD卡中

7.1 生成uboot二进制文件,二进制文件就是裸机程序。

运行 uboot源码目录(uboot_itop4412_2017.11.tar.gz 或 jason412_uboot-2017.11)mkboot子目录下的脚本程序 build.sh,在uboot/mkboot目录下输入 ./build.sh 进行 uboot源码的编译,编译完成后,会生成两个文件,一个是itop4412-spl.bin,一个是u-boot.bin。

uboot的源码目录是指:jason412_uboot-2017.11目录
itop4412-spl.bin是在 uboot/spl目录下
u-boot.bin是在 uboot目录下

脚本程序build.sh会将itop4412-spl.bin文件和u-boot.bin拷贝到 uboot/mkboot目录下。

7.2 合成最终的uboot

通过命令 cat E4412_N.bl1.bin itop4412-spl.bin env.bin u-boot.bin > u-boot-iTOP-4412.bin

E4412_N.bl1.bin:三星提供的二进制文件。
itop4412-spl.bin :u-boot编译生成的。
env.bin :保存的环境变量。
u-boot.bin:编译uboot生成的。

通过命令cat E4412_N.bl1.bin itop4412-spl.bin env.bin u-boot.bin > u-boot-iTOP-4412.bin把三个二进制文件合成为一个最终的 u-boot-iTOP-4412.bin

7.3 通过dd命令把u-boot-iTOP-4412.bin烧写到SD卡中

sudo dd iflag=dsync oflag=dsync if=u-boot-iTOP-4412.bin of=/dev/sdb seek=1

解析:
sudo是超级用户权限
dd 是linux 的命令;
dsync 读写数据采用同步IO;所谓同步就是写入或读取磁盘会花费时间,同步就是等待读/写结束,阻塞式等待。
iflag=dsync 使用iflag来控制读取数据时的行为特征。
oflag=dsync 使用oflag来控制写入数据时的行为特征。
if: 输入的文件
of:输出到哪个设备文件(磁盘文件),of=/dev/sdb 其中的 /dev/sdb就代表SD卡

因此意思是:使用超级用户权限把u-boot-iTOP-4412.bin写入到磁盘sdb上,跳过该设备的第一个块(block)(每个block的大小为512B)

块(block):举例说明,内存是以字节为单位来访问的,块设备,如磁盘(flash,SD卡,emmc)是按照块大小为单位来访问的。块的大小可以理解 为内存中的一个存储单元。

磁盘设备的第一个块,存储有磁盘的一些重要信息,一定不能用dd命令去写。

8. 制作linux根文件系统

8.1 busybox

BusyBox 是一个轻量级的开源工具箱,官网地址是:http://www.busybox.net/,其中包含了许多标准的 Unix 工具,例如 sh、ls、cp、sed、awk、grep 等,同时它也支持大多数关键的系统功能,例如自启动、进程管理、启动脚本等等。

8.2 需要配置的软件环境

  • 安装arm交叉编译工具链 8.3.0
  • 在ubuntu中安装libncurses5-dev sudo apt install libncurses5-dev

8.3 配置busybox选项并编译

  1. 解压buxybox压缩包
tar -jxvf busybox-1.36.1.tar.bz2 //解压buxybox压缩包
cd busybox-1.36.1 //会在当前目录下解压为一个文件夹,进入
  1. 配置编译选项
make menuconfig ARCH=arm //弹出图形化界面

一般配置三个选项:

a)编译器前缀
Settings ---->(arm-linux-gnueabihf-) Cross compiler prefix //添加交叉编译链arm-linux-gnueabihf-b)编译静态库
Settings ---->[*] Build static binary (no shared libs) c)安装目录
Settings ---->[*] ( ./_install) Destination path for 'make install'     //./install为rootfs安装的目录路径d)保存后退出
  1. 编译
make ARCH=arm CROSS_COMPILE=arm-linux-guneabihf-

在 busybox-1.36.1目录下会生成一个busybox可执行文件。运行file busybox,如下:
$ file busybox 确认编译生成的是 ARM 平台的(显示为ELF 32-bit LSB executable, ARM)

  1. 安装
make install
  1. 做了什么
    至此通过busybox编译安装了根文件目录_install,即rootfs,现在要做的是将根文件目录放到nfs下

8.4 制作根文件系统

  1. 进入busybox install后的安装目录并创建所需目录
cd _install
mkdir dev etc mnt  proc var tmp sys root lib
  1. 将工具链中的库拷贝到_install/lib 目录下
cd lib#从编译工具链中拷贝运行库到刚制作的根据文件系统的lib下
sudo cp -Parf /opt/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/arm-linux-gnueabihf/lib/*  ./
sudo cp -Parf /opt/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/*  ./
  1. 删除静态库和共享库(动态库)文件中的符号表以减小体积
#在 lib 目录下,删除掉静态库
rm *.a#裁剪掉调试信息 
arm-linux-gnueabihf-strip ./*
  1. 查看lib目录大小
du -mh lib/

应该是7.0MB的大小左右

  1. 添加系统启动文件
cp -rf ~/nfs/rootfs/etc .

拷入成熟的参考配置,将linux内核能成功挂载的rootfs目录下的etc文件夹拷贝到新制作的rootfs目录下面。
a) 在etc下添加文件inittab,文件内容如下:

#this is run first except when booting in single-user mode.
::sysinit:/etc/init.d/rcS
# /bin/sh invocations on selected ttys
# Start an "askfirst" shell on the console (whatever that may be)
::respawn:-/bin/sh
# Stuff to do when restarting the init process
::restart:/sbin/init
# Stuff to do before rebooting
::ctrlaltdel:/sbin/reboot 

b) 在etc目录下创建init.d子目录,并在etc/init.d目录下添加rcS文件:

#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
mount -a
echo /sbin/mdev>/proc/sys/kernel/hotplug
mdev -s
mount -o remount,rw /

c) 更改rcS的权限

chmod a+x _install/etc/init.d/rcS

d) 修改以可读可写方式挂载文件系统Readonly file system

vim  rootfs/etc/init.d/rcS

e) 在文件末尾添加以下内容

mount -o remount,rw /

f) 在etc下添加文件fstab,文件内容如下

#device     mount-point      type       options         dump     fsck order
proc	       /proc                proc       defaults             0               0
tmpfs        /tmp             tmpfs      defaults         0           0
sysfs          /sys              sysfs       defaults         0           0
tmpfs       /dev             tmpfs      defaults          0           0
  1. 支持挂载proc, sysfs, tmpfs文件的内核配置

这里我们挂载的文件系统有三个proc、sysfs和tmpfs。在内核中proc和sysfs默认都支持,而tmpfs是没有支持的,我们需要添加tmpfs的支持。
进入linux-4.14.12内核源码根目录,修改Linux内核配置并重新编译:

$ make menuconfig
File systems --->Pseudo filesystems --->[*] Tmpfs virtual memory file system support (former shm fs)[*] Tmpfs POSIX Access Control Lists

在Linux内核源码根目录下,重新编译内核

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- LOADADDR=0x40008000 uImage
  1. 在rootfs目录下的etc目录下添加profile文件,文件内容为
#!/bin/sh
export HOSTNAME=i4412
export USER=root
export HOME=root
export PS1="[$USER@$HOSTNAME \W]\# "
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH  LD_LIBRARY_PATH

重要:新制作的文件系统尺寸若超出8M,删除不需要的库文件
9. 创建设备文件

在根文件系统的根目录执行以下命令

#在根文件系统的dev目录一创建一个console设备文件
sudo mknod dev/console c 5 1#在根文件系统的dev目录一创建一个null设备文件
sudo mknod dev/null c 1 3
  1. 测试:看新的根文件系统能否正常挂载到开发板
#把原有的根文件系统备份一下
linux@linux:~/busybox-1.22.1  $ mv  ~/nfs/rootfs /nfs/rootfs.ok把新的根文件系统拷贝过去(改名rootfs)
linux@linux:~/busybox-1.22.1$ sudo cp -arf _install  ~/nfs/rootfs
  1. 挂载成功

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

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

相关文章

量子算法入门——5.Qiskit库介绍与简单应用(2)

参考资料&#xff1a; 【【零基础入门量子计算】】 来自b站up&#xff1a;溴锑锑跃迁 建议关注他的更多高质量文章&#xff1a;CSDN&#xff1a;【溴锑锑跃迁】 &#xff08;实际上只带一点点原创&#xff0c;绝大部分资料来自这位大佬&#xff09; 跟着视频我手打了一遍notebo…

前端如何优雅地实现一个“请求队列”,避免服务器被卡死?

有这样一些场景&#xff1a; 页面一加载&#xff0c;需要同时发 10 个请求&#xff0c;结果页面卡住&#xff0c;服务器也快崩了。用户可以批量操作&#xff0c;一次点击触发了几十个上传文件的请求&#xff0c;浏览器直接转圈圈。 当后端处理不过来时&#xff0c;前端一股脑…

SSL/TLS协议信息泄露漏洞(CVE-2016-2183)、SSL/TLS RC4 信息泄露漏洞(CVE-2013-2566)修复方法

目录 一、问题原因二、整改步骤 一、问题原因 通过绿盟漏洞检测工具扫描发现Windows系统存在SSL/TLS协议信息泄露漏洞(CVE-2016-2183)、SSL/TLS RC4 信息泄露漏洞(CVE-2013-2566)、SSL/TLS 受诫礼(BAR-MITZVAH)攻击漏洞(CVE-2015-2808)。 二、整改步骤 使用gpedit.msc进入组…

MinHook 如何对 .NET 母体 CoreCLR 进行拦截

一&#xff1a;背景 1. 讲故事 这篇文章起源于和一家 .NET公司 开线上会议时&#xff0c;提出的一个场景问题&#xff0c;程序出现了非托管内存暴涨&#xff0c;这些非托管内存关联的对象都囤积在 终结器队列 中&#xff0c;很显然这是代码中没用 using 及时释放引发的&#…

DPI深度检索原理和架构

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; DPI&#xff08;深度包检测&#xff09;技术通过**透视网络载荷内容**实现精细化流量管控与威胁检测&#xff0c;其核心在于突破传统防火墙仅检查IP/端口等表层信息的局限&#xff0c;对**应用层数据**进…

QT Creator的返回到上一步、下一步的快捷键是什么?

在 Qt Creator 中&#xff0c;用于导航的 返回上一步 (Back) 和 前进下一步 (Forward) 的快捷键如下&#xff1a; 默认快捷键&#xff1a; 功能Windows/LinuxmacOS返回上一步Alt ←Command [前进下一步Alt →Command ]

UI前端大数据处理策略优化:基于云计算的数据存储与计算

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 一、引言&#xff1a;大数据时代前端处理的挑战与云计算破局 在数字化转型的浪潮中&#xff…

机器学习基础 多层感知机

机器学习基础 多层感知机 文章目录 机器学习基础 多层感知机1. 多层感知机1.1 线性模型的失效1.2 感知机1.3 感知机的收敛定理1.4 从线性到非线性1.5 多层感知机的定义和实现 参考 1. 多层感知机 1.1 线性模型的失效 ​ 在李沐《动手学深度学习》中有这样的描述&#xff1a; …

关于安装Ollama大语言模型本地部署工具

一、Ollama 安装方法概述 Ollama 是一个开源的大型语言模型(LLM)本地部署工具&#xff0c;支持在 Windows、macOS 和 Linux 系统上运行。它简化了在本地计算机上运行和管理大语言模型的流程&#xff0c;让开发者能够轻松部署各种开源模型。 Windows 系统安装步骤 访问 Ollam…

html配置rem实现页面自适应

1.在js文件使用&#xff0c;建议放到全局js中 // 全局js文件 $(function () {// 设置根目录字体大小var baseSize 16; // 设计稿的基准字体大小&#xff0c;通常是16pxvar baseWidth 750; // 设计稿的基准宽度&#xff0c;通常是750pxfunction adjustFontSize() {const widt…

POI实现文档的图片的提取和替换

1. 简介 在日常办公自动化开发中&#xff0c;常常需要对 Word 文档中的图片进行批量提取、保存&#xff0c;甚至将图片替换为自定义的文本或链接。Apache POI 是一款强大的 Java 开源库&#xff0c;支持对 Microsoft Office 文档&#xff08;包括 Word、Excel、PowerPoint 等&…

毫米波雷达 – 深度学习

目录 数据表示 公开数据库 未来发展方向 稀疏点云 + 深度学习 直接处理点云 (1/2) 候选生成+特征提取+候选分类(DL* ) 候选生成+特征提取+候选分类(DL) 直接处理点云 (2/2) 候选生成+特征提取(DL)+候选分类(DL) 网格数据+端对端检测(DL) 稠密数据块 + 深度学习 直接…

Redis——常用指令汇总指南(一)

目录 1.set & get ①set指令 ②get指令 2.keys 3.del 4.expire & setex & psetex 5.ttl 6.exists 7.setnx 8.flushall 9.object encoding 10. type 1.set & get set & get指令中key和value都是字符串&#xff0c;但是不需要加单引号或双引号。 …

PDF处理控件Aspose.PDF教程:在 Java 中删除 PDF 页面

您是否需要使用 Java 从PDF文档中删除特定页面&#xff1f;无论您是要清理空白页、删除机密部分&#xff0c;还是仅仅在分发前调整内容&#xff0c;以编程方式操作 PDF 页面的能力都将大有裨益。本指南将向您展示如何借助Aspose.PDF仅用几行代码删除不需要的页面。让我们深入了…

RediSearch 字段类型与配置选项

1. 数值字段&#xff08;NUMERIC&#xff09; 用途&#xff1a;存储整数或浮点数&#xff0c;可进行范围查询与排序。 选项&#xff1a; SORTABLE&#xff1a;允许用 SORTBY 排序NOINDEX&#xff1a;不参与索引&#xff0c;仅供返回 定义语法 FT.CREATE idx ON HASH PREFIX…

PHP Yii2 安装SQL Server扩展-MAC M4 Pro芯片

MAC M4 Pro芯片版本&#xff0c;千锤百炼编译十几次终于成功 # 设置基础镜像并强制使用 x86_64 架构&#xff08;适配 M4 芯片&#xff09; FROM --platformlinux/amd64 php:8.1-fpm-alpine3.18WORKDIR /var/www/html# 可选&#xff1a;设置时区 ARG TZAsia/Shanghai ENV TZ${…

HTML初学者第二天

<1>HTML的语法规范 1.1标签 -双标签&#xff1a;如 <html></html> 前面的叫开始标签&#xff0c;后面的叫结束标签。 -单标签&#xff1a;如 <br /> 1.2基本语法概述 -HTML标签是由尖括号包围的关键词&#xff0c;例如<html>。 -HTML标…

【加解密与C】HASH系列(二) SHA

SHA&#xff08;安全散列算法&#xff09;简介 SHA&#xff08;Secure Hash Algorithm&#xff09;是由美国国家安全局&#xff08;NSA&#xff09;设计的一系列密码散列函数&#xff0c;用于将任意长度的数据转换为固定长度的散列值。SHA家族包括SHA-1、SHA-2&#xff08;含S…

【Python】进阶 - 数据结构与算法

系列篇章&#x1f389; No.文章1【Python】基础知识&#xff08;详细&#xff09;&#x1f680;2【Python】基础 - 循环、容器类型&#x1f680;3【Python】基础 - 推导式、函数&#x1f680;4【Python】基础 - 文件、异常、模块&#x1f680;5【Python】进阶 - 面向对象&…

【如何实现分布式压测中间件】

分布式压测中间件的原理及其实现 原理全链路追踪框架&#xff08;Trace&#xff09;MQ中间件数据库分布式缓存中间件&#xff08;Redis&#xff09;分库分表中间件 原理 通过大量阅读中间件源码&#xff0c;开源社区调研&#xff0c;得到设计原理&#xff1a; &#xff08;1&a…