系统移植
一.服务器的搭建
1. TFTP服务器
1.1 安装
#sudo apt-get install tftpd-hpa tftp-hpa
1.2配置服务器客户端在同一网段
服务器 (Ubuntu)$ sudo ifconfig eth0(网卡) 192.168.~.~ netmask 255.255.255.0
上面的命令,将ip地址和子网掩码设置到内核;
当网卡断开时,内核会丢掉ip地址;
当网卡连接时,内核会从配置文件(从网络自动获取)读取ip地址和子网掩码
客户端 (开发板)# setenv ipaddr 192.168.~.~ 将ip地址设置到ipaddr环境变量
# setenv netmask 255.255.255.0 设置子网掩码
# saveenv 保存所有的环境变量到emmc
网卡:将虚拟机设置为桥接模式
1.3修改配置文件
# sudo vi /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/tftpboot" #****指定tftp服务器的根目录,就是下载文件的位置
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-c -s -l" #这里是选项,-c是可以上传文件的参数,-s是指定tftpd-hpa服务目录,上面已经指定 -l 监听模式
创建tftpboot目录,重启启动 tftp-server
#sudo mkdir /tftpboot
#sudo chmod 777 /tftpboot
#sudo service tftpd-hpa restart
2.通过TFTP服务器移植系统
通过网线将(Ubuntu)中tftp文件夹下的系统配置文件烧写到开发板中
2.1烧写kernel(uImage)
1. 拷贝uImage到虚拟机的/tftpboot
2. 下载uImage到开发板内存(0x41000000)
# tftp 41000000(内存地址) uImage
2.2 烧写设备树(exynos4412-fs4412.dtb)
1. 拷贝exynos4412-fs4412.dtb到虚拟机的/tftpboot
2. 下载exynos4412-fs4412.dtb到开发板内存(0x41000000)
# tftp 0x41000000(内存地址) exynos4412-fs4412.dtb
3. 烧写exynos4412-fs4412.dtb到emmc
# movi write dtbs(分区名) 0x41000000(内存,放了exynos4412-fs4412.dtb)
2.3烧写文件系统rootfs(ramdisk.img)
1. 拷贝ramdisk.img到虚拟机的/tftpboot
2. 下载ramdisk.img到开发板内存(0x41000000)
# tftp 0x41000000(内存地址) ramdisk.img
3. 烧写ramdisk.img到emmc
# movi write rootfs(分区名) 0x41000000(内存,放了ramdisk.img) 0x300000(分区大小)
2.4手动启动
1. 设置内核的启动参数
# setenv bootargs init=/linuxrc(告诉内核第一个应用程序的位置) console=ttySAC2,115200(告诉内核哪个终端是它的输入/输出终端)
# saveenv
2. 读取kernel到内存(运行时以下三个文件要并存,地址要偏移下,不要覆盖)
# movi read kernel 0x41000000
3. 读取设备树到内存
# movi read dtbs 0x42000000
4. 读取rootfs(ramdisk.img)到内存
# movi read rootfs 0x43000000(放在内存的位置) 0x300000(大小)
5. 启动内核
#bootm 0x41000000(内核) 0x43000000(根文件系统) 0x42000000(设备树的位置)
2.5自动启动
1. 原理
u-boot启动后,如果倒计时到0, 它会自动运行bootcmd环境变量中的命令
2. 设置bootcmd环境变量
# setenv bootcmd movi read kernel 0x41000000\;movi read dtbs 0x42000000\;movi read rootfs 0x43000000 0x300000\;bootm 0x41000000 0x43000000 0x42000000
# saveenv
3. 重启开发板
注:当出现下载不动,终端一直打印T时,检查服务器配置,端口设置,重启服务器
3.通过NFS服务器挂载网络文件系统
3.1原理
将开发板上的文件系统挂载到服务器(Ubuntu)上,实现服务器和开发板可以同时对改文件系统进行操作。
3.2 安装
#sudo apt-get install nfs-kernel-server nfs-common
3.3修改配置文件系统
sudo vi /etc/exports
在注视下添加一行:
/source/rootfs *(rw,sync,no_root_squash,no_subtree_check)
/source/rootfs”是存放nfs文件系统的路径;“*”表示在所有的网段都可以共享;“rw”表示nfs文件系统允许读写;
“sync”表示修改都会同步到nfs服务端,否则只是会暂存在本地内存;
新建配置文件指定的对应的nfs服务器根目录
sudo mkdir -p /source/rootfs
重启nfs服务程序,使配置生效
sudo service nfs-kernel-server restart
3.4就该开发板Uboot的内核启动参数
//根文件系统通过nfs协议去挂载 网络文件系统存放的位置
#setenv bootargs root=/dev/nfs rw nfsroot=192.168.1.250:/source/rootfs ip=192.168.1.4(内核用到的ip地址,因为内核要和nfs服务器进行网络通讯) console=ttySAC2,115200 init=/linuxrc
(3) 设置自动运行命令
#setenv bootcmd tftp 41000000 uImage\;tftp 42000000 exynos4412-fs4412.dtb\;bootm 41000000 - 42000000 ("-"表示不指定根文件系统地址)
#saveenv
3. boot或重启开发板
二.U-boot
1.BootLoader.
1.1简介:
属于嵌入式系统的软件层次,固话在固件中的boot程序,类似于(BOIS),grub,它是在操作系统运行前执行的一小段程序,主要是用于引导操作系统。
1.2基本功能
a.初始化硬件 b.把BootLoader自搬到内存中 c.执行用户命令(访问环境变量,网络,串口通讯,读写ram/flash) d.设置Linux启动参数
1.3 执行过程
不同的处理器上电或复位后执行的第一条指令地址并不相同,对于 ARM 处理器来说,该地址为 0x00000000。
对于一般的嵌入式系统,通常把 Flash 等非易失性存储器映射到这个地址处,而 Bootloader就位于该存储器的最前端,
所以系统上电或复位后执行的第一段程序便是Bootloader。而因为存储 Bootloader的存储器不同,Bootloader的执行过程也并不相同,
嵌入式系统中广泛采用的非易失性存储器通常是 Flash,而 Flash 又分为 Nor Flash 和Nand Flash 两种。
它们之间的不同在于:Nor Flash 支持芯片内执行(XIP, eXecute In Place),这样代码可以在Flash上直接执行而不必拷贝到RAM中去执行。
而Nand Flash并不支持XIP,所以要想执行 Nand Flash 上的代码,必须先将其拷贝到 RAM中去,然后跳到 RAM 中去执行
2.uboot分析
2.1 uboot特点
代码结构清晰,易于一直,支持多种CUP,可以支持多种操作系统,支持许多开发板,支持多种协议文件系统。
2.2uboot常用命令
setenv var value 设置环境变量
setenv var 删除var变量
saveenv <==>save
printenv <==> pri
特殊变量 bootcmd uboot在自启动模式下会自动执行。
bootcmd 在uboot启动的时候,当倒计时到0的时候,uboot会去找到bootcmd环境变量,取得它的值。
bootcmd的值都是一些uboot可执行的命令,uboot会去自动执行这些命令。
bootargs linux内核启动参数,uboot会将此环境变量的值存到启动参数区,内核在启动的时候,首先会去启动参数区
获取相关参数,解析处理,做相应的处理。参数格式,名称不能随意,固定的。
2.3uboot启动流程
第一阶段:汇编
1>初始化硬件(CPU内部的寄存器)
2>初始化RAM,为第二阶段程序准备空间
3>拷贝第二阶段的程序到内存空间
4>跳转到第二阶段C入口
第二阶段:C语言
1>初始化硬件(板级硬件设备)
2>将内核和根文件系统镜像加载到内存中
3>执行内核
3.U-BOOT移植
3.1基本步骤
1.找到相近的代码,并拷贝一份作为自己修改的源码
2.先修改源码,使能核心部件(uart clock ram..),能串口输出信息。
3.移植修改其他非核心源码
三.Linux内核
1 Linux内核的基本组成
a.MM内存管理
b.PM进程管理
c.FS文件系统
d.DC驱动架构
e.NET网络
f.驱动代码(占很大部分代码)
Linux内核是一个有文件系统,多任务管理,硬件抽象层2等功能的系统软件。内核不是一个完整的操作系统
linux系统 = Linux kernel + lib + apps + GUI(图形界面 qt window gome)
2.Linux内核的特征
2.1特点
1.可裁剪,可扩展,可定制。
2.可移植性强,支持多种体系结构。
3.稳定性强,网络功能强。
4.支持多任务多用户,资源耗费少。
2.2内核源码目录
git分布式 svn托管 代码管理系统
*arch 体系结构相关代码,各体系结构cpu
arch/arm/板子 arm体系结构 目录都是开发板
mach-开发板名称
开发板相关代码,以前有各个板子硬件信息。
后面device tree技术出来之后,硬件信息提取出来。
boot/compressed 下面是压缩解压代码(image<->zImage --mkimage--> uImage)
arch/arm/kernel/head.S是第一个被执行文件
boot/dts 设备树源码文件
.dtsi 设备树头文件 .h
.dts 设备树源码 .c
.dtb 被编译过的产物
*Documentation 文档
init 内核启动初始化代码 不可裁剪
lib 通用库实现
sound 音频驱动
block 块设备
*drivers 设备驱动
ipc 进程间通讯
fs 文件系统
include 通用头文件
kernel 核心代码不可裁剪 pm
scripts 配置编译脚本 这些脚本用于系统源码的配置和编译
mm 内存管理
3.配置编译
1.修改源码目录下顶层的Makefile
ARCH ?= arm
CROSS_COMPILE ?= arm-none-linux-gnueabi-
2.找一个与开发板类似的缺省配置,参考导入默认参考配置
make exynos_defconfig(只用执行一次,生成一个默认的.config)
3.执行配置命令
make menuconfig 字符界面配置菜单,需要ncureses库
sudo apt-get install ncurses-dev
4.内核启动流程
上电--->CPU跳到中断向量处执行--->加载并执行bootloader代码--->加载内核--->
执行内核---->挂载根文件系统--》运行第一个用户空间程序 bootargs init=/linuxrc