http://www.ibm.com/developerworks/cn/linux/l-initrd.html
-------------------------------------------------------------------------------------------------------------------
Linux® 初始 RAM 磁盘(initrd)是在系统引导过程中挂载的一个临时根文件系统,用来支持两阶段的引导过程。initrd 文件中包含了各种可执行程序和驱动程序,它们可以用来挂载实际的根文件系统,然后再将这个 initrd RAM 磁盘卸载,并释放内存。在很多嵌入式 Linux 系统中,initrd 就是最终的根文件系统。本文将探索 Linux 2.6 的初始 RAM 磁盘,包括如何创建以及如何在 Linux 内核中使用。
什么是初始 RAM 磁盘?
初始 RAM 磁盘(initrd)是在实际根文件系统可用之前挂载到系统中的一个初始根文件系统。initrd
与内核绑定在一起,并作为内核引导过程的一部分进行加载。内核然后会将这个 initrd
文件作为其两阶段引导过程的一部分来加载模块,这样才能稍后使用真正的文件系统,并挂载实际的根文件系统。
initrd 中包含了实现这个目标所需要的目录和可执行程序的最小集合,例如将内核模块加载到内核中所使用的 insmod
工具。
在桌面或服务器 Linux 系统中,initrd 是一个临时的文件系统。其生存周期很短,只会用作到真实文件系统的一个桥梁。在没有存储设备的嵌入式系统中,initrd 是永久的根文件系统。本文将对这两种情况进行探索。
initrd 映像中包含了支持 Linux 系统两阶段引导过程所需要的必要可执行程序和系统文件。
根据我们运行的 Linux 的版本不同,创建初始 RAM 磁盘的方法也可能会有所不同。在 Fedora Core 3 之前,initrd 是使用 loop 设备 来构建的。loop 设备 是一个设备驱动程序,利用它可以将文件作为一个块设备挂载到系统中,然后就可以查看这个文件系统中的内容了。在您的内核中可能并没有 loop 设备,不过这可以通过内核配置工具(make menuconfig
)选择 Device Drivers > Block Devices > Loopback Device Support 来启用。我们可以按照下面的方法来查看 loop 设备的内容(initrd 文件的名字可能会稍有不同):
清单 1. 查看 initrd 的内容(适用于 FC3 之前的版本)
# mkdir temp ; cd temp # cp /boot/initrd.img.gz . # gunzip initrd.img.gz # mount -t ext -o loop initrd.img /mnt/initrd # ls -la /mnt/initrd #
|
现在我们就可以查看 /mnt/initrd 子目录中的内容了,这就代表了 initrd 文件的内容。注意,即使您的 initrd
映像文件不是以 .gz 结尾,它也可能是一个压缩文件,您可以给这个文件添加上 .gz 后缀,然后再使用 gunzip 对其进行解压。
从 Fedora Core 3 开始,默认的 initrd 映像变成了一个经过压缩的 cpio 归档文件。我们不用再使用 loop
设备来将 initrd 作为压缩映像进行挂载,而是可以将其作为 cpio 归档文件来使用。要查看 cpio 归档文件的内容,可以使用下面的命令:
清单 2. 查看 initrd 的内容(适用于 FC3 及其以后的版本)
# mkdir temp ; cd temp # cp /boot/initrd-2.6.14.2.img initrd-2.6.14.2.img.gz # gunzip initrd-2.6.14.2.img.gz # cpio -i --make-directories < initrd-2.6.14.2.img #
|
结果会生成一个很小的根文件系统,如清单 3 所示。在 ./bin 目录中有一组很少但却非常必要的应用程序,包括 nash
(即 not a shell,是一个脚本解释器)、insmod
(用来加载内核模块)和 lvm
(逻辑卷管理工具)。
清单 3. 默认的 Linux initrd 目录结构
# ls -la # drwxr-xr-x 10 root root 4096 May 7 02:48 . drwxr-x--- 15 root root 4096 May 7 00:54 .. drwxr-xr-x 2 root root 4096 May 7 02:48 bin drwxr-xr-x 2 root root 4096 May 7 02:48 dev drwxr-xr-x 4 root root 4096 May 7 02:48 etc -rwxr-xr-x 1 root root 812 May 7 02:48 init -rw-r--r-- 1 root root 1723392 May 7 02:45 initrd-2.6.14.2.img drwxr-xr-x 2 root root 4096 May 7 02:48 lib drwxr-xr-x 2 root root 4096 May 7 02:48 loopfs drwxr-xr-x 2 root root 4096 May 7 02:48 proc lrwxrwxrwx 1 root root 3 May 7 02:48 sbin -> bin drwxr-xr-x 2 root root 4096 May 7 02:48 sys drwxr-xr-x 2 root root 4096 May 7 02:48 sysroot #
|
清单 3 中比较有趣的是 init 文件就在根目录中。与传统的 Linux 引导过程类似,这个文件也是在将 initrd 映像解压到 RAM 磁盘中时被调用的。在本文稍后我们将来探索这个问题。
创建 initrd 所使用的工具
|
cpio 命令
使用 cpio
命令,我们可以对 cpio 文件进行操作。cpio 是一种文件格式,它简单地使用文件头将一组文件串接在一起。cpio 文件格式可以使用
ASCII 和二进制文件。为了保证可移植性,我们可以使用 ASCII 格式。为了减小文件大小,我们可以使用二进制的版本。
|
|
下面让我们回到最开始,来看一下 initrd 映像最初是如何构建的。对于传统的 Linux 系统来说,initrd 映像是在 Linux 构建过程中创建的。有很多工具,例如 mkinitrd
,都可以用来使用必要的库和模块自动构建 initrd,从而用作与真实的根文件系统之间的桥梁。mkinitrd
工具实际上就是一个 shell 脚本,因此我们可以看到它究竟是如何来实现这个结果的。还有一个 YAIRD
(即 Yet Another Mkinitrd)工具,可以对 initrd 构建过程的各个方面进行定制。
手工构建定制的初始 RAM 磁盘
由于在很多基于 Linux 的嵌入式系统上没有硬盘,因此 initrd 也会作为这种系统上的永久根文件系统使用。清单 4
显示了如何创建一个 initrd 映像文件。我使用了一个标准的 Linux
桌面,这样您即使没有嵌入式平台,也可以按照下面的步骤来执行了。除了交叉编译,其他概念(也适用于 initrd 的构建)对于嵌入式平台都是相同的。
清单 4. 创建定制 initrd 的工具(mkird)
#!/bin/bash
# Housekeeping... rm -f /tmp/ramdisk.img rm -f /tmp/ramdisk.img.gz
# Ramdisk Constants RDSIZE=4000 BLKSIZE=1024
# Create an empty ramdisk image dd if=/dev/zero of=/tmp/ramdisk.img bs=$BLKSIZE count=$RDSIZE
# Make it an ext2 mountable file system /sbin/mke2fs -F -m 0 -b $BLKSIZE /tmp/ramdisk.img $RDSIZE
# Mount it so that we can populate mount /tmp/ramdisk.img /mnt/initrd -t ext2 -o loop=/dev/loop0
# Populate the filesystem (subdirectories) mkdir /mnt/initrd/bin mkdir /mnt/initrd/sys mkdir /mnt/initrd/dev mkdir /mnt/initrd/proc
# Grab busybox and create the symbolic links pushd /mnt/initrd/bin cp /usr/local/src/busybox-1.1.1/busybox . ln -s busybox ash ln -s busybox mount ln -s busybox echo ln -s busybox ls ln -s busybox cat ln -s busybox ps ln -s busybox dmesg ln -s busybox sysctl popd
# Grab the necessary dev files cp -a /dev/console /mnt/initrd/dev cp -a /dev/ramdisk /mnt/initrd/dev cp -a /dev/ram0 /mnt/initrd/dev cp -a /dev/null /mnt/initrd/dev cp -a /dev/tty1 /mnt/initrd/dev cp -a /dev/tty2 /mnt/initrd/dev
# Equate sbin with bin pushd /mnt/initrd ln -s bin sbin popd
# Create the init file cat >> /mnt/initrd/linuxrc << EOF #!/bin/ash echo echo "Simple initrd is active" echo mount -t proc /proc /proc mount -t sysfs none /sys /bin/ash --login EOF
chmod +x /mnt/initrd/linuxrc
# Finish up... umount /mnt/initrd gzip -9 /tmp/ramdisk.img cp /tmp/ramdisk.img.gz /boot/ramdisk.img.gz
|
|
initrd Linux 发行版
Minimax
是一个开放源码项目,其设计目标是成为一个全部封装在 initrd 中的 Linux 发行版。它的大小是 32MB,为了尽量小,它使用了
BusyBox 和 uClibc。除了非常小之外,它还使用了 2.6 版本的 Linux 内核,并提供了很多有用的工具。
|
|
为了创建 initrd,我们最开始创建了一个空文件,这使用了 /dev/zero
(一个由零组成的码流)作为输入,并将其写入到 ramdisk.img 文件中。所生成的文件大小是 4MB(4000 个 1K 大小的块)。然后使用 mke2fs
命令在这个空文件上创建了一个 ext2(即 second extended)文件系统。现在这个文件变成了一个 ext2
格式的文件系统,我们使用 loop 设备将这个文件挂载到 /mnt/initrd 上了。在这个挂载点上,我们现在就有了一个目录,它以 ext2
文件系统的形式呈现出来,我们可以对自己的 initrd 文件进行拼装了。接下来的脚本提供了这种功能。
下一个步骤是创建构成根文件系统所需要的子目录:/bin、/sys、/dev 和 /proc。这里只列出了所需要的目录(例如没有库),但是其中包含了很多功能。
|
ext2 文件系统的替代品
尽
管 ext2 是一种通用的 Linux 文件系统格式,但是还有一些替代品可以减小 initrd
映像文件以及所挂载上来的文件系统的大小。这种文件系统的例子有 romfs(ROM 文件系统)、cramfs(压缩 ROM 文件系统)和
squashfs(高度压缩只读文件系统)。如果我们需要暂时将数据写入文件系统中,ext2 可以很好地实现这种功能。最后,e2compr 是
ext2 文件系统驱动程序的一个扩展,可以支持在线压缩。
|
|
为了可以使用根文件系统,我们使用了 BusyBox。这个工具是一个单一映像,其中包含了很多在 Linux 系统上通常可以找到的工具(例如
ash、awk、sed、insmod 等)。BusyBox
的优点是它将很多工具打包成一个文件,同时还可以共享它们的通用元素,这样可以极大地减少映像文件的大小。这对于嵌入式系统来说非常理想。将
BusyBox 映像从自己的源目录中拷贝到自己根目录下的 /bin 目录中。然后创建了很多符号链接,它们都指向 BusyBox
工具。BusyBox 会判断所调用的是哪个工具,并执行这个工具的功能。我们在这个目录中创建了几个链接来支持 init
脚本(每个命令都是一个指向 BusyBox 的链接。)
下一个步骤是创建几个特殊的设备文件。我从自己当前的 /dev 子目录中直接拷贝了这些文件,这使用了 -a
选项(归档)来保留它们的属性。
倒数第二个步骤是生成 linuxrc 文件。在内核挂载 RAM 磁盘之后,它会查找 init
文件来执行。如果没有找到 init
文件,内核就会调用 linuxrc 文件作为自己的启动脚本。我们在这个文件中实现对环境的基本设置,例如挂载 /proc 文件系统。除了 /proc 之外,我还挂载了 /sys 文件系统,并向终端打印一条消息。最后,我们调用了 ash
(一个 Bourne Shell 的克隆),这样就可以与根文件系统进行交互了。linuxrc 文件然后使用 chmod
命令修改成可执行的。
最后,我们的根文件系统就完成了。我们将其卸载掉,然后使用 gzip
对其进行压缩。所生成的文件(ramdisk.img.gz)被拷贝到 /boot 子目录中,这样就可以通过 GNU GRUB 对其进行加载了。
要构建初始 RAM 磁盘,我们可以简单地调用 mkird
,这样就会自动创建这个映像文件,并将其拷贝到 /boot 目录中。
测试定制的初始 RAM 磁盘
|
Linux 内核中对 initrd 的支持
对于 Linux 内核来说,要支持初始 RAM 磁盘,内核必须要使用 CONFIG_BLK_DEV_RAM 和 CONFIG_BLK_DEV_INITRD 选项进行编译。
|
|
新的 initrd 映像现在已经在 /boot 目录中了,因此下一个步骤是使用默认的内核来对其进行测试。现在我们可以重新启动 Linux
系统了。在出现 GRUB 界面时,按 C 键启动 GRUB 中的命令行工具。我们现在可以与 GRUB 进行交互,从而定义要加载哪个内核和
initrd 映像文件。kernel
命令让我们可以指定内核文件,initrd
命令可以用来指定 initrd 映像文件。在定义好这些参数之后,就可以使用 boot
命令来引导内核了,如清单 5 所示。
清单 5. 使用 GRUB 手工引导内核和 initrd
GNU GRUB version 0.95 (638K lower / 97216K upper memory)
[ Minimal BASH-like line editing is supported. For the first word, TAB lists possible command completions. Anywhere else TAB lists the possible completions of a device/filename. ESC at any time exits.]
grub> kernel /bzImage-2.6.1 [Linux-bzImage, setup=0x1400, size=0x29672e]
grub> initrd /ramdisk.img.gz [Linux-initrd @ 0x5f2a000, 0xb5108 bytes]
grub> boot
Uncompressing Linux... OK, booting the kernel.
|
在内核启动之后,它会检查是否有 initrd 映像文件可用(稍后会更详细介绍),然后将其加载,并将其挂载成根文件系统。在清单 6
中我们可以看到这个 Linux 启动过程最后的样子。在启动之后,ash shell
就可以用来输入命令了。在这个例子中,我们将浏览一下根文件系统的内容,并查看一下虚拟 proc 文件系统中的内容。我们还展示了如何通过
touch 命令在文件系统中创建文件。注意所创建的第一个进程是 linuxrc
(通常都是 init
)。
清单 6. 使用简单的 initrd 引导 Linux 内核
... md: Autodetecting RAID arrays md: autorun md: ... autorun DONE. RAMDISK: Compressed image found at block 0 VFS: Mounted root (ext2 file system). Freeing unused kernel memory: 208k freed / $ ls bin etc linuxrc proc sys dev lib lost+found sbin / $ cat /proc/1/cmdline /bin/ash/linuxrc / $ cd bin /bin $ ls ash cat echo mount sysctl busybox dmesg ls ps /bin $ touch zfile /bin $ ls ash cat echo mount sysctl busybox dmesg ls ps zfile
|
使用初始 RAM 磁盘来引导系统
现在我们已经了解了如何构建并使用定制的初始 RAM 磁盘,本节将探索内核是如何识别 initrd 并将其作为根文件系统进行挂载的。我们将介绍启动链中的几个主要函数,并解释一下到底在进行什么操作。
引导加载程序,例如 GRUB,定义了要加载的内核,并将这个内核映像以及相关的 initrd 拷贝到内存中。我们可以在 Linux 内核源代码目录中的 ./init 子目录中找到很多这种功能。
在内核和 initrd 映像被解压并拷贝到内存中之后,内核就会被调用了。它会执行不同的初始化操作,最终您会发现自己到了 init/main.c:init()
(subdir/file:function)函数中。这个函数执行了大量的子系统初始化操作。此处会执行一个对 init/do_mounts.c:prepare_namespace()
的调用,这个函数用来准备名称空间(挂载 dev 文件系统、RAID 或 md、设备以及最后的 initrd)。加载 initrd 是通过调用 init/do_mounts_initrd.c:initrd_load()
实现的。
initrd_load()
函数调用了 init/do_mounts_rd.c:rd_load_image()
,它通过调用 init/do_mounts_rd.c:identify_ramdisk_image()
来确定要加载哪个 RAM 磁盘。这个函数会检查映像文件的 magic 号来确定它是 minux、etc2、romfs、cramfs 或 gzip 格式。在返回到 initrd_load_image
之前,它还会调用 init/do_mounts_rd:crd_load()
。这个函数负责为 RAM 磁盘分配空间,并计算循环冗余校验码(CRC),然后对 RAM 磁盘映像进行解压,并将其加载到内存中。现在,我们在一个适合挂载的块设备中就有了这个 initrd 映像。
现在使用一个 init/do_mounts.c:mount_root()
调用将这个块设备挂载到根文件系统上。它会创建根设备,并调用 init/do_mounts.c:mount_block_root()
。在这里调用 init/do_mounts.c:do_mount_root()
,后者又会调用 fs/namespace.c:sys_mount()
来真正挂载根文件系统,然后 chdir
到这个文件系统中。这就是我们在清单 6 中所看到的熟悉消息 VFS: Mounted root (ext2 file system).
的地方。
最后,返回到 init
函数中,并调用 init/main.c:run_init_process
。这会导致调用 execve
来启动 init 进程(在本例中是 /linuxrc
)。linuxrc 可以是一个可执行程序,也可以是一个脚本(条件是它有脚本解释器可用)。
这些函数的调用层次结构如清单 7 所示。尽管此处并没有列出拷贝和挂载初始 RAM 磁盘所涉及的所有函数,但是这足以为我们提供一个整体流程的粗略框架。
清单 7. initrd 加载和挂载过程中所使用的主要函数的层次结构
init/main.c:init init/do_mounts.c:prepare_namespace init/do_mounts_initrd.c:initrd_load init/do_mounts_rd.c:rd_load_image init/do_mounts_rd.c:identify_ramdisk_image init/do_mounts_rd.c:crd_load lib/inflate.c:gunzip init/do_mounts.c:mount_root init/do_mounts.c:mount_block_root init/do_mounts.c:do_mount_root fs/namespace.c:sys_mount init/main.c:run_init_process execve
|
无盘引导
与嵌入式引导的情况类似,本地磁盘(软盘或 CD-ROM)对于引导内核和 ramdisk
根文件系统来说都不是必需的。DHCP(Dynamic Host Configuration Protocol)可以用来确定网络参数,例如 IP
地址和子网掩码。TFTP(Trivial File Transfer Protocol)可以用来将内核映像和初始 ramdisk
映像传输到本地设备上。传输完成之后,就可以引导 Linux 内核并挂载 initrd 了,这与本地映像引导的过程类似。
压缩 initrd
在构建嵌入式系统时,我们可能希望将 initrd 映像文件做得尽可能小,这其中有一些技巧需要考虑。首先是使用 BusyBox(本文中已经展示过了)。BusyBox 可以将数 MB 的工具压缩成几百 KB。
在这个例子中,BusyBox 映像是静态链接的,因此它不需要其他库。然而,如果我们需要标准的 C
库(我们自己定制的二进制可能需要这个库),除了巨大的 glibc 之外,我们还有其他选择。第一个较小的库是
uClibc,这是为对空间要求非常严格的系统准备的一个标准 C 库。另外一个适合空间紧张的环境的库是
dietlib。要记住我们需要使用这些库来重新编译想在嵌入式系统中重新编译的二进制文件,因此这需要额外再做一些工作(但是这是非常值得的)。
结束语
初始 RAM 磁盘最初是设计用来通过一个临时根文件系统来作为内核到最终的根文件系统之间的桥梁。initrd 对于在嵌入式系统中加载到 RAM 磁盘里的非持久性根文件系统来说也非常有用。
参考资料
学习
获得产品和技术
-
cpio 文件格式(现在可以用作 Fedora Core 的一种 initrd 映像格式)具有很长的历史,可以在很多 UNIX 系统上使用。
-
ash shell 是 Bourne Shell 的一个克隆(它们大部分是兼容的),它虽然很小,但是完全可以正常工作。它非常适合在对空间要求非常严格的嵌入式系统上用作脚本解释器。
-
BusyBox 是一种缩减您下一个嵌入式 Linux 项目内存需求的好方法。
- 要进一步缩减 initrd 文件的大小,请考虑使用 glibc 的替代库,例如 uClibc 或 dietlib。如果您喜欢使用 C++,那么可以试用一下 uClibc++ 库的 Alpha 版本。
-
Minimax 是一个完全封装在 initrd 映像文件中的 Linux 发行版!
-
订购免费的 SEK for Linux,这有两张 DVD,包括最新的 IBM for Linux 的试用软件,包括 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere®。
- 在您的下一个开发项目中采用 IBM 试用软件,这可以从 developerWorks 上直接下载。
相关推荐
Matlab领域上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
该项目包含完整的前后端代码、数据库脚本和相关工具,简单部署即可运行。功能完善、界面美观、操作简单,具有很高的实际应用价值,非常适合作为Java毕业设计或Java课程设计使用。 所有项目均经过严格调试,确保可运行!下载后即可快速部署和使用。 1 适用场景: 毕业设计 期末大作业 课程设计 2 项目特点: 代码完整:详细代码注释,适合新手学习和使用 功能强大:涵盖常见的核心功能,满足大部分课程设计需求 部署简单:有基础的人,只需按照教程操作,轻松完成本地或服务器部署 高质量代码:经过严格测试,确保无错误,稳定运行 3 技术栈和工具 前端:HTML + Vue.js 后端框架:Spring Boot 开发环境:IntelliJ IDEA 数据库:MySQL(建议使用 5.7 版本,更稳定) 数据库可视化工具:Navicat 部署环境:Tomcat(推荐 7.x 或 8.x 版本),Maven
该项目包含完整的前后端代码、数据库脚本和相关工具,简单部署即可运行。功能完善、界面美观、操作简单,具有很高的实际应用价值,非常适合作为Java毕业设计或Java课程设计使用。 所有项目均经过严格调试,确保可运行!下载后即可快速部署和使用。 1 适用场景: 毕业设计 期末大作业 课程设计 2 项目特点: 代码完整:详细代码注释,适合新手学习和使用 功能强大:涵盖常见的核心功能,满足大部分课程设计需求 部署简单:有基础的人,只需按照教程操作,轻松完成本地或服务器部署 高质量代码:经过严格测试,确保无错误,稳定运行 3 技术栈和工具 前端:HTML + Vue.js 后端框架:Spring Boot 开发环境:IntelliJ IDEA 数据库:MySQL(建议使用 5.7 版本,更稳定) 数据库可视化工具:Navicat 部署环境:Tomcat(推荐 7.x 或 8.x 版本),Maven
代码随想录知识星球精华(最强八股文)第五版(算法篇).pdf
该项目包含完整的前后端代码、数据库脚本和相关工具,简单部署即可运行。功能完善、界面美观、操作简单,具有很高的实际应用价值,非常适合作为Java毕业设计或Java课程设计使用。 所有项目均经过严格调试,确保可运行!下载后即可快速部署和使用。 1 适用场景: 毕业设计 期末大作业 课程设计 2 项目特点: 代码完整:详细代码注释,适合新手学习和使用 功能强大:涵盖常见的核心功能,满足大部分课程设计需求 部署简单:有基础的人,只需按照教程操作,轻松完成本地或服务器部署 高质量代码:经过严格测试,确保无错误,稳定运行 3 技术栈和工具 前端:HTML + Vue.js 后端框架:Spring Boot 开发环境:IntelliJ IDEA 数据库:MySQL(建议使用 5.7 版本,更稳定) 数据库可视化工具:Navicat 部署环境:Tomcat(推荐 7.x 或 8.x 版本),Maven
VSG风光储直流微电网simulink仿真 详细效果可以看这个视频 风力发电机组、光伏阵列和燃料电池并联接入直流母线,直流母线连接蓄电池采用恒压控制,并采用固定系数的VSG发出PWM信号控制逆变桥,有功功率指令再1s时变化,无功功率指令在2.1s时变化。 最后得到的结果具有较好的稳定性。 经过测试,在风速变化和光照强度变化时均不会影响稳定性。
内容概要:本文档介绍了如何在Java环境下设置多个项目的联合编译机制,尤其是针对采用Eclipse IDE的情况。首先讲述了配置构建路径以及创建合适的项目结构的关键步骤,确保不同模块间的依赖性和相互引用得到正确处理。然后详细探讨了自动编译器参数配置和解决可能出现的常见错误的方法。 适用人群:适用于初学者及以上水平的Java程序员或者团队负责人,在他们面临复杂的多项目工程管理任务时提供指导。 使用场景及目标:本指南的目标是在实际工作中提升跨模块代码集成效率、缩短产品迭代周期的同时减少潜在的技术债务。具体来说,可以用于大型系统拆分为多个子模块以便并行开发的场景中。 其他说明:虽然本文档主要关注Eclipse平台,但大部分的概念同样适用于其他的IDE工具如IntelliJ IDEA等;此外,关于联合编译过程中遇到的问题排查技巧也有涉及,旨在帮助用户更好地理解和应用相关内容。
你好阿德简答ID卡是你没多久你到家
该项目包含完整的前后端代码、数据库脚本和相关工具,简单部署即可运行。功能完善、界面美观、操作简单,具有很高的实际应用价值,非常适合作为Java毕业设计或Java课程设计使用。 所有项目均经过严格调试,确保可运行!下载后即可快速部署和使用。 1 适用场景: 毕业设计 期末大作业 课程设计 2 项目特点: 代码完整:详细代码注释,适合新手学习和使用 功能强大:涵盖常见的核心功能,满足大部分课程设计需求 部署简单:有基础的人,只需按照教程操作,轻松完成本地或服务器部署 高质量代码:经过严格测试,确保无错误,稳定运行 3 技术栈和工具 前端:HTML + Vue.js 后端框架:Spring Boot 开发环境:IntelliJ IDEA 数据库:MySQL(建议使用 5.7 版本,更稳定) 数据库可视化工具:Navicat 部署环境:Tomcat(推荐 7.x 或 8.x 版本),Maven
pytorch基于LSTM、GRU、BPNN进行时间序列预测源码(高分项目),个人大三大作业设计项目、经导师指导并认可通过的高分设计项目,评审分99分,代码完整确保可以运行,小白也可以亲自搞定,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。 pytorch基于LSTM、GRU、BPNN进行时间序列预测源码(高分项目)pytorch基于LSTM、GRU、BPNN进行时间序列预测源码(高分项目)pytorch基于LSTM、GRU、BPNN进行时间序列预测源码(高分项目)pytorch基于LSTM、GRU、BPNN进行时间序列预测源码(高分项目)pytorch基于LSTM、GRU、BPNN进行时间序列预测源码(高分项目)pytorch基于LSTM、GRU、BPNN进行时间序列预测源码(高分项目)pytorch基于LSTM、GRU、BPNN进行时间序列预测源码(高分项目)pytorch基于LSTM、GRU、BPNN进行时间序列预测源码(高分项目)pytorch基于LSTM、GRU、BPNN进行时间序列预测源码(高分项目)pytorch基于L
安卓游戏-Android studio拼图游戏项目源码+说明(高分期末大作业),个人大三大作业设计项目、经导师指导并认可通过的高分设计项目,评审分99分,代码完整确保可以运行,小白也可以亲自搞定,主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。 安卓游戏-Android studio拼图游戏项目源码+说明(高分期末大作业)安卓游戏-Android studio拼图游戏项目源码+说明(高分期末大作业)安卓游戏-Android studio拼图游戏项目源码+说明(高分期末大作业)安卓游戏-Android studio拼图游戏项目源码+说明(高分期末大作业)安卓游戏-Android studio拼图游戏项目源码+说明(高分期末大作业)安卓游戏-Android studio拼图游戏项目源码+说明(高分期末大作业)安卓游戏-Android studio拼图游戏项目源码+说明(高分期末大作业)安卓游戏-Android studio拼图游戏项目源码+说明(高分期末大作业)安卓游戏-Android studio拼图游戏项目源码+说明(高分期末大作业)
nashorn.jar依赖包
卡通手绘男女结婚礼邀请函模板
自动浇花系统采用51单片机+LCD1602液晶+土壤传感器+继电器+ADC0832+水泵设计而成。 系统三个按键分别是:系统复位键、设置键、加键、减键。 1、土壤干湿度传感器实时给单片机传输信号。 2、按键设置土壤干湿度阈值,实现土壤水分的动态控制。 3、液晶实时显示土壤湿度情况,所设置的阈值,直观明了。 4、ADC0832将模拟信号转换成数字信号传给单片机。 按键调节上下限值,LCD1602实时显示土壤湿度值,并显示上下限值。土壤检测传感器检测湿度值低于下限时,蜂鸣器报警并驱动水泵浇水,湿度值高于上限时停止浇水。
自适应巡航控制,ACC,模型预测控制,MPC,纵向跟车避撞控制为分层式控制,上层控制得到期望加速度,下层控制得到对应的期望制动压力和节气门开度。 上层控制首先建立考虑前车加速度扰动的离散跟车运动学模型,然后建立了基于反馈校正的跟车预测模型,接着引入松弛因子与多目标优化求解,大概几百行MPC代码,最后是基于模糊控制的权重系数调整,这是该模型中最重要的一点,当MPC目标函数中的权重系数取为定值时,难以适应复杂多变的道路交通环境,通过根据跟车性、安全性、舒适性以及经济性的偏重程度来设计相对应的权重系数调整策略,可以改善跟车避撞系统对交通环境的适应性,参考其他文献自己搭建的模糊控制规则得到可变权重,这也是ACC控制不同于网上烂大街的普通ACC控制的独特所在,设置了合理的模糊规则,基本论域、模糊集论域、量化因子,比例因子,调整的权重主要有:车间距误差权重系数q_Δd、两车相对速度权重系数q_vrel和自车加速度权重系数q_ar,而把自车跃度q_jr设置为常量,若q_jr也为变权重系数时会使得模糊控制系统过于复杂,易不稳定。 控制效果:匀速输入时,车间距、相对速度、自车的加速度、跃度、期望制动压力
对应chrome版本:118.0.5993.32 系统环境:win32/64位 内容概述:ChromeDriver.exe是一款实用的chrome浏览器驱动工具,能够用于自动化测试、网络爬虫和操作浏览器,其主要作用是模拟浏览器操作,在使用时需要与对应的chrome浏览器版本匹配,否则无法驱动。 应用场景:网络爬虫、自动化测试、web自动化,例如与Selenium等自动化测试框架一起使用,提供更高级的浏览器自动化,实现自动输入、点击、发送等操作。。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。
Comsol光学 :taper波导传输及倏逝场效率求解
内容概要:本文档详细介绍了用 C 语言开发的一个小型银行排队和VIP管理系统的代码细节与业务流程模拟实现。主要包含了队列数据结构的应用、顾客到达离开、窗口状态管理以及服务质量评估等功能的模块化代码实现。同时提供了基于时间轴的数据统计,比如业务耗时计算和柜台满意度得分。 这个程序通过构建链表、数组来管理窗口及等待队列,并设有主菜单用于指导用户交互如增加新客户入队,显示队列状态查看窗口繁忙程度,顾客办完事后离柜并反馈评价等场景操作。此外特别设计了VIP绿色通道机制确保特定身份客户能够得到优先权处理。它还实现了对不同类别(普通客户、vip)访问次数及每个交易平均处理速度的汇总统计。 该系统旨在提高银行网点的工作效率和服务质量,通过合理的任务分配和技术手段减少顾客不必要的等待成本。整个项目源代码结构清晰注释完善,对于初学者来说是个很好的实战案例可以帮助理解和掌握基本编程技巧尤其是关于数据类型的使用,指针概念理解,结构体运用以及标准库中关于输入/输出流日期时间相关接口调用方法等内容。 最后作者给出了一些额外特性比如屏幕清屏命令改变背景前景文字样式,通过系统命令行调整终端大小以达到良好UI用户体验,同时考虑到实际应用过程中可能遇到的异常情况加入了简单有效的验证机制保障了整体运行稳定性。 适合人群:对数据结构(尤其是线性和链式存储方式)、C语言有一定基础的学习开发者,希望深入探究队列管理和银行服务模型的实际应用案例的研究人员或者有兴趣于金融IT领域的爱好者。 使用场景及目标:该系统的开发不仅有助于加深学员对于计算机科学理论知识的理解——例如抽象数据类型ADT的概念与具体实现形式;而且还能作为金融机构优化客户服务体验的有效工具——通过对营业大厅客流高峰期低谷期变化趋势分析帮助管理层制定更合理的运营政策安排;另外亦可为后续更大规模企业级应用程序架构搭建打下坚实的逻辑思维基础。 其他说明:文中存在部分旧式的iostream头文件引用方式,这是早期版本C++的残留,并非现行规范推荐的做法;此外在面向对象编程兴起之前的背景下该解决方案显得较为朴素缺乏面向对象的设计思想如类封装多态继承等。但无论如何作为一个教学辅助材料来讲还是非常适合用来学习传统的过程驱动型编码模式及其背后的工作原理。
2024具身智能科技前沿热点-中关村智友-2024-32页.pdf
该项目包含完整的前后端代码、数据库脚本和相关工具,简单部署即可运行。功能完善、界面美观、操作简单,具有很高的实际应用价值,非常适合作为Java毕业设计或Java课程设计使用。 所有项目均经过严格调试,确保可运行!下载后即可快速部署和使用。 1 适用场景: 毕业设计 期末大作业 课程设计 2 项目特点: 代码完整:详细代码注释,适合新手学习和使用 功能强大:涵盖常见的核心功能,满足大部分课程设计需求 部署简单:有基础的人,只需按照教程操作,轻松完成本地或服务器部署 高质量代码:经过严格测试,确保无错误,稳定运行 3 技术栈和工具 前端:HTML + Vue.js 后端框架:Spring Boot 开发环境:IntelliJ IDEA 数据库:MySQL(建议使用 5.7 版本,更稳定) 数据库可视化工具:Navicat 部署环境:Tomcat(推荐 7.x 或 8.x 版本),Maven