当前位置: 首页 > news >正文

I.MX6ULL_Linux_系统篇(23) busybox文件系统构建

Linux“三巨头”已经完成了 2 个了,就剩最后一个 rootfs(根文件系统)了,本章我们就来学习一下根文件系统的组成以及如何构建根文件系统。这是 Linux 移植的最后一步,根文件系统构建好以后就意味着我们已经拥有了一个完整的、可以运行的最小系统。以后我们就在这个最小系统上编写、测试 Linux 驱动,移植一些第三方组件,逐步的完善这个最小系统。最终得到一个功能完善、驱动齐全、相对完善的操作系统。

BusyBox 构建根文件系统

BusyBox 是一个集成了大量的 Linux 命令和工具的软件,像 ls、 mv、 ifconfig 等命令 BusyBox 都会提供。 BusyBox 就是一个大的工具箱,这个工具箱里面集成了 Linux 的许多工具和命令。一般下载 BusyBox 的源码,然后配置 BusyBox,选择自己想要的功能,最后编译即可。BusyBox 可以在其官网下载到,官网地址为: https://busybox.net/,如图所示:

在官网左侧的“Get BusyBox”栏有一行“Download Source”,点击“Download Source”即可打开 BusyBox 的下载页,如图所示:
 

从图中可以看出,目前最新的 BusyBox 版本是 1.36.0,不过本篇我们使用开发板提供的 1.29.0 版本的BusyBox 源码->busybox-1.29.0.tar.bz2, BusyBox 准备好以后就可以构建根文件系统了!

准备BusyBox

一般我们在 Linux 驱动开发的时候都是通过 nfs 挂载根文件系统的(便于调试,不用每次修改后还要打包烧录重启),所以要在 nfs 服务器(自行搭建nfs服务器)目录中创建一个名为 rootfs 的子目录(名字大家可以随意起,为了方便就用了 rootfs)。

将 busybox-1.29.0.tar.bz2 发送到 Ubuntu 中,存放位置大家随便选择。然后使用如下命令将其解压:

tar -vxjf busybox-1.29.0.tar.bz2

解压完成以后进入到 busybox-1.29.0 目录中,此目录中的文件和文件夹如图所示:

 中文字符支持,可选,但本文不做修改。

配置 busybox

与我们编译 Uboot、 Linux kernel 一样,我们要先对 busybox 进行默认的配置,有以下几种配置选项:
①、 defconfig,缺省配置,也就是默认配置选项。
②、 allyesconfig,全选配置,也就是选中 busybox 的所有功能。
③、 allnoconfig,最小配置。
我们一般使用默认配置即可,因此使用如下命令先使用默认配置来配置一下 busybox:

make defconfig

busybox 也支持图形化配置,通过图形化配置我们可以进一步选择自己想要的功能,输入如下命令打开图形化配置界面:

make menuconfig

 配置路径如下:

Location:-> Settings-> Build static binary (no shared libs)
不选

选项“Build static binary (no shared libs)”用来决定是静态编译 busybox 还是动态编译,静态编译的话就不需要库文件,但是编译出来的库会很大。动态编译的话要求根文件系统中有库文件,但是编译出来的 busybox 会小很多。配置如图所示:

Location:-> Settings-> vi-style line editing commands

Location:-> Linux Module Utilities-> Simplified modutils
不选

Location:
-> Linux System Utilities
-> mdev (16 kb) //确保下面的全部选中,默认都是选中的

编译 busybox

配置好 busybox 以后就可以编译了,我们可以指定编译结果的存放目录,我们肯定要将编译结果存放到前面创建的 rootfs 目录中,输入如下命令:

make
make install CONFIG_PREFIX=/home/xxxxxx/nfs/rootfs

COFIG_PREFIX 指 定 编 译 结 果 的 存 放 目 录 , 比 如 我 存 放 到“/home/xxxxxx/nfs/rootfs”目录中,等待编译完成。编译完成以后如图所示:

编译完成以后会在 busybox 的所有工具和文件就会被安装到 rootfs 目录中, rootfs 目录内容如图所示:

从图中可以看出, rootfs 目录下有 bin、 sbin 和 usr 这三个目录,以及 linuxrc 这个文件。前面说过 Linux 内核 init 进程最后会查找用户空间的 init 程序,找到以后就会运行这个用户空间的 init 程序,从而切换到用户态。如果 bootargs 设置 init=/linuxrc,那么 linuxrc 就是可以作为用户空间的 init 程序,所以用户态空间的 init 程序是 busybox 来生成的。busybox 的工作就完成了,但是此时的根文件系统还不能使用,还需要一些其他的文件,我们继续来完善 rootfs。

添加 lib 库

向 rootfs 的“/lib”目录添加库文件:
Linux 中的应用程序一般都是需要动态库的, 当然你也可以编译成静态的,但是静态的可执行文件会很大。如果编译为动态的话就需要动态库,所以我们需要向根文件系统中添加动态库。在 rootfs 中创建一个名为“lib”的文件夹,命令如下:

mkdir lib

lib 文件夹创建好了,库文件从哪里来呢? lib 库文件从交叉编译器中获取,前面我们搭建交叉编译环境的时候将交叉编译器存放到了“/usr/local/arm/”目录中。交叉编译器里面有很多的库文件,这些库文件具体是做什么的我们作为初学者肯定不知道,既然我不知道那就简单粗暴的把所有的库文件都放到我们的根文件系统中。这样做出来的根文件系统肯定很大,但是我们现在是学习阶段,还做不了裁剪。进入如下路径对应的目录:

/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib

此目录下有很多的*so*(*是通配符)和.a 文件,这些就是库文件,将此目录下所有的*so*和.a文件都拷贝到 rootfs/lib 目录中,拷贝命令如下:

cp *so* *.a /home/xxxxxx/rootfs/lib/ -d

后面的“-d”表示拷贝符号链接,这里有个比较特殊的库文件: ld-linux-armhf.so.3,此库文件也是个符号链接,相当于 Windows 下的快捷方式。会链接到库 ld-2.19-2014.08-1-git.so 上,输
入命令“ls ld-linux-armhf.so.3 -l”查看此文件详细信息,如图所示:

从图可以看出, ld-linux-armhf.so.3 后面有个“->”,表示其是个软连接文件,链接到文件 ld-2.19-2014.08-1-git.so,因为其是一个“快捷方式”,因此大小只有 24B。但是, ld-linuxarmhf.so.3 不能作为符号链接,否则的话在根文件系统中执行程序无法执行!所以我们需要 ldlinux-armhf.so.3 完成逆袭,由“快捷方式”变为“本尊”,方法很简单,那就是重新复制 ld-linuxarmhf.so.3,只是不复制软链接即可。

继续进入如下目录中(不用操作也可以,库是一样的,不会新增拷贝项):

gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/lib

此目录下也有很多的的*so*和.a 库文件,我们将其也拷贝到 rootfs/lib 目录中,命令如下:

cp *so* *.a /home/xxxxxx/rootfs/lib/ -d

向 rootfs 的“usr/lib”目录添加库文件:

在 rootfs 的 usr 目录下创建一个名为 lib 的目录,将如下目录中的库文件拷贝到 rootfs/usr/lib目录下:

gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/lib

将此目录下的 so 和.a 库文件都拷贝到 rootfs/usr/lib 目录中,命令如下:

cp *so* *.a /home/xxxxxx/rootfs/usr/lib/ -d

至此,根文件系统的库文件就全部添加好了。

创建其他文件夹

在根文件系统中创建其他文件夹,如 dev、 proc、 mnt、 sys、 tmp 和 root 等,创建完成以后如图所示:

目前来看,这个根文件系统好像已经准备好了,开始测试!

测试

接下来我们使用测试一下前面创建好的根文件系统 rootfs,测试方法就是使用 NFS 挂载,uboot 里面的 bootargs 环境变量会设置“root”的值,所以我们将 root 的值改为 NFS 挂载即可。在 Linux 内核源码里面有相应的文档讲解如何设置,文档为 Documentation/filesystems/nfs/nfsroot.txt,格式如下:

root=/dev/nfs nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>] ip=<client-ip>:<server-ip>:<gwip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>

<server-ip>:服务器 IP 地址,也就是存放根文件系统主机的 IP 地址,那就是 Ubuntu 的 IP地址,比如我的 Ubuntu 主机 IP 地址为 192.168.1.250。
<root-dir>: 根文件系统的存放路径,比如我的就是/home/zuozhongkai/linux/nfs/rootfs。
<nfs-options>: NFS 的其他可选选项,一般不设置。
<client-ip>: 客户端 IP 地址,也就是我们开发板的 IP 地址, Linux 内核启动以后就会使用此 IP 地址来配置开发板。此地址一定要和 Ubuntu 主机在同一个网段内,并且没有被其他的设备使用,在 Ubuntu 中使用 ping 命令 ping 一下就知道要设置的 IP 地址有没有被使用,如果不能ping 通就说明没有被使用,那么就可以设置为开发板的 IP 地址。
<server-ip>: 服务器 IP 地址,前面已经说了。
<gw-ip>: 网关地址,我的就是 192.168.1.1。
<netmask>:子网掩码,我的就是 255.255.255.0。
<hostname>:客户机的名字,一般不设置,此值可以空着。
<device>: 设备名,也就是网卡名,一般是 eth0, eth1….,正点原子的 I.MX6U-ALPHA 开发板的 ENET2 为 eth0, ENET1 为 eth1。如果你的电脑只有一个网卡,那么基本只能是 eth0。
这里我们使用 ENET2,所以网卡名就是 eth0。
<autoconf>: 自动配置,一般不使用,所以设置为 off。
<dns0-ip>: DNS0 服务器 IP 地址,不使用。
<dns1-ip>: DNS1 服务器 IP 地址,不使用。
根据上面的格式 bootargs 环境变量的 root 值如下:

root=/dev/nfs nfsroot=192.168.1.250:/home/zuozhongkai/linux/nfs/rootfs,proto=tcp rw ip=192.168.1.251:192.168.1.250:192.168.1.1:255.255.255.0::eth0:off

“proto=tcp”表示使用 TCP 协议,“rw”表示 nfs 挂载的根文件系统为可读可写。 启动开发板,进入 uboot 命令行模式,然后重新设置 bootargs 环境变量,命令如下:

setenv bootargs 'console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.1.250:
/home/zuozhongkai/linux/nfs/rootfs,proto=tcp rw ip=192.168.1.251:192.168.1.250:192.168.1.1:
255.255.255.0::eth0:off' //设置 bootargs
saveenv //保存环境变量

 设置好以后使用“boot”命令启动 Linux 内核,结果如图所示:

从图中可以看出,我们进入了根文件系统,说明我们的根文件系统工作了!如果没有启动进入根文件系统的话可以重启一次开发板试试。我们可以输入“ls”命令测试一下,结果如图所示:

可以看出 ls 命令工作正常!那么是不是说明我们的 rootfs 就制作成功了呢?大家注意,在进入根文件系统的时候会有下面这一行错误提示:

提示很简单,说是无法运行“/etc/init.d/rcS”这个文件,因为这个文件不存在。

完善rootfs

创建/etc/init.d/rcS 文件

rcS 是个 shell 脚本, Linux 内核启动以后需要启动一些服务,而 rcS 就是规定启动哪些文件的脚本文件。在 rootfs 中创建/etc/init.d/rcS 文件,然后在 rcS 中输入如下所示内容:

1 #!/bin/sh
2 
3 PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
4 LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
5 export PATH LD_LIBRARY_PATH
6 
7 mount -a
8 mkdir /dev/pts
9 mount -t devpts devpts /dev/pts
10
11 echo /sbin/mdev > /proc/sys/kernel/hotplug
12 mdev -s

第 1 行,表示这是一个 shell 脚本。
第 3 行, PATH 环境变量保存着可执行文件可能存在的目录,这样我们在执行一些命令或者可执行文件的时候就不会提示找不到文件这样的错误。
第 4 行, LD_LIBRARY_PATH 环境变量保存着库文件所在的目录。
第 5 行,使用 export 来导出上面这些环境变量,相当于声明一些“全局变量”。
第 7 行,使用 mount 命令来挂载所有的文件系统,这些文件系统由文件/etc/fstab 来指定,所以我们一会还要创建/etc/fstab 文件。
第 8 和 9 行,创建目录/dev/pts,然后将 devpts 挂载到/dev/pts 目录中。
第 11 和 12 行,使用 mdev 来管理热插拔设备,通过这两行, Linux 内核就可以在/dev 目录下自动创建设备节点。关于 mdev 的详细内容可以参考 busybox 中的 docs/mdev.txt 文档。
示例代码中的 rcS 文件内容是最精简的,大家如果去看 Ubuntu 或者其他大型 Linux操作系统中的 rcS 文件,就会发现其非常复杂。因为我们是初次学习,所以不用搞这么复杂的,而且这么复杂的 rcS 文件也是借助其他工具创建的,比如 buildroot 等。创建好文件/etc/init.d/rcS 以后一定要给其可执行权限!

置好以后就重新启动 Linux 内核,启动以后如图所示:

从图中可以看到,提示找不到/etc/fstab 文件,还有一些其他的错误,我们先把/etc/fstab这个错误解决了。说不定把这个问题解决以后其他的错误也就解决了。前面我们说了“mount -a”挂载所有根文件系统的时候需要读取/etc/fstab,因为/etc/fstab 里面定义了该挂载哪些文件,好了,接下来就是创建/etc/fstab 文件。

创建/etc/fstab 文件

在 rootfs 中创建/etc/fstab 文件, fstab 在 Linux 开机以后自动配置哪些需要自动挂载的分区,格式如下:

<file system> <mount point> <type> <options> <dump> <pass>

<file system>:要挂载的特殊的设备,也可以是块设备,比如/dev/sda 等等。
<mount point>:挂载点。
<type>:文件系统类型,比如 ext2、 ext3、 proc、 romfs、 tmpfs 等等。
<options>:挂载选项,在 Ubuntu 中输入“man mount”命令可以查看具体的选项。一般使用 defaults,也就是默认选项, defaults 包含了 rw、 suid、 dev、 exec、 auto、 nouser 和 async。
<dump>:为 1 的话表示允许备份,为 0 不备份,一般不备份,因此设置为 0。
<pass>:磁盘检查设置,为 0 表示不检查。根目录‘/’设置为 1,其他的都不能设置为 1,其他的分区从 2 开始。一般不在 fstab 中挂载根目录,因此这里一般设置为 0。按照上述格式,在 fstab 文件中输入如下内容:

1 #<file system> <mount point> <type> <options> <dump> <pass>
2 proc             /proc         proc defaults     0     0
3 tmpfs             /tmp         tmpfs defaults     0     0
4 sysfs             /sys         sysfs defaults     0     0

fstab 文件创建完成以后重新启动 Linux,结果如图所示:

从图可以看出,启动成功,而且没有任何错误提示。但是我们要还需要创建一个文件/etc/inittab。

创建/etc/inittab 文件

inittab 的详细内容可以参考 busybox 下的文件 examples/inittab。 init 程序会读取/etc/inittab这个文件, inittab 由若干条指令组成。每条指令的结构都是一样的,由以“:”分隔的 4 个段组
成,格式如下:

<id>:<runlevels>:<action>:<process>

<id>:每个指令的标识符,不能重复。但是对于 busybox 的 init 来说, <id>有着特殊意义。<id>用来指定启动进程的控制 tty,一般我们将串口或者 LCD 屏幕设置为控制 tty。
<runlevels>: 对 busybox 来说此项完全没用,所以空着。
<action>:动作,用于指定<process>可能用到的动作。 busybox 支持的动作如表所示:

动作描述
sysinit在系统初始化的时候 process 才会执行一次。
respawn当 process 终止以后马上启动一个新的。
askfirst和 respawn 类似,在运行 process 之前在控制台上显示“Please press Enter to activate
this console.”。只要用户按下“Enter”键以后才会执行 process。
wait告诉 init,要等待相应的进程执行完以后才能继续执行。
once仅执行一次,而且不会等待 process 执行完成。
restart当 init 重启的时候才会执行 process。
ctrlaltdel当按下 ctrl+alt+del 组合键才会执行 process。
shutdown关机的时候执行 process。

<process>: 具体的动作,比如程序、脚本或命令等。参考 busybox 的 examples/inittab 文件,我们也创建一个/etc/inittab,在里面输入如下内容:

1 #etc/inittab
2 ::sysinit:/etc/init.d/rcS
3 console::askfirst:-/bin/sh
4 ::restart:/sbin/init
5 ::ctrlaltdel:/sbin/reboot
6 ::shutdown:/bin/umount -a -r
7 ::shutdown:/sbin/swapoff -a

第 2 行,系统启动以后运行/etc/init.d/rcS 这个脚本文件。
第 3 行,将 console 作为控制台终端,也就是 ttymxc0。
第 4 行,重启的话运行/sbin/init。
第 5 行,按下 ctrl+alt+del 组合键的话就运行/sbin/reboot,看来 ctrl+alt+del 组合键用于重启系统。
第 6 行,关机的时候执行/bin/umount,也就是卸载各个文件系统。
第 7 行,关机的时候执行/sbin/swapoff,也就是关闭交换分区。
/etc/inittab 文件创建好以后就可以重启开发板即可,至此!根文件系统要创建的文件就已经全部完成了。接下来就要对根文件系统进行其他的测试,比如我们自己编写的软件运行是否正
常、是否支持软件开机自启动、以及能不能链接等。

创建/etc/resolv.conf,指定域名服务器:

1 nameserver 114.114.114.114
2 nameserver 192.168.1.1

开机自启:

进入根文件系统的时候会运行/etc/init.d/rcS 这个 shell 脚本,因此我们可以在这个脚本里面添加自启动相关内容。添加完成以后的/etc/init.d/rcS 文件内容如下:

1 #!/bin/sh
2 PATH=/sbin:/bin:/usr/sbin:/usr/bin
3 LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
4 runlevel=S
5 umask 022
6 export PATH LD_LIBRARY_PATH runlevel
7 
8 mount -a
9 mkdir /dev/pts
10 mount -t devpts devpts /dev/pts
11
12 echo /sbin/mdev > /proc/sys/kernel/hotplug
13 mdev -s
14
15 #开机自启动
16 cd /drivers
17 ./hello &
18 cd /

第 16 行,进入 drivers 目录,因为要启动的软件存放在 drivers 目录下。
第 17 行,以后台方式执行 hello 这个软件。
第 18 行,退出 drivers 目录,进入到根目录下。
自启动代码添加完成以后就可以重启开发板,hello 这个软件就会自动运行!
 

相关文章:

I.MX6ULL_Linux_系统篇(23) busybox文件系统构建

Linux“三巨头”已经完成了 2 个了&#xff0c;就剩最后一个 rootfs(根文件系统)了&#xff0c;本章我们就来学习一下根文件系统的组成以及如何构建根文件系统。这是 Linux 移植的最后一步&#xff0c;根文件系统构建好以后就意味着我们已经拥有了一个完整的、可以运行的最小系…...

shpjs将.zip文件转成geoJson

一、npm install shpjs二、import shp from shpjs三、async setLayerSource() {const geoJsonData await shp(dataUrl)}一直报错&#xff1a;是因为Buffer这个插件一直没找到Uncaught Error: nodebuffer is not supported by this browser解决办法npm install node-polyfill-w…...

eBay是不是一定要养号?是的

相信每个运营过eBay的用户遇到过这个棘手的问题&#xff0c;eBay个人账户的刊登数量是有限的&#xff0c;尤其是新账户只有5个sku&#xff0c;所以一开始的运营会比较艰难。想要快点走上正轨的话&#xff0c;就一定要去注重这个“养号”。eBay运营模式 1.拍卖 eBay最开始是一个…...

宝塔(二):升级JDK版本

目录 背景 一、下载JDK17 二、配置环境变量 三、配置新的JDK路径 背景 宝塔的软件商店只有JDK8&#xff0c;不满足我当前项目所需的JDK版本&#xff0c;因此想对JDK版本进行升级&#xff0c;升级为JDK17。 一、下载JDK17 先进入 /usr/lib/jvm 目录 点击终端&#xff0c;进…...

【LeetCode】螺旋矩阵 [M](数组)

54. 螺旋矩阵 - 力扣&#xff08;LeetCode&#xff09; 一、题目 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,…...

实验二:动态规划

1.双11的红包雨 问题描述 双11到了&#xff0c;据说这2天会下红包雨&#xff0c;每个红包有不同的价值&#xff0c;小k好开心&#xff0c;但有个规则&#xff0c;就只能接掉落在他身旁的10米范围内的红包&#xff08;0-10这11个位置&#xff09;。小k想尽可能的多抢红包&…...

华为机试 HJ27 查找兄弟单词

题目链接&#xff1a;https://www.nowcoder.com/practice/03ba8aeeef73400ca7a37a5f3370fe68?tpId37&tqId21250&rp1&ru/exam/oj/ta&qru/exam/oj/ta&sourceUrl%2Fexam%2Foj%2Fta%3Fdifficulty%3D3%26page%3D1%26pageSize%3D50%26search%3D%26tpId%3D37%26t…...

佩戴舒适的蓝牙耳机有哪些?佩戴舒适的蓝牙耳机推荐

音乐对许多人而言&#xff0c;都是一种抚慰生命的力量&#xff0c;特别是在上下班的时候&#xff0c;在熙熙攘攘的人流中&#xff0c;戴着耳机听一首动听的曲子&#xff0c;无疑会让人心情变得更加舒畅&#xff0c;要想获得出色的音乐体验&#xff0c;没有一副出色的耳机可不行…...

ESXI主机安装Zabbix 6.2

1&#xff1a;首先下载Zabbix Appliance 2&#xff1a;还需要下载VMware converter &#xff0c;这个需要VMware的账号&#xff0c;或者从其他地方下载也可以。 3:vmdk格式的 image 可直接在 VMware Player、 Server 和 Workstation 产品中使用。要在 ESX,、ESXi 和 vSphere 中…...

【Linux 网络编程1】使用UDP/TCP编写套接字,多进程/多线程版本的TCP编写的套接字,将套接字封装

目录 1.学习网络编程前的一些基础知识 2.UDP(user datagram protocol)协议的特点 3.使用有UPD编写套接字 4.使用TCP编写套接字 4.2.TCP客服端 4.3.TCP服务器端 4.4.单进程版本&#xff08;没有人会使用&#xff09; 4.5.多进程版本 4.6.多线程版本 5.把套接字封装 1…...

滑动窗口求最大和最小

滑动窗口 要区分最小和最大滑窗&#xff0c;内层while循环的条件和更新结果的地方 核心&#xff1a; 关键的区别在于&#xff0c;最大滑窗是在迭代右移右边界的过程中更新结果&#xff0c;而最小滑窗是在迭代右移左边界的过程中更新结果。 最小滑窗 给定数组 nums&#xff0…...

跟ChatGPT学量化,菜鸟炒股也不怕

你是一个python资深量化开发工程师&#xff0c;请介绍量化交易的基本框架 量化交易的基本框架包括以下几个步骤&#xff1a; 数据获取&#xff1a;获取市场数据和公司财务数据等&#xff0c;可以使用API接口、爬虫等方式获取。数据清洗和预处理&#xff1a;对获取到的数据进行清…...

扬帆优配|2600亿新能源巨头狂飙!外资唱多中国:再涨15%

全国停摆的危机&#xff0c;正在迫临法国。 大停工正在将法国推向风险境地。法国政府估计&#xff0c;当地时间3月7日&#xff0c;将迸发全国大型停工游行。法国总工会宣告&#xff0c;到时将让全法国停摆。法国担任交通业务的部长级代表克莱蒙博讷正告称&#xff0c;7日将成为…...

ChatGPT技术与商业模式及产业发展布局方案

文章目录模块一&#xff1a;概念模块二&#xff1a;架构模块三&#xff1a;技术模块四&#xff1a;算力模块五&#xff1a;体验模块六&#xff1a;应用模块七&#xff1a;商业模块八&#xff1a;产业模块九&#xff1a;建议结语主要内容&#xff1a; 采用模块化教学方法&#x…...

CIMCAI port ai shipping ai artificial intelligence smart port

上海人工智能独角兽中集集团高科技中集飞瞳&#xff0c;是全球应用落地最广&#xff0c;规模最大&#xff0c;最先进的的港航人工智能高科技企业&#xff0c;工业级成熟港航人工智能产品全球规模化落地应用&#xff0c;全球前三大船公司及港口码头应用落地。上海人工智能独角兽…...

《数据解构》HashMap源码解读

&#x1f451;作者主页&#xff1a;Java冰激凌 &#x1f4d6;专栏链接&#xff1a;数据结构 目录 了解HashMap HashMap的构造 两个参数的构造方法 一个参数的构造方法 不带参数的构造方法 哈希表初始化的长度 HashMap源码中的成员 Pt Get 了解HashMap 首先我们要明…...

Databend 开源周报 第 83 期

Databend 是一款现代云数仓。专为弹性和高效设计&#xff0c;为您的大规模分析需求保驾护航。自由且开源。即刻体验云服务&#xff1a;https://app.databend.com 。Whats New探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。Support for WebHDFSHDFS 是大数…...

Spring | 基础

1. IOC和DI IOC&#xff1a;控制反转&#xff0c;其思想是反转资源获取的方向&#xff0c;传统的资源查找方式要求组件向容器发起请求查找资源&#xff0c;作为回应&#xff0c;容器适时的返回资源。而应用了 IOC 之后&#xff0c;则是**容器主动地将资源推送给它所管理的组件…...

windows7安装sql server 2000安装步骤 及安装过程中遇到的问题和解决方式

提示&#xff1a;文章写完后windows7安装sql server 2000安装步骤 及安装过程中遇到的问题和解决方式&#xff0c; 文章目录一、ms sql server 2000是什么&#xff1f;版本简介&#xff1a;**特点&#xff1a;****优点&#xff1a;**二、步骤1.下载安装包及Sq4补丁包2.安装 ms …...

Python 开发-批量 FofaSRC 提取POC 验证

数据来源 学习内容和目的&#xff1a; ---Request 爬虫技术&#xff0c;lxml 数据提取&#xff0c;异常护理&#xff0c;Fofa 等使用说明---掌握利用公开或 0day 漏洞进行批量化的收集及验证脚本开发Python 开发-某漏洞 POC 验证批量脚本---glassfish存在任意文件读取在默认4…...

Linux系统中部署软件

目录 1.Mysql 2.Redis 3.ZooKeeper 声明 致谢 1.Mysql 参考&#xff1a;CentOS7安装MySQL 补充&#xff1a; ① 执行&#xff1a;rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022 再执行&#xff1a;yum -y install mysql-community-server ② mysql…...

PHP常用框架介绍与比较

HP是一种广泛应用于Web开发的编程语言。随着互联网的快速发展,PHP的应用场景变得越来越广泛,从简单的网站到复杂的Web应用程序都可以使用PHP来开发。为了更好地组织和管理PHP代码,开发人员经常会使用框架来提高开发效率和代码质量。 本文将介绍一些常用的PHP框架,并进行简…...

Umi + React + Ant Design Pro 项目实践(一)—— 项目搭建

学习一下 Umi、 Ant Design 和 Ant Design Pro 从 0 开始创建一个简单应用。 首先&#xff0c;新建项目目录&#xff1a; 在项目目录 D:\react\demo 中&#xff0c;安装 Umi 脚手架&#xff1a; yarn create umi # npm create umi安装成功&#xff1a; 接下来&#xff0c;…...

MySQL知识点总结(1)

目录 1、sql、DB、DBMS分别是什么&#xff0c;他们之间的关系&#xff1f; 2、什么是表&#xff1f; 3、SQL语句怎么分类呢&#xff1f; 4、导入数据 5、什么是sql脚本呢&#xff1f; 6、删除数据库 7、查看表结构 8、表中的数据 10、查看创建表的语句 11、简单的查询…...

day45第九章动态规划(二刷)

今日任务 70.爬楼梯(进阶)322.零钱兑换279.完全平方数 70.爬楼梯(进阶) 题目链接&#xff1a; https://leetcode.cn/problems/climbing-stairs/description/ 题目描述&#xff1a; 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不…...

第十四届蓝桥杯第三期模拟赛原题与详解

​​​​​​​ 文章目录 一、填空题 1、1 找最小全字母十六进制数 1、1、1 题目描述 1、1、2 题解关键思路与解答 1、2 给列命名 1、2、1 题目描述 1、2、2 题解关键思路与解答 1、3 日期相等 1、3、1 题目描述 1、3、2 题解关键思路与解答 1、4 乘积方案数 1、4、1 题目描…...

client打包升级

目录 前言 一、client如何打包升级&#xff1f; 二、使用步骤 1.先进行改版本 2.执行打包升级命令 总结 前言 本文章主要记录一下&#xff0c;日常开发中&#xff0c;常需要进行打包升级的步骤。 一、client如何打包升级&#xff1f; # 升级发布版本 ## 修改版本 * 父p…...

Blazor_WASM之3:项目结构

Blazor_WASM之3&#xff1a;项目结构 Blazor WebAssembly项目模板可选两种&#xff0c;Blazor WebAssemblyAPP及Blazor WebAssemblyAPP-Empty 如果使用Blazor WebAssemblyAPP模板&#xff0c;则应用将填充以下内容&#xff1a; 一个 FetchData 组件的演示代码&#xff0c;该…...

OperWrt 包管理系统02

文章目录 OperWrt 包管理系统OPKG简介OPKG的工作原理OPKG命令介绍软件包的更新、安装、卸载和升级等功能软件包的信息查询OPKG配置文件说明OPKG包结构(.ipk)OPKG演示案例OperWrt 包管理系统 OPKG简介 OPKG(Open/OpenWrt Package)是一个轻量快速的软件包管理系统,是 IPKG…...

人人都学会APP开发 提高就业竞争力 简单实用APP应用 安卓浏览器APP 企业内部通用APP制作 制造业通用APP

安卓从2009年开始流程于手机、平板&#xff0c;已经是不争的非常强大生产力工具&#xff0c;更为社会创造非常高的价值&#xff0c;现在已经是202X年&#xff0c;已经十几年的发展&#xff0c;安卓平台已经无所不在。因此建议人人都学学APP制作&#xff0c;简易入门&#xff0c…...

东莞网站制作培训/管理人员课程培训

背 景MySQL高可用方案有很多种&#xff0c;常见的有&#xff1a;keepalived、MHA、Galera、MGR、Orchestrator、replication-manager等。本系列将介绍在GitHub被使用的Orchestrator方案。本篇文章先介绍最基础的单节点模式的安装。环 境orchestrator机器&#xff1a;10.10.30.1…...

慈溪做网站/女生读网络营销与电商直播

VNCTF2022_Misc_复现 仔细找找 放大图片可以看见有很小的与周围颜色不同的像素点均匀的分布在图片中 先寻找像素点之间的间隔&#xff0c;然后拼接在一起生成新的图片 代码实现 from re import L from PIL import Image import numpy pic Image.open("C:\\Users\\Me…...

进口全屋定制十大名牌/seo整站优化

MQTT v5 相较于 MQTT v3.1 和 v3.1.1 提供了许多新特性。我们会尽量以通俗易懂的方式展示这些特性&#xff0c;并探讨这些特性对开发者的影响。我们已经探讨过其中一部分 MQTT v5 新特性&#xff0c;今天将继续讨论&#xff1a;主题别名。 什么是主题别名 主题别名&#xff0…...

wordpress qoob/seo算法

使用场景&#xff1a;在操作应用时常见toast弹框&#xff0c;通过toast弹框信息的获取判断当前的某个操作是否成功 引用的包&#xff1a;from selenium.webdriver.support import expected_conditions as EC,\expected_conditions from selenium.webdriver.common.by import By…...

云南专业网站建设/外贸网站制作推广

算是狗年上班的最后一天吧&#xff0c;想想还是略略总结一下近半年来的概况。 这段时间比较懒得去总结更新发表新的博客&#xff0c;一来是生活和工作的琐碎让自己有些懈怠&#xff0c;二是对自己写的东西缺乏深度感到困扰&#xff0c;自己大概也带着些完美型人格吧。最近的工…...

如何做传奇私服网站/seo搜索优化排名

题目链接&#xff1a;https://loj.ac/problem/10013 分析&#xff1a; 对于题目中给定的二次函数是符合用三分求极值的&#xff0c;关键是如何在n个这样的函数中找到最大的那一个&#xff1f; 我们会的就是一个这样的函数在给定区间内求极值。 所以&#xff0c;在每次三分的过…...