Linux:宿主机与目标机的tftp和nfs环境搭建

宿主机(Ubuntu)配置交叉编译环境

  • Ubuntu装的是64位的,交叉编译工具一般是32位的,所以要安装一些库
sudo apt-get install u-boot-tools
sudo apt-get install lib32z1
sudo apt-get install lib32ncurses5
sudo apt-get install libncurses5-dev libncursesw5-dev
sudo apt-get install lib32stdc++6
sudo apt-get install libc6-dev
  • 安装SSH
sudo apt-get install openssh-server
sudo /etc/init.d/ssh start
  • 安装交叉编译工具
sudo tar -jxvf arm-linux-gcc-4.3.2.tar.bz2 –C /

参考博客:https://blog.csdn.net/qq_24601427/article/details/102983794

  • 交叉编译工具下的bin目录添加到环境变量
#临时设置
export PATH=$PATH:交叉编译器路径
#修改全局配置
sudo vim /etc/profile
#修改用户配置文件
#通常是“~/.bashrc”或者“~/.bash_profile” 或者 “~/.profile”

安装和配置TFTP

TFTP

  • 安装
#tftp-hpa是客户端,tftpd-hpa是服务器端
sudo apt-get install tftp-hpa tftpd-hpa
  • 配置
#创建共享目录
sudo mkdir /tftproot
#修改权限
sudo chmod 777 /tftproot
  • 修改tftp服务器配置文件
sudo vim /etc/default/tftpd-hpa3
#添加如下内容
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftproot" #修改为需要的路径
TFTP_OPTIONS="-l -c -s" #通过mantftpd查看各种参数的意义
TFTP_DIRECTORY="/srv/tftp"
  • 重启tftp,使其配置生效
sudo service tftpd-hpa restart
  • 本地测试
$cd ~/tftpboot echo "hello tftp service">>a.txt
$echo "hello tftp service,put to tftp serive">>b.txt
$tftp localhost
tftp> get a.txt
tftp> put b.txt
tftp> quit 
#其中get是取得文件,put是将文件上传到TFTP服务器上

xinetd和TFTP

  • 安装
#xinetd是新一代的网络守护进程服务程序
sudo apt-get install xinetd
sudo apt-get install tftp tftpd
  • 配置
vi /etc/xinetd.d/tftp
#使用命令:"vi /etc/xinetd.d/tftp"建立TFTP配置文件
#向文件中写入如下代码
#必须按照格式严格对齐
server tftp
{
    socket_type = dgram
    protocol = udp
     wait = yes
    user = root
    server = /usr/sbin/in.tftpd
    server_args = -s /tftproot
    disable = no
    per_source = 11
    cps = 100 2
    flags = IPv4
}
#server_args设置的/var/tftproot目录是tftp服务器的目录
  • 重启xinetd服务
sudo /etc/init.d/xinetd restart

安装和配置NFS

安装NFS服务端

  • 安装
#服务端
sudo apt install nfs-kernel-server
  • 创建共享目录
sudo mkdir -p /tmp
sudo mkdir -p /data
sudo mkdir -p /logs
  • nfs配置
#编辑/etc/exports 文件
sudo vim /etc/exports
#添加内容
/tmp *(rw,sync,no_subtree_check,no_root_squash)
/data *(rw,sync,no_subtree_check,no_root_squash)
/logs *(rw,sync,no_subtree_check,no_root_squash)
#/home   :共享的目录
#*       :指定哪些用户可以访问
#            *  所有可以ping同该主机的用户
#            192.168.1.*  指定网段,在该网段中的用户可以挂载
#            192.168.1.12 只有该用户能挂载
#(ro,sync,no_root_squash):  权限
#        ro : 只读
#        rw : 读写
#        sync :  同步
#        no_root_squash: 不降低root用户的权限
#    其他选项man 5 exports 查看
  • 重启NFS服务
sudo /etc/init.d/nfs-kernel-server restart
  • 常用命令工具
#显示已经mount到本机nfs目录的客户端机器。
sudo showmount -e localhost
#将配置文件中的目录全部重新export一次!无需重启服务。
sudo exportfs -rv
#查看NFS的运行状态
sudo nfsstat
#查看rpc执行信息,可以用于检测rpc运行情况
sudo rpcinfo
#查看网络端口,NFS默认是使用111端口。
sudo netstat -tu -4

安装NFS客户端

  • 安装
#客户端
sudo apt install nfs-common
  • 查看NFS服务器上的共享目录
#显示指定的(192.168.3.167)NFS服务器上export出来的目录
sudo showmount -e 192.168.3.167
  • 创建本地挂载目录
sudo mkdir -p /mnt/data
sudo mkdir -p /mnt/logs
  • 挂载共享目录
#将NFS服务器192.168.3.167上的目录,挂载到本地的/mnt/目录下
sudo mount -t nfs 192.168.3.167:/data /mnt/data
sudo mount -t nfs 192.168.3.167:/logs /mnt/logs

目标机启动运行

参考博客

系统文件区别

  1. linux内核经过编译后会生成一个elf格式的可执行程序,叫vmlinux或vmlinuz(原始的未经任何处理加工的原版内核elf文件);
  2. 嵌入式系统部署时烧录的一般不是这个vmlinuz/vmlinux,而是要用objcopy工具去制作成烧录镜像格式,经过制作加工成烧录镜像的文件就叫Image(这个制作烧录镜像主要目的就是缩减大小,节省磁盘)
  3. 原则上Image就可以直接被烧录到Flash上进行启动执行(类似于u-boot.bin),实际上linux的作者们觉得Image还是太大了所以对Image进行了压缩,并且在image压缩后的文件的前端附加了一部分解压缩代码,构成了一个压缩格式的镜像就叫zImage
  4. 解压的时候,通过zImage镜像头部的解压缩代码进行自解压,然后执行解压出来的内核镜像。具体的实现流程如下:
    在这里插入图片描述
  5. uboot为了启动linux内核,发明了一种内核格式叫uImage
  6. uImage是由zImage加工得到的,uboot中有一个工具,可以将zImage加工生成uImage。注意:uImage不关linux内核的事,linux内核只管生成zImage即可,然后uboot中的mkimage工具再去由zImage加工生成uImage来给uboot启动。这个加工过程其实就是在zImage前面加上64字节的uImage的头信息即可。

注:如果直接在kernel底下去make uImage会提示mkimage command not found。解决方案是去uboot/tools目录下执行cp mkimage /usr/local/bin/,复制mkimage工具到系统目录下。再去make uImage即可。

  • vmlinux 编译出来的最原始的内核文件,未压缩
  • zImage 是vmlinux经过gzip压缩后的文件
  • bzImage bz表示“big zImage”,不是用bzip2压缩的。两者的不同之处在于,zImage解压缩内核到低端内存(第一个640K),bzImage解压缩内核到高端内存(1M以上)。如果内核比较小,那么采用zImage或bzImage都行,如果比较大应该用bzImage
  • uImage U-boot专用的映像文件,它是在zImage之前加上一个长度为0x40的tag,说明这个内核的版本、加载位置、生成时间、大小等信息;其0x40之后与zImage没区别
  • vmlinuz 是bzImage/zImage文件的拷贝或指向bzImage/zImage的链接
  • initrd 是“initial ramdisk”的简写,一般被用来临时的引导硬件到实际内核vmlinuz能够接管并继续引导的状态

Uboot加载内核过程

  • bootm加载linux镜像是加载uIamge,uIamge是由mkimage制作而来,和zIamge的差异是uIamge是zIamge压缩过的,bootm需要先对uIamge解压,解压地址为内核入口地址
  • 原则上uboot启动时应该给他uImage格式的内核镜像,但是实际上uboot中也可以支持zImage,是否支持就看是否定义了LINUX_ZIMAGE_MAGIC这个宏

内核文件生成流程图

在这里插入图片描述

编译uImage

  • 解压内核代码
tar -xvf linux-3.14.tar.xz
  • 设置交叉编译工具链
#编辑源代码顶层Makefile
vim Makefile
#修改内容
#ARCH = arm
#CROSS_COMPILE = arm_none_linux_gnueabi-
  • 选择一个soc
make exynos_defconfig 
#cp -raf arch/arm/configs/exynos_defconfig .config
  • 内核源代码配置(内核裁剪)
make menuconfig
  • 进入内核源代码目录
#需要使用到工具mkimage,存放到宿主机/usr/bin/
make uIamge -j2

编译设备树

设备树存放路径:linux-3.14/arch/arm/boot/dts

  • 修改linux-3.14/arch/arm/boot/dts路径下的Makefile
vim linux-3.14/arch/arm/boot/dts/Makefile
#修改对应的内容
  • 编译设备树
#回到源代码根目录
make dtbs
  • 替换目标机的dtb文件

通过TFTP启动内核

  • 将uImage和dtb文件放入宿主机ubuntu系统中的/tftproot
#在源代码根目录
cp -raf arch/arm/boot/uIamge /tftpboot
cp -raf arch/arm/boot/dts/exynos4412-fs4412.dtb /tftpboot
  • 在开发板中设置uboot参数,使其能够加载内核
#目标机输入命令
set ipaddr 192.168.7.22 #目标机的IP地址
set serverip 192.168.7.21 #宿主机的IP地址
set bootcmd tftp 0x410000000 uImage \;tftp 0x42000000 exynos4412-fs4412.dtd \;bootm 0x41000000 - 0x42000000
save

通过NFS挂载rootfs系统

  • 解压跟文件系统rootfs.tar.xz,到宿主机的nfs目录下
sudo tar -xvf rootfs.tar.xz -C /opt/4412/
  • 配置宿主机的nfs服务器,让/opt/4412/rootfs可以被挂载
sudo vim /etc/exports
#添加内容
#/opt/4412/rootfs *(subtree_check,rw,no_root_aquash,async)

#重启nfs服务
sudo service nfs-kernel-server restart
  • 在目标机指定内核通过网络挂载根文件系统
#目标机输入命令
set bootargs console=ttySAC2,115200 init=/linuxrc root= /dev/nfs rw nfsroot=192.168.7.21:/opt/4412/rootfs ip=192.168.7.22
save
#bootargs uboot传递给内核的启动参数,是字符串
# console=xxx 内核启动时的调试信息输出端
# root=xxx 内核根文件系统路径
#   root=/dev/nfs 表示根文件系统在网络远端
#   nfsroot=IP:path
#ip=xxx 目标机开机时的ip地址

驱动的Makefile示例

ROOTFS_DIR = /opt/4412/rootfs
ifeq ($(KERNELRELEASE), )
	KERNEL_DIR = /home/dylan/Linux_4412/kernel/linux-3.14
	CUR_DIR = $(shell pwd)
all:
#-C 选项的作用是指将当前工作目录转移到你所指定的位置
#M=选项的作用是,当用户需要以某个内核为基础编译一个外部模块的话,需要在make modules 命令中加入“M=dir”
#程序会自动到你所指定的dir目录中查找模块源码,将其编译,生成KO文件
	make -C $(KERNEL_DIR) M=$(CUR_DIR) modules
clean:
	make -C $(KERNEL_DIR) M=$(CUR_DIR) clean
install:
	cp -raf *.ko $(ROOTFS_DIR)/drv_moduls
else
	obj-m += hell0.c
endif
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值