# 一、根文件系统简介
Linux系统三大块:U-boot、kernel以及最后这个rootfs,跟文件系统。在kernel中,启动流程的最后会调用 prepare_namespace 函数,挂载根文件系统,这里就是挂载的本篇要说的。
根文件系统保存了内核代码映射文件,并对它们进行组织,方便用户与操作系统进行交互。但嵌入式里的内核代码保存在flash专用分区里面。内核会调用根文件系统的脚本文件进行初始化操作,如果没有根文件系统,则会出现内核崩溃。
首先,我们要了解一个根文件系统的结构,这才是以后经常打交道的对象,下面是常用的目录:
这些是本人经常看的目录,其它的基本没怎么用,如果有兴趣可以自己查下。
根文件系统搭建是一个很麻烦很麻烦很麻烦的事,这些文件夹你可以一个个从网上下,哈哈哈哈,但是有专门的工具帮我们搭建。下面是几种常用的搭建方式。
busybox是最简单的搭建工具,但它也集成了大量的 Linux命令和工具的软件,像 ls、 mv、 ifconfig,可以搭建一个最小的根文件系统。
busybox下载官网:https://busybox.net/,简陋的一批。
左面那一块,Get BusyBox里面第一个,点开,里面是各种版本:
这里本人不建议用最新版的,还是倒退一两个版本比较好。
下载后解压,然后在Makefile里面改一下ARCH ?= arm 和 CROSS_COMPILE = 交叉编译器路径。
接着 make menuconfig 进行配置,这些配置务必要进行:
Location:
-> Settings
-> [ ] Build static binary (no shared libs)
Location:
-> Settings
-> [*] vi-style line editing commands
Location:
-> Linux Module Utilities
-> [ ] Simplified modutils
Location:
-> Linux System Utilities
-> [*] mdev (16 kb) //确保下面的全部选中,默认都是选中的
Location:
-> Settings
-> [*] Support Unicode
-> [*] Check $LC_ALL, $LC_CTYPE and $LANG environment variables
最后编译安装,指定路径
make
make install CONFIG_PREFIX=这里是路径
ok 还没完,虽然busybox搭建完了,可,还有特别多库需要移植才能用,接下来需要移植busybox的库。
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib
export PATH LD_LIBRARY_PATH
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s
#<file system> <mount point> <type> <options> <dump> <pass>
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
#etc/inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
可以看出,busybox的搭建还是很麻烦的,下面写一下buildroot这种搭建,这个也是我目前用的搭建方法,效果还不戳。
首先嘞,先下一个buildroot的安装包,然后嘞,解压呀,再然后嘞,进到目录里面,打开终端。输入make menuconfig
打开图形化配置界面,然后进行如下系列配置:
Target options
-> Target Architecture = ARM (little endian)
-> Target Binary Format = ELF
-> Target Architecture Variant = cortex-A7
-> Target ABI = EABIhf
-> Floating point strategy = NEON/VFPv4
-> ARM instruction set = ARM
Toolchain
-> Toolchain type = External toolchain
-> Toolchain = Custom toolchain //用户自己的交叉编译器
-> Toolchain origin = Pre-installed toolchain //预装的编译器
-> Toolchain path =/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf
-> Toolchain prefix = $(ARCH)-linux-gnueabihf //前缀
-> External toolchain gcc version = 4.9.x
-> External toolchain kernel headers series = 4.1.x
-> External toolchain C library = glibc/eglibc
-> [*] Toolchain has SSP support? (NEW) //选中
-> [*] Toolchain has RPC support? (NEW) //选中
-> [*] Toolchain has C++ support? //选中
-> [*] Enable MMU support (NEW) //选中
System configuration
-> System hostname = alpha_imx6ull //平台名字,自行设置
-> System banner = Welcome to alpha i.mx6ull //欢迎语
-> Init system = BusyBox //使用 busybox
-> /dev management = Dynamic using devtmpfs + mdev //使用 mdev
-> [*] Enable root login with password (NEW) //使能登录密码
-> Root password = 123456 //登录密码为 123456
然后返回到终端,输入make (如果make错误,再试试sudo make 我个人不太喜欢sudo make 权限很烦人),有时候会遇到半天下载很慢的,在图中那个位置可以找到那个下载网址,再跑到windows下下载。
前面是搭建最小系统的方法,其它第三方软件buildroot也含有,这里建议先搭建个最小的,后面搭建其它的也可能会出现各种意外错误,其它软件添加在:Target packages 里面找,也可以直接按 / 全局搜索,有的软件安装是有依赖的,每次添加完编译都需要先输入 sudo make clean all,再编译,所以建议一次性添加完。
这里直接放一个之前写过的链接吧,没写完,因为最后家里网不行,东西就是下不下来,由于不可描述原因,外网是别想了。
这个我也用过,但是后面不知道为什么,用过一段时间后,网络挂载就挂不上了,搞得我很心累,唉,先记下来,万一什么时候知道原因了再来改一下,下面先描述一下大致的搭建过程。
首先嘞,先下一个ubuntu-base的安装包,ubuntu版本提供很多,记得别选错,然后嘞,解压呀,再然后,安装 qemu工具,命令:sudo apt-get install qemu-user-static
将刚刚安装的 qemu-user-static拷贝到刚刚解压出来的 ubuntu base目录中,也就是ubuntu_rootfs/usr/bin目录下,命令如下:
cd /home/zuozhongkai/linux/nfs/ubuntu_rootfs //进入到 ubuntu_rootfs目录下
sudo cp /usr/bin/qemu-arm-static ./usr/bin/ //拷贝 qemu-arm-static
用过ubuntu的都知道,apt软件管理工具需要提供一个软件源,这个源在 /etc/resolv.conf 下,但是arm架构和X86架构的源是不一样的,所以在网上应该找ARM源,一般情况下ARM源的网址比X86源多了一个-ports,例如:
X86架构阿里源
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
ARM架构阿里源
deb http://mirrors.aliyun.com/ubuntu-ports/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu-ports/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu-ports/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu-ports/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu-ports/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu-ports/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu-ports/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu-ports/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu-ports/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu-ports/ bionic-backports main restricted universe multiverse
换源的同时也需要注意,不同版本的Ubuntu源是不一样的,要找对应版本的源。
源确定后就要在主机挂载并配置根文件系统,脚本如下:
#!/bin/bash
echo "MOUNTING"
sudo mount -t proc /proc /ubuntu-base根目录/proc
sudo mount -t sysfs /sys /ubuntu-base根目录/sys
sudo mount -o bind /dev /ubuntu-base根目录/dev
sudo mount -o bind /dev/pts /ubuntu-base根目录/dev/pts
sudo chroot /ubuntu-base根目录
卸载脚本如下:
#!/bin/bash
echo "UNMOUNTING"
sudo umount /ubuntu-base根目录/proc
sudo umount /ubuntu-base根目录/sys
sudo umount /ubuntu-base根目录/dev/pts
sudo umount /ubuntu-base根目录/dev
挂载后,输入以下安装指令:
apt update
apt install language-pack-en-base
apt install sudo
apt install vim
apt install kmod
apt install net-tools
apt install ethtool
apt install ifupdown
apt install rsyslog
apt install htop
apt install iputils-ping
然后执行卸载脚本,就完成了。
APT下载工具可以实现软件自动下载、配置、安装二进制或者源码的功能。 APT下载工具和“ install”命令结合在一起构成了 Ubuntu下最常用的下载和安装软件方法。它解决了 Linux平台下安装软件的一个缺陷,即软件之间相互依赖。
APT采用的 C/S模式,也就是客户端 /服务器模式,我们的 PC机作为客户端,当需要下载软件的时候就向服务器请求,因此我们需要知道服务器的地址,也叫做安装源或者更新源。更新源的方法见ubuntu构建里面,但是不同的系统软件管理工具是不一样的,ubuntu操作系统的是apt,cantos的是yum等等。
下面大致讲一下APT的使用:
操作系统一般会带有VI(自已没移植当我没说),但是有时候会出现上下左右出来的却是wsad,这里还需要重新安装一些vim解决:
sudo apt-get install vim
VIM编辑器有 3种工作模式:输入模式、指令模式和底行模式,通过切换不同的模式可以完成不同的功能。当用vim打开一个文件的时候,默认指令模式,是无法编辑的,输入以下指令可以进入编辑模式:
i 在当前光标所在字符的前面,转为输入模式。
I 在当前光标所在行的行首转换为输入模式。
a 在当前光标所在字符的后面,转为输入模式。
A 在光标所在行的行尾,转换为输入模式。
o 在当前光标所在行的下方,新建一行,并转为输入模式。
O 在当前光标所在行的上方,新建一行,并转为输入模式。
s 删除光标所在字符。
r 替换光标处字符。
但是需要注意的是,编辑的时候,会下意识按Ctrl+S保存,但是VIM下会进入锁屏,选哟按下Ctrl+Q退出。退出编辑模式的方法是按下ESC,回到指令模式。
1、移动光标指令:
h(或左方向键 ) 光标左移一个字符。
l(或右方向键 ) 光标右移一个字符。
j(或下方向键 ) 光标下移一行。
k(或上方向键 ) 光标上移一行。
nG 光标移动到第 n行首。
n+ 光标下移 n行。
n- 光标上移 n行。
2、屏幕翻滚指令
Ctrl+f 屏幕向下翻一页,相当于下一页。
Ctrl+b 屏幕向上翻一页,相当于上一页。
3、复制、删除和粘贴指令
cc 删除整行,并且修改整行内容。
dd 删除该行,不提供修改功能。
ndd 删除当前行向下 n行。
x 删除光标所在的字符。
X 删除光标前面的一个字符。
nyy 复制当前行及其下面 n行。
p 粘贴最近复制的内容。
在指令模式下输入“:”进入底行模式,底行常用的命令如下:
x 保存当前文档并且退出。
q 退出。
w 保存文档。
q! 退出 VI/VIM,不保存文档。
另外可以通过 “/ ” 进入另一种底行模式,搜索模式,这样就可以在全局搜索需要查找的内容了。
简单的说 Shell就是敲命令。国内把 Linux下通过命令行输入命令叫做“敲命令”,国外人玩的比较洋气,人家叫做“ Shell”。因此以后看到 Shell这个词语第一 反应就是在终端中敲命令,将多个Shell命令按照一定的格式放到一个文本中,那么这个文本就叫做 Shell脚本。
Shell命令的格式如下:
command -options [argument]
command: Shell命令名称。
options:选项,同一种命令可能有不同的选项,不同的选项其实现的功能不同。
argument Shell命令是可以带参数的,也可以不带参数运行。
对于shell命令,这里有一个不错的博客,博主收集了很多指令并按类分好,可以查看。
什么是Shell脚本:
Shell脚本(英语:Shell script),又称Shell命令稿、程序化脚本,是一种电脑程序与文本文件,内容由一连串的shell命令组成,经由Unix Shell直译其内容后运作。被当成是一种脚本语言来设计,其运作方式与直译语言相当,由Unix shell扮演命令行解释器的角色,在读取shell脚本之后,依序运行其中的shell命令,之后输出结果。利用shell脚本可以进行系统管理,文件操作等。
#!/bin/sh
cd ~
mkdir shell_tut
cd shell_tut
for ((i=0; i<10; i++)); do
touch test_$i.txt
done
# 定义变量
name="xxx"
# 使用变量
$name
${name} # 花括号指明边界,因为有的场合变量后面也有字符
# 重定义变量
name="xxx" # 定义
name="nnn" # 重定义
# 注释以#开头,没有多行注释,只能一行行加#
# 字符串
# 单引号
str='this is a string'
# 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
# 单引号字串中不能出现单引号(对单引号使用转义符后也不行)
# 双引号
str="Hello, I know your are \"$your_name\"! \n"
# 双引号里可以有变量
# 双引号里可以出现转义字符
# 字符串操作
# 拼接字符串
name="xxx"
greeting="hello, "$name" !"
greeting_1="hello, ${name} !"
echo $greeting $greeting_1
# 获取字符串长度:
string="abcd"
echo ${#string} #输出:4
# 提取子字符串
string="alibaba is a great company"
echo ${string:1:4} #输出:liba
# 查找子字符串
string="alibaba is a great company"
echo `expr index "$string" is`#输出:8,这个语句的意思是:找出单词is在这名话中的位置