说明:
        《一》:查看此博文,建议查看笔者上一篇博文(Linux启动过程),因为只有在完全了解Linux系统启动流程及一些配置文件的相关性,在阅读此博文才能有思路,理解起来更容易写。

        《二》:此博文主要讲解如何基于busybox制作一个属于自己的嵌入式Linux系统,及编译安装ngnix软件提供http功能,及利用dropbear提供SSH功能

提示:笔者在书写过程中难免发生书写错误,忘读者提出及谅解,笔者会在第一时间内修改内容。

  1. 基于busybox制作微型嵌入式Linux系统:kernel(编译)+initrd(busybox)+/(busybox)+dropbear(提供SSH功能)
  2. 操作环境表述:
  3. kernel版本:linux-2.6.38.5.tar.bz2(编译安装)-->http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.38.5.tar.bz2
  4. busybox版本:busybox-1.20.2.tar.bz2 --> http://www.busybox.net/downloads/busybox-1.20.2.tar.bz2
  5. dropbear:http://matt.ucc.asn.au/dropbear/dropbear.html/dropbear-2013.56.tar.bz2
  6. busybox介绍:
  7. BusyBox 是一个集成了百多个最常用linux命令和工具的软件。
  8. BusyBox 包含了一些简单的工具(ls、cat、echo、touch......)及复杂的命令(grep、find、mount....)
  9. Busybox最初是由Bruce Perens在1996年为Debian GNU/Linux安装盘编写,简单的说BusyBox就是个百宝箱,它集成压缩了Linux系统中的许多工具和命令。
  10. dropbear(开源软件)介绍:
  11. dropbear是一个相对较小的SSH服务器和客户端软件,运行在一个基于POSIX的各种平台,dropbear实现完整的SSH S/C版本2协议。
  12. 简单说dropbear就是一款开源的轻量级SSH服务软件。(笔者理解)
  13. 实现步骤:
  14. 1、添加一块IDE硬盘(10G),并对其进行分区(/dev/hda1(20M)、/dev/hda2(512M)、/dev/hda3(128M)->将/dev/hda3的文件类型改为82即可)
  15. 文件类型均为ext3(mke2fs -j /dev/hda#),可以参考笔者写的RAID的原理及一步步来实现RAID的创建 (里面有关于创建分区及更改分区文件系统类型案例)
  16. # fdisk /dev/hda (/dev/hda分区)
  17. # partprobe /dev/hda
  18. # mke2fs -j /dev/hda#
  19. 2、创建目录作为/dev/hda1、/dev/hda2挂载点并进行挂载
  20. # mkdir /mnt/{boot,sysroot} -pv
  21. # tree /mnt     ##查看/mnt目录下的所有文件及其子目录
  22. # mount /dev/hda1 /mnt/boot       ##用于Linux启动分区
  23. # mount /dev/hda2 /mnt/sysroot    ##用于Linux根分区
  24. # mount       ##可以使用mount命令查看是否挂载成功
  25. 3、编译内核源代码,作为新系统提供所需的内核(源代码包都位于/usr/src目录中)
  26. # cd  /usr/src
  27. # tar jxvf linux-2.6.38.5.tar.bz2    ##解压源代码这里下载的bzip格式压缩的,所以使用j选项
  28. # ln  -sv  linux-2.6.38.5  linux      ##给linux-2.6.38.5做个软连接其命名为linux
  29. # cd linux
  30. # cp /root/kernel-2.6.38.1-i686.cfg   ./.config  ##kernel-2.6.38.1-i686.cfg(2.6.38系统所使用的模块,可以修改一些模块)
  31. # make menuconfig
  32. 说明:在这里我们将文件系统中的ext3、网卡的驱动程序直接编译进内核,因为笔者使用的是vmware Workstation虚拟机 ,所以网卡类型为pcnet32
  33. # make  SUBDIR=arch/
  34. # cp arch/x86/boot/bzImage  /mnt/boot/  ##将我们编译安装好的内核文件复制到/mnt/boot目录
  35. 4、编译安装busybox(busybox-1.20.2.tar.bz2)
  36. 说明:busybox需要比较新的内核支持头文件中的ubi-user.h,
  37. 所以我们要将这个文件复制到/usr/src/busybox-1.20.2/iniclued/mtd即可
  38. # cd /usr/src
  39. # tar  jxvf  busybox-1.20.2.tar.bz2
  40. # cd  busybox-1.20.2
  41. # mkdir include/mtd
  42. # cp  /usr/src/linux/include/mtd/ubi-user.h  include/mtd/
  43. # make menuconfig    ## 参考“说明”
  44. # make install
  45. 说明:
  46. 1、  此处需要选择 Busybox Settings --> Build Options -->  Build BusyBox as a static binary (no shared libs),这样可以把Busybox编译成一个不使用共享库
  47. 的静态二进制文件,从而避免了对宿主机的共享库产生依赖,但你也可以不选择此项,而完成编译后把其依赖的共享库复制至目标系统上的/lib目录中即可;
  48. 2、  修改安装位置为/mnt/sysroot;方法为:Busybox Settings --> Installation Options --> (./_install) BusyBox installation prefix,
  49. 修改其值为/mnt/sysroot,默认安装在当当前目录,其命名为_install
  50. 说明:安装后的文件均位于/mnt/sysroot目录中,但为了创建initrd(虚拟根文件系统),并实现让其启动以后将真正切换至目标系统分区上的rootfs,
  51. 这里我们创建个临时目录(/tmp/busybox)使用,
  52. # mkdir -pv /tmp/busybox      ##创建临时目录,用于制作虚拟根文件系统
  53. # cp -r /mnt/sysroot/*  /tmp/busybox -a
  54. # cd /tmp/busybox  ##进入临时目录将linuxrc链接文件删除
  55. # mkdir proc sys etc dev mnt/sysroot tmp lib/modules -pv
  56. # vim init
  57. mount -t proc proc /proc
  58. mount -t sysfs sysfs /sys
  59. mdev -s
  60. mount -t ext3 /dev/hda2  /mnt/sysroot
  61. exec  switch_root  /mnt/sysroot  /sbin/init
  62. :wq
  63. # chmod +x init
  64. 3、创建两个必要的设备文件:
  65. # mknod  dev/console  c  5  1
  66. # mknod  dev/null  c  1  3
  67. 4、制作initrd
  68. # find  .  | cpio  --quiet  -H newc  -o  | gzip  -9 -n > /mnt/boot/initrd.gz
  69. 5、建立真正根文件系统(rootfs)
  70. # cd /mnt/sysroot
  71. # mkdir -pv  proc  sys  etc/rc.d/init.d  tmp  dev/pts  boot  var/log  usr/lib
  72. # mknod  dev/console  c  5  1
  73. # mknod  dev/null  c  1  3
  74. # vim etc/rc.d/init.d/functions  ##定义函数用于其它脚本调用(内容如下:)
  75. #!/bin/bash
  76. A=`stty -F /dev/console size &>/dev/null`  ##显示的是我们终端支持横和列,默认(25 80)
  77. lie=${A#* }
  78. [ -z $lie ] && lie=80
  79. space=$[$lie-14]
  80. RED='\033[31m'
  81. GREEN='\033[32m'
  82. NORMAL='\033[0m'
  83. success() {
  84. string=$1
  85. RT_SPA=$[$space-${#string}]
  86. echo -n "$string"
  87. for I in `seq 1 $RT_SPA`;do
  88. echo -n " "
  89. done
  90. echo -e "[  ${GREEN}OK${NORMAL}  ]"
  91. }
  92. failure() {
  93. string=$1
  94. RT_SPA=$[$space-${#string}]
  95. echo -n "$string"
  96. for I in `seq 1 $RT_SPA`;do
  97. echo -n " "
  98. done
  99. echo -e "[  ${RED}FAILED${NORMAL}  ]"
  100. }
  101. :wq
  102. # chmod +x etc/rc.d/init.d/functions
  103. 创建系统初始化rc.sysinit脚本
  104. # vim  etc/rc.d/rc.sysinit
  105. #!/bin/bash
  106. echo -e "\tWelcome to  \033[31mMageEdu\033[0m Linux"
  107. . /etc/rc.d/init.d/functions              ##读取functions函数到etc/rc.d/rc.sysinit
  108. success "Remounting the root filesystem ..."
  109. mount -t proc proc /proc
  110. mount -t sysfs sysfs /sys
  111. mount -o  remount,rw  /
  112. mdev -s
  113. success "Creating the files of device ..."
  114. mount -a
  115. swapon -a
  116. success "Mounting the filesystem ..."
  117. syslogd
  118. klogd
  119. success "Starting the log daemon ..."
  120. ifconfig  lo  127.0.0.1/24
  121. ifconfig eth0 172.16.100.9/16
  122. success "Configuring loopback interface ..."
  123. :wq
  124. # chmod +x etc/rc.d/rc.sysinit
  125. 6、配置init及其所需要inittab文件
  126. # cd  /tmp/busybox
  127. # rm  -f  linuxrc
  128. # vim  etc/inittab
  129. 添加如下内容:
  130. ::sysinit:/etc/rc.d/rc.sysinit
  131. console::respawn:-/bin/sh
  132. ::ctrlaltdel:/sbin/reboot
  133. ::shutdown:/bin/umount -a -r
  134. :wq
  135. 7、为系统准备一个“文件系统表”配置文件/etc/fstab
  136. # vim  etc/fstab
  137. 添加如下内容:
  138. sysfs                   /sys                    sysfs   defaults        0 0
  139. proc                    /proc                   proc    defaults        0 0
  140. /dev/hda1               /boot                   ext3    defaults        0 0
  141. /dev/hda2               /                       ext3    defaults        1 1
  142. :wq
  143. 8、下面就可以为系统创建所需的引导程序grub了
  144. # grub-install  --root-directory=/mnt  /dev/hda
  145. 9、为grub建立配置文件,让系统引导grub所定义的配置文件:
  146. # vim  /mnt/boot/grub/grub.conf
  147. 添加如下内容:(这里只做了简单的定义)
  148. default=0           ## 设定默认启动的title的编号,从0开始
  149. timeout=3           ## 等待用户选择的超时时长,单位是秒
  150. title   MyLinx system (2.6.38.5)          ## 内核标题,或操作系统名称,字符串,可自由修改
  151. root (hd0,0)    # 内核文件所在的设备;对grub而言,所有类型硬盘一律hd,格式为(hd#,N);hd#, #表示第几个磁盘;最后的N表示对应磁盘的分区;
  152. kernel /bzImage ro root=/dev/hda2 quiet        # 内核文件路径,及传递给内核的参数
  153. initrd /initrd.gz         ##这是我们给予busybox制作的虚拟根文件系统
  154. :wq
  155. 现在我们来做个测试:
  156. 说明:
  157. 这里我们的实验环境用的vmware Workstation,所以我们重新创建个虚拟机:步骤如下:
  158. 点击:File->New Virtual Machine..(ctrl+n)->Custom(advanced)->Next->(default)Next->(default)Next->更改Guest opevating system选项改为linux,然后将
  159. Version版本改为Red Hat Enterprise Linux 5 ->Next->保持默认也可作相应的设置->Next->设置内存为64即可->选择桥接方式(这里我们使用第一选项)->Next->
  160. 选择硬盘,这里我们选择第二选项(就是已存在的磁盘)-Next->浏览我们虚拟机添加的那块IDE硬盘即可->Finish
  161. 下面我们来做下扩张内容:
  162. 1、为新构建的微型Linux启用虚拟控制台
  163. # cd /mnt/sysroot
  164. 将 etc/inittab文件改为如下内容:
  165. ::sysinit:/etc/init.d/rc.sysinit
  166. tty1::askfirst:/bin/sh
  167. tty2::askfirst:/bin/sh
  168. tty3::askfirst:/bin/sh
  169. tty4::askfirst:/bin/sh
  170. tty5::askfirst:/bin/sh
  171. tty6::askfirst:/bin/sh
  172. ::ctrlaltdel:/sbin/reboot
  173. ::shutdown:/bin/umount -a -r
  174. :wq
  175. 注:因为我们使用的是busybox制作的根文件系统,所以关于init所使用的配置文件/etc/inittab的格式有所不同。
  176. 2、已经实现了虚拟控制台,但其仍是直接进入系统,且系统没有用户帐号等安全设施,所以接下来的工作就是实现为系统用户添加账号(以root为例)
  177. 我们知道关于用户都会设置到一下文件:
  178. /etc/passwd
  179. /etc/group
  180. /etc/shadow
  181. 步骤如下:
  182. (1)、为目标主机建立passwd帐号文件
  183. # cd /mnt/sysroot
  184. # vim etc/passwd
  185. 添加如下内容:
  186. root:x:0:0::/root:/bin/sh
  187. :wq
  188. # mkdir root    ##为root用户创建“家”目录:
  189. (2)、为目标主机建立group帐号文件
  190. # vim  etc/group
  191. 添加如下内容:
  192. root:x:0:
  193. :wq
  194. (3)、为目标主机建立shadow影子口令文件,这里采用直接复制宿主机的shadow文件中关于root口令行的行来实现
  195. # grep  "^root"  /etc/shadow  > etc/shadow
  196. 注:等目标主机启动时,root用户的口令也是宿主机的root用户的口令。您可以在目标主机启动以后再动手更改root用户的口令。
  197. 更改口令命令为:
  198. # passwd
  199. 这样就是可以实现用户的登陆:
  200. 下面我们在进一步扩展,让我们真正了解linux的启动流程
  201. 注:一下更改就在宿主机上完成
  202. 1、为系统登录时提供banner信息
  203. 注:我们知道提供banner信息所使用的配置文件为/etc/issue,直接在/mnt/sysroot/etc/创建issue文件
  204. 这个可以通过宿主机来实现,也可以直接在目标主机上进行配置。
  205. # vi  /etc/issue
  206. 添加如下内容:
  207. Welcome to http://www.magedu.com   ##欢迎信息
  208. Kernel \r
  209. 注:这里的内容可以根据你的需要显示的内容进行修改相应修改
  210. 2、在系统启动时为系统提供主机名称:
  211. (1)、创建保存主机名称的配置文件
  212. # mkdir /etc/sysconfig
  213. # vi  /etc/sysconfig/network
  214. 添加如下内容:
  215. HOSTNAME=www.magedu.com
  216. :wq
  217. (2)、编辑系统初始化脚本,实现开机过程中设定主机名称
  218. # vi /etc/init.d/rc.sysinit
  219. 添加如下内容:
  220. HOSTNAME=
  221. [ -e  /etc/sysconfig/network  && -r /etc/sysconfig/network ] && . /etc/sysconfig/network
  222. [ -z ${HOSTNAME} ] && HOSTNAME="localhost"
  223. /bin/hostname  ${HOSTNAME}
  224. :wq
  225. 这样,我们的制作的微型嵌入式Linux系统就完善了许多。
  226. 下面,我们使用dropbear软件实现远程SSH连接(SHH2)
  227. 1、通过dropbear为系统提供ssh远程连接服务
  228. 1、编译安装dropbear
  229. # cd /usr/src
  230. # tar xf dropbear-2013.56.tar.bz2
  231. # cd dropbear-2013.56
  232. # ./configure
  233. # make
  234. # make install
  235. 2、移植dropbear至目标系统
  236. 下面我们来写一个脚本,脚本功能实现二进制程序及二进制文件所依赖的库文件复制到/mnt/syroot/bin及/mnt/sysroot/lib目录中,脚本如下:
  237. #!/bin/bash
  238. #
  239. read -t 30 -p "Target System Directory[/mnt/sysroot]: " DEST
  240. DEST=${DEST:-/mnt/sysroot}
  241. libcp() {
  242. LIBPATH=${1%/*}    ##截取机名   如/bin/bash 所显示的结果为bash
  243. [ ! -d $DEST$LIBPATH ] && mkdir -p $DEST$LIBPATH
  244. [ ! -e $DEST${1} ] && cp $1 $DEST$LIBPATH && echo "copy lib $1 finished."
  245. }
  246. #判读目录是否存在,如果不存在则创建,存在将二进制命令复制到相对目录下
  247. bincp() {
  248. CMDPATH=${1%/*}
  249. [ ! -d $DEST$CMDPATH ] && mkdir -p $DEST$CMDPATH
  250. [ ! -e $DEST${1} ] && cp $1 $DEST$CMDPATH
  251. ## 判断我们输入的命令所依赖的库目录是否存在,不存在则创建,存在则执行复制工作。
  252. for LIB in  `ldd $1 | grep -o "/.*lib\(64\)\{0,1\}/[^[:space:]]\{1,\}"`; do
  253. libcp $LIB
  254. done
  255. }                   ##使用ldd命令常看二进制程序所用到的库文件,并执行复制工作
  256. read -p "Your command: " CMD
  257. until [ $CMD == 'q' ]; do
  258. ! which $CMD && echo "Wrong command" && read -p "Input again:" CMD && continue
  259. COMMAND=` which $CMD | grep -v "^alias" | grep -o "[^[:space:]]\{1,\}"`
  260. bincp $COMMAND
  261. echo "copy $COMMAND finished."
  262. read -p "Continue: " CMD
  263. done          ##调用bincp函数来执行操作
  264. # chmod +x bincp.sh(脚本名称)
  265. 好了,接下来就运行bincp.sh脚本将,输入dropbear、dropbearkey和dbclient即可;这些命令会被存储于目标系统的/usr/local/sbin或/usr/local/bin目录中。
  266. 3、为远程登录的用户提供伪终端设备文件
  267. # vim /mnt/sysroot/etc/fstab,添加如下一行:
  268. devpts      /dev/pts        devpts  mode=620    0 0
  269. :wq
  270. 创建所需要的目录:
  271. # mkdir /mnt/sysroot/dev/pts
  272. 4、为目标系统的dropbear生成主机密钥
  273. 默认情况下,dropbear到/etc/dropbear目录中查找使用的rsa格式主机密钥(默认名称为dropbear_rsa_host_key)和dss格式的主机密钥
  274. (默认名称为dropbear_dss_host_key)。其中,rsa格式可使用不同长度的密钥,但dss格式只使用1024位的密钥。
  275. # mkdir /mnt/sysroot/etc/dropbear
  276. # dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key -s 2048
  277. # dropbearkey -t rsa -f /etc/dropbear/dropbear_dss_host_key
  278. 在生成rsa格式的key时,其长度指定部分-s 2048可以省略,也可以为其指定为其它长度,但长度需要为8的整数倍。
  279. 说明:此步骤也可以在目标主机上进行,但路径要做相应的修改。
  280. 5、定义安全shell
  281. 安全起见,dropbear默认情况下仅允许其默认shell出现在/etc/shells文件中的用户远程登录,因此,这里还需要创建/etc/shells文件,并添加所有允许的shell。
  282. # cat >> /mnt/sysroot/etc/shells << EOF
  283. /bin/sh
  284. /bin/ash
  285. /bin/hush
  286. /bin/bash
  287. EOF
  288. 6、为目标主机提供网络服务转换机制
  289. 在宿主机上使用默认选项编译的dropbear将依赖nsswitch实现用户名称解析,因此,还需要为目标主机提供nss相关的库文件及配置文件。
  290. # cat >> /mnt/sysroot/etc/nsswitch.conf << EOF
  291. passwd:     files
  292. shadow:     files
  293. group:      files
  294. hosts:      files dns
  295. EOF
  296. 复制所需要的库文件:
  297. # cp -d /lib/libnss_files*  /mnt/sysroot/lib/
  298. # cp -d /usr/lib/libnss3.so /usr/lib/libnss_files.so /mnt/sysroot/usr/lib/
  299. 7、由于在rc.sysinit文件中启动了日志进程,因此系统在运行中会产生大量日志并将其显示于控制台;
  300. # vim  etc/syslog.conf
  301. 添加如下一行:
  302. *.info    /var/log/messages
  303. :wq
  304. 说明: 由于在rc.sysinit文件中启动了日志进程,因此系统在运行中会产生大量日志并将其显示于控制台;
  305. 这将会经常性的打断正在进行的工作,为了避免这种情况,我们这里为日志进程建立配置文件,为其指定将日志发送至/var/log/messages文件;
  306. 8、测试
  307. 启动目标主机,设定好网络属性后,使用如下命令启动dropbear服务即可。
  308. # /usr/local/sbin/dropbear
  309. 接下来就可以远程进行连接测试了。
  310. 接下来我们实现一个基于nginx软件,来为我们制作的微型Linux系统提供www服务
  311. 通过nginx提供web服务
  312. 1、在宿主机编译安装nginx-1.2.5
  313. # tar nginx-1.2.5.tar.gz
  314. # cd nginx-1.2.5
  315. # ./configure --prefix=/usr/local --conf-path=/etc/nginx/nginx.conf  --error-log-path=/var/log/nginx/error.log --user=nginx --group=nginx --http-log-path=/var/log/nginx/access.log  --without-pcre --without-http_rewrite_module --without-http_geo_module --without-http_fastcgi_module  --without-http_uwsgi_module  --without-http_scgi_module --without-http_memcached_module --without-http_upstream_ip_hash_module --without-http_upstream_least_conn_module  --without-http_upstream_keepalive_module --http-log-path=/var/log/nginx
  316. # make
  317. # make install
  318. 2、移植nginx至目标系统
  319. (1) 移植二进制程序及其依赖的库文件,方能实现其在目标系统上正常运行。建议使用前面的bincp.sh脚本进行。
  320. (2) 移植配置文件至目标系统
  321. # mkdir  /mnt/sysroot/etc/nginx/
  322. # cp /etc/nginx/{nginx.conf,mime.types}  /mnt/sysroot/etc/nginx/
  323. (3) 移植测试页面至目标系统,当然,也可以不采用下面的步骤而在目标系统上直接创建。
  324. # mkdir /mnt/sysroot/usr/local/
  325. # cp -r /usr/local/html  /mnt/sysroot/usr/local/
  326. 3、测试
  327. 启动目标主机,首先配置好网络属性,并使用adduser为其添加nginx用户和nginx组。
  328. 然后使用如下命令启动nginx
  329. # /usr/local/nginx
  330. 测试命令
  331. #elinks IPADDR即可在我们制作的LINUX系统上进行测试啦。

转载于:https://blog.51cto.com/guodayong/1168743

详解基于busybox、dropbear、ngnix制作完整的嵌入式Linux系统相关推荐

  1. android 远程视频监控程序源码,详解基于Android已开放源代码的远程视频监控系统教程...

    网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket.Socket的英文原义是"孔"或"插座".通常也称作"套接字 ...

  2. 【正点原子Linux连载】第三十一章 U-Boot顶层Makefile详解 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

    1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...

  3. 【正点原子Linux连载】第三十五章 Linux内核顶层Makefile详解 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

    1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...

  4. 【正点原子Linux连载】第三十二章 U-Boot启动流程详解 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

    1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...

  5. Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(一)

    Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(一) 本文目录: 一.[旋转的精灵女孩]案例运行效果 二.Three.js简介 三.Three.js代码正常运行显示条件 (1)不载入 ...

  6. python selenium爬虫_详解基于python +Selenium的爬虫

    详解基于python +Selenium的爬虫 一.背景 1. Selenium Selenium 是一个用于web应用程序自动化测试的工具,直接运行在浏览器当中,支持chrome.firefox等主 ...

  7. 《嵌入式Linux软硬件开发详解——基于S5PV210处理器》——1.2 S5PV210处理器

    本节书摘来自异步社区<嵌入式Linux软硬件开发详解--基于S5PV210处理器>一书中的第1章,第1.2节,作者 刘龙,更多章节内容可以访问云栖社区"异步社区"公众号 ...

  8. OSPFv2原理详解(基于RFC2328)+配置介绍+RFC2328翻译

    个人认为,理解报文就理解了协议.通过报文中的字段可以理解协议在交互过程中相关传递的信息,更加便于理解协议. 虽然路由器自身可以对协议做一些独特的配置,但是报文仍然是协议的核心.例如,OSPF的完全末节 ...

  9. 算法经典“钓鱼”问题详解 基于贪心算法 C语言描述

    算法经典"钓鱼"问题详解 基于贪心算法 初始条件 在一条水平路边,有 n 2 ≤ n ≤ 25个钓鱼池,从左到右编号为1.2.3.--.n.小明有H1 ≤ H ≤ 16个小时的空余 ...

最新文章

  1. Jquery 将表单序列化为Json对象
  2. 第1章 Java语言概述
  3. mysql将字符转换成数字
  4. 疫情撬动游戏产业“底层认知”,正向价值愈发突显
  5. 教师查询系统C语言,教师管理系统c语言版
  6. 经典C语言程序100例之三零
  7. 在redhat6.3 安装oracle 11.2.0.1遇到的错误
  8. build.gradle里repositories的mavenCentral实现原理解析
  9. 程序员的算法课(11)-KMP算法
  10. 栈在表达式求值中的应用
  11. 2021年,对话系统该如何学?
  12. 技术博客2013年2月份头条记录
  13. 帆软FineMobile 自适应
  14. android 反编译 dex2jar,Android反编译教程:apktool,dex2jar的使用
  15. 【数值分析】python实现复化高斯积分
  16. 将内存FFFF:0 ~ FFFF:F 内存单元中的数据复制到 0:200 ~ 0:20F 中
  17. Pr 视频速率与关键帧
  18. BasicVSR++: Improving Video Super-Resolution with Enhanced Propagation and Alignment阅读笔记
  19. 团队项目(2.1) -- 飞机躲避小游戏
  20. 数字图像处理(16): 图像颜色空间转换 和 OpenCV图像灰度化处理

热门文章

  1. http响应Last-Modified和ETag以及Apache和Nginx中的配置
  2. 让Squid 显示本地时间
  3. 文本的DES加密 MD5散列值 DSA的数字签名
  4. SpringMVC集成Tiles布局引擎框架
  5. 在Ubuntu上编译opencv 2.4.13源码支持android平台操作步骤
  6. FFmpeg中一个线程获取视频流一个线程执行scale测试代码
  7. BP神经网络公式推导及实现(MNIST)
  8. 【FFmpeg】ffmpeg工具源码分析(二):转码核心函数 transcode
  9. 【摄像头】摄像头IRCUT滤光片
  10. 【Linux】修改/etc/fstab时参数设错,导致启动异常,无法进入系统(已解决)