使用FS4412开发板
网络配置
配置板子IP
编辑/etc/init.d/rcS文件,添加
1 | ifconfig eth0 192.168.2.111 |
重启板子即可。
配置虚拟机IP
点击虚拟网络编辑器
虚拟机有线网络设置
注意:虚拟机网络适配器需要更改为桥接模式
编译软件
编译软件采用arm-linux-gcc
1 | arm-linux-gcc a.c |
文件传输
采用tftp工具进行传输
安装tftp服务器: 注意:虚拟机需要连外网
1
2sudo apt-get update
sudo apt-get install tftpd-hpa tftp-hpa配置tftp服务器:
1
2
3
4
5
6
7
8
9
10
11
12sudo vim /etc/default/tftpd-hpa
点i进入编辑模式
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/home/hqyj/tftpboot" //共享文件的路径;
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -c -s"
点Esc退出编辑模式
家目录下面创建目录tftpboot:
sudo mkdir /home/hqyj/tftpboot
修改共享文件的权限:
sudo chmod 0777 /home/hqyj/tftpboot启动tftp服务器: Ubuntu开机后只需要启动一次
1
sudo service tftpd-hpa restart
将需要传输的文件存储在共享目录中(/home/hqyj/tftpboot):
1
cp <filename> /home/hqyj/tftpboot
要从远程主机192.168.1.2上下载
test.txt,则应输入以下命令
1 | tftp -g -r test.txt 192.168.1.2 |
将磁盘中的文件上传到远程主机的命令
1 | tftp -p -l file.txt 192.168.1.2 |
Linux文件操作
相关驱动文件存放在/dev中
1 | int fd = open(); |
ioctl的请求:
- _IO('L',0) 开灯
- _IO('L',2) 关灯
裸机操作
可以发现LED3连接到GPX1_0,查询用户手册
- CON:配置寄存器
- DAT:数据寄存器
- PUD:
- DRV:
可以看到GPX1_0对应配置为GPX1CON[0],配置[3:0]位置即可设置状态
GPX1DAT[7:0]既可以配置输入输出电平,
打开板子开关,马上按回车,进入启动加载界面(U-boot),类似于终端
通过pri命令可以打印基本配置信息
通过set命令修改配置信息,save保存
ping测试连通性
注意:Ubuntu ping不同开发板,裸机只能由开发板主动发起ping
通过tftp下载文件,
1 | tftp 内存地址 文件名 |
此时为裸机,需要用二进制文件才能识别
这个不为二进制数据文件
高级语言:(预处理->编译->汇编->链接)
- 预处理:展开头文件
- 编译:把高级语言转变为汇编语言
- 汇编:转变为二进制
- 链接:将多个二进制段结合在一起
1 |
|
转变为汇编语言
操作系统启动
量产:研发完成后,直接以一个整体放到内存中,直接启动 -> 产品
研发过程中,首先将系统分为4部分:
启动加载器(bootloader) + 系统内核(kernel) + 设备树(device tree) + 根文件系统(rootfs-root file system)
1 | 相关命令: |
分段启动操作系统
1 | 将 u-sd.bin烧写进入SD卡 |
1 | tftp 41000000 start/uImage |
输入完成后即可进入此界面
配置网络采用ifconfig eth0 ip地址
自启动操作系统
1 | set bootcmd "tftp 41000000 start/uImage;tftp 42000000 start/exynos4412-fs4412.dtb;tftp 43000000 start/ramdisk.img;bootm 41000000 43000000 42000000" |
NFS挂载启动
通过网络挂载一个共享文件夹
ramdisk.img是封装好的,rootfs.tar.gz是没封装的
Ubuntu下操作:
1.nfs安装,要有外网
sudo apt-get update
sudo apt-get install nfs-kernel-server
2.准备好一个即将被共享出去的文件夹
sudo mkdir nfs
sudo chmod 0777 nfs
3.将 文件系统 放入 nfs 文件夹, 解压文件系统 解压 rootfs.tar.xz
tar -xvf rootfs.tar.xz
4.解压后进入到rootfs目录,使用pwd确定所对应的绝对路径
cd rootfs
pwd --> /home/hqyj/nfs/rootfs 就是用来挂载的共享路径;
5.在nfs服务器的配置文件中说明 /home/hqyj/nfs/rootfs 需要共享出去
sudo vi /etc/exports
尾部加入, 添加新的一行:
/home/hqyj/nfs/rootfs *(rw,sync,no_root_squash,no_subtree_check)
解释:
*:允许所有的网段访问,也可以使用具体的IP
rw:挂接此目录的客户端对该共享目录具有读写权限
sync:资料同步写入内存和硬盘
no_root_squash:root用户具有对根目录的完全管理访问权限
no_subtree_check:不检查父目录的权限
6.重启nfs共享
sudo service nfs-kernel-server restart
7.检查是否开成功
showmount -e
Export list for ubuntu:
/home/hqyj/nfs/rootfs * //共享成功的路径
开发板上操作(不进操作系统):
8.修改u-boot启动参数
set bootargs "root=/dev/nfs nfsroot=192.168.2.222:/home/hqyj/nfs/rootfs,v3 rw console=ttySAC2,115200 clk_ignore_unused init=/linuxrc ip=192.168.2.111"
注意更改:
nfsroot=192.168.2.222:/home/hqyj/nfs/rootfs //Ubuntu的ip地址, 要挂载的文件路径
解释:
root=/dev/nfs //文件系统在网上
nfsroot=192.168.2.222:/home/hqyj/nfs/rootfs,v3 //那台电脑的哪个文件夹,而且用v3版本的协议
rw //可读可写
console=ttySAC2,115200 //通过串口2输出信息,波特率115200
clk_ignore_unused //忽略未使用的时钟,如果不加很有可能卡住
init=/linuxrc //当挂载成功后,自动执行init进程(文件夹下的linuxrc文件)
ip=192.168.2.111 //内核起来之后用这个IP(开发板IP)
9.修改u-boot启动命令
set bootcmd "tftp 41000000 start/uImage; tftp 43000000 start/exynos4412-fs4412.dtb; bootm 41000000 - 43000000"
save
EMMC启动
要确保有一个u-emmc.bin
1 | 先SD卡启动,将u-emmc.bin 下载到运存 |
进入后操作与前段相同
Bootloader
CPU架构:
1 | X86(intel):高性能 |
什么是Bootloader?
- 硬件启动的引导程序,是运行操作系统的前提。
- 在操作系统内核或用户应用运行之前的一段代码。
- 对于硬件进行初始化,为操作系统准备好环境。
- 在嵌入式系统重,整个系统的启动加载任务通常由bootloader来完成。
Bootloader的特点:
- 不属于操作系统,由汇编语言或C语言开发
- 针对特定的硬件平台编写
- 在移植系统时,首先要为开发板移植bootloader
- bootloader不依赖于CPU的体系结构,依赖于嵌入式系统班设备的配置
bootloader的基本功能:
- 初始化相关硬件,把bootloader自搬运到内存中
- 执行用户的命令:访问环境变量,通过串口/网络通信,读写RAM/FLASH
- 加载并执行内核
bootloader启动:
- 第一阶段:BL1
- 初始化基本的硬件
- 把bootloader搬运到内存
- 设置堆栈指针并将bss段清理,为后续执行C代码做准备
- 跳转到第二阶段代码
- 第二阶段:BL2
- 初始化本阶段需要用到底的硬件
- 读取环境变量
- 如果是自启动模式,从flash或通过网络加载内核并执行
- 如果是下载模式,接收用户的命令后执行
u-boot系统移植
1.抄板
仿照别人的板子修改一些信息, 改成自己的
1 | vi boards.cfg 复制284行, yy复制, p粘贴, 将复制的285行中的两个origen修改为fs4412 |
具体过程:
Linux内核
通常我们使用的Linux系统是一个集Linux内核、工具集、各种库、桌面管理器、应用程序于一体的一个发布包
一个内核不是一套完整的操作系统,
“内核”指的是一个提''供硬件抽象层、磁盘以及文件控制、多任务等功能的系统软件
内核移植
准备
安装插件exuberant-ctags和libncurses5-dev
1 | sudo apt-get update //更新软件 |
获取Linux源码,并解压
1 | tar -xvf linux-3.14.tar.xz |
修改交叉编译工具
1 | 修改Makefile,198行,199行 |
生成默认配置
(配置文件放在 arch/arm/configs下)
1 | make exynos_defconfig |
配置内核:
正常执行,会弹出一个菜单选项,我们可以去选择需要配置的内核;
1 | make menuconfig |
在菜单界面选中 dm9000 网卡驱动
1 | Device Drivers ---> |
1 | 内核中选配必要的网络协议栈支持 |
1 | 选择NFS支持 |
1 | 选择USB支持 |
编译生成内核镜像
编译内核镜像会用到"mkimage"命令, 需要提前配置一下, 这个工具在 u-boot 文件夹下 首先将u-boot-2013.01文件夹下的mkimage命令复制到用户系统命令文件夹下
1 | sudo cp ../u-boot-2013.01/tools/mkimage /usr/local/bin/ |
编译内核
1 | make uImage |
编译成功会生成一个经过压缩后的镜像文件uImage,
其生成的文件路径为:arch/arm/boot/uImage
将生成的 uImage 移动到 tftp 共享 路径下
1 | cp arch/arm/boot/uImage /home/hqyj/tftp/my_uImage |
启动镜像
1 | Image:原始镜像 |
设备树移植
复制一份为exynos4412-fs412.dts
修改527行后面,添加网卡驱动
格式不对,选中全部行,按一下"=",格式即可对齐
修改makefile文件
编译设备树文件:
1 | make dtbs |
拷贝编译的设备树到tftp共享文件中:
1 | cp arch/arm/boot/dts/exynos4412-fs4412.dtb /home/hqyj/tftp/my_exynos4412-fs4412.dtb |
挂载启动
拓展:添加USB驱动
1 | vim arch/arm/boot/dts/exynos4412-fs4412.dts |
1 | usbphy: usbphy@125B0000 { |
1 | make dtbs |
1 | cp arch/arm/boot/dts/exynos4412-fs4412.dtb /home/hqyj/tftp/my_exynos4412-fs4412.dtb |
插入USB设备,
字符设备
主(组)设备号,用于定义同一类设备
次设备号用于定位具体设备
修改Makefile
生成驱动代码.ko文件
板子通过insmod myled.ko安装驱动
通过应用程序开关灯
卸载驱动文件
根文件系统制作
我们选择的版本是busybox-1.22.1.tar.bz2, 将文件移动到Ubuntu内, 进行解压:
进入源码目录, 在 busybox-1.22.1 文件夹内进行操作:
1 | make menuconfig |
1 | Busybox Settings ---> |
配置好保存后, 进行编译:
1 | make |
编译好后, 安装busybox, 生成根文件夹:
1 | make install |
安装完成后默认生成 _install 文件夹, 这就是我们制作的根文件夹, 将所有文件拷贝到nfs共享文件夹下, 切换路径:
1 | sudo cp -rf _install /home/hqyj/nfs/my_rootfs |
创建缺少的目录
1 | sudo mkdir etc dev tmp mnt proc sys var lib |
添加所需要的库代码
1 | sudo cp -a /home/hqyj/Downloads/gcc-4.6.4/arm-arm1176jzfssf-linux-gnueabi/sysroot/lib/* ./lib/ |
删除无用的库,用来保证rootfs足够小8M以内;
1 | sudo rm lib/*.a |
添加系统启动文件
在etc下添加文件inittab,文件内容如下 sudo vi etc/inittab
1 | #this is run first except when booting in single-user mode. |
在etc下添加文件fstab,文件内容如下,
1 | #device mount-point type options dump fsck order |
在etc下创建init.d目录,并在init.d下创建rcS文件,rcS文件内容为:
1 | #!/bin/sh |
为rcS添加可执行权限:
1 | sudo chmod +x etc/init.d/rcS |
在etc下添加profile文件,文件内容为:
1 | #!/bin/sh |
复制文件系统, 修改挂载镜像
在nfs服务器的配置文件中说明 /home/hqyj/nfs/my_rootfs 需要共享出去
1 | sudo vi /etc/exports |
1 | 将原来的挂载信息屏蔽 - 前面加#: |
1 | 重启nfs |
开发板设置启动参数
1 | set bootargs "root=/dev/nfs nfsroot=192.168.2.222:/home/hqyj/nfs/my_rootfs,v3 rw console=ttySAC2,115200 clk_ignore_unused init=/linuxrc ip=192.168.2.111" |
打包为img镜像文件
1 | cd /home/hqyj/nfs |
创建一个8M的空磁盘(ramdisk)
1 | dd if=/dev/zero of=ramdisk bs=1k count=8192 |
把ramdisk制作成ext2格式的文件
1 | mkfs.ext2 -F ramdisk |
创建mymnt目录作为挂载点
1 | mkdir mymnt |
把ramdisk挂载到mymnt/
1 | sudo mount -t ext2 ramdisk mymnt/ |
将测试好的文件系统里的内容全部拷贝到 mymnt/ 目录下面
1 | sudo cp -a my_rootfs/* mymnt/ |
取消挂载
1 | sudo umount mymnt/ |
压缩ramdisk为ramdisk.gz
1 | gzip --best -c ramdisk > ramdisk.gz |
格式化为uboot识别的格式
1 | mkimage -n "ramdisk" -A arm -O linux -T ramdisk -C gzip -d ramdisk.gz ramdisk.img |
拷贝到tftp目录下,方便下载
1 | cp ramdisk.img /home/hqyj/tftp/my_ramdisk.img |
板子设置
1 | set bootcmd "tftp 41000000 my_uImage;tftp 42000000 my_exynos4412-fs4412.dtb;tftp 43000000 my_ramdisk.img;bootm 41000000 43000000 42000000" |
整个打包
创建一个img镜像文件
1 | sudo dd if=/dev/zero of=fs4412.img bs=1M count=300 |
安装工具
1 | sudo apt install kpartx qemu-utils fdisk |
建立分区
1 | sudo fdisk ./fs4412.img |
加载img文件
1 | sudo kpartx -av ./fs4412.img |
格式化两个分区
1 | 第一分区为fat16(按需求 v3s是fat16) |
挂载两个分区
1 | 创建两个文件夹 |
将boot,内核,设备树文件拷贝进boot分区中