linux系统移植
1 linux环境搭建
1.1 添加交叉开发工具链
新建如下工程目录:
gcc-4.6.4.tar.xz #拷贝
tar -Jxvf gcc-4.6.4.tar.xz #解压
cd ./gcc-4.6.4/bin #到.bin目录,pwd获取当前目录
pwd
/home/ubuntu/workdir/fs4412/toolchain/gcc-4.6.4/bin
新开一个终端在根目录下;
sudo vi /etc/bash.bashrc #添加全局环境变量
TOOLCHAIN=/home/ubuntu/workdir/fs4412/toolchain/gcc-4.6.4/bin
Export PATH=$PATH:$TOOLCHAIN
arm-none-linux-gnueabi-gcc –v
测试环境变量是否添加成功。
file
命令查看文件属性
1.2 配置tftp服务(文件传输)
(1)安装软件包
(2)修改默认的配置文件 /etc/default/tftpd-hpa
(3)重新启动tftp服务 sudo /etc/init.d/tftpd-hpa restart
注意源文件的路径一定要是在tftpboot
下
sudo chown ubuntu:ubuntu * -R
tftp> get uImage
Error code 0: Permission denied
ubuntu@farsight:~/workdir$ ls
fs4412
ubuntu@farsight:~/workdir$ cd fs4412/
ubuntu@farsight:~/workdir/fs4412$ ls
fs kernel tftpboot toolchain u-boot
ubuntu@farsight:~/workdir/fs4412$ cd tftpboot/
ubuntu@farsight:~/workdir/fs4412/tftpboot$ ls
exynos4412-fs4412.dtb hello.c uImage
ubuntu@farsight:~/workdir/fs4412/tftpboot$ **chmod 777 **
ubuntu@farsight:~/workdir/fs4412/tftpboot$
这里要在这个目录下加权限 (**chmod 777 **)
tar -Jxvf rootfs.tar.xz
1.3 配置nfs服务(设置目录为网络上的共享目录)
(1)安装软件包
(2)修改默认的配置文件 /etc/exports (sudo vi /etc/exports
)
(3)重新启动nfs服务 sudo /etc/init.d/nfs-kernel-server restart
注:前面的路径要填写自己rootfs所在的路径。(pwd指令)
ubuntu@farsight:~/workdir/fs4412/fs/rootfs$ pwd
/home/ubuntu/workdir/fs4412/fs/rootfs
注意格式一定要一致。
挂载:
取消挂载:
1.4 网络方式加载Linux内核(开发阶段)
网络方式加载linux内核故障判断:
1)、网络不通 ping测试,与虚拟机ping测试确认网络连接是否OK;
2)、tftp 服务测试;
a)重启tftp服务确认故障是否解决;
b)其次是文件的读写权限,通过chmod 777 修改/workdir/fs4412/tftpboot路径下的文件权限;
3)、serverip确认,确认IP地址是否正确;这里是服务器也就是虚拟机那边的IP地址;
1.5 从EMMC加载内核和文件系统(产品发布阶段)
2 u-boot启动流程
2.1 开发平台
[1]CPU 核
ARM cortex-A9 armv7指令集
[2]SOC
Samsung exynos4412 4个cortex-a9核
[3]board
fs4412 --------> 参照三星的母板进行设计
2.2 u-boot 目录结构
1.board 存放是特定开发板相关的代码,一般以芯片厂家的名字命名
origen是三星基于exynos4412做一块开发板
board/samsung/origen/lowlevel_init.S
系统时钟初始化代码
board/samsung/origen/mem_setup.S
内存初始化代码
2.arch 都是跟cpu架构相关的代码,例如:arm ,x86 ,mips ,ppc
arch/arm/cpu/armv7/start.S
这个是uboot首先执行的代码
arch/arm/cpu/u-boot.lds
这个是连接脚本文件(告诉编译在连接生成可执行文件的时候,一些段存放位置)
3.include 存放的是uboot相关代码需要头文件
include/configs/origen.h
origen开发板对应的头文件,它决定了origen所需要的一些代码的宏开关
它也是开发板配置头文件,开发板所需要的代码宏开关和相关的宏定义的
参数都应该在此文件中定义
#ifdef SAMSUNG_XXXX
.......
#endif
#ifdef TI_XXX
.....
#endif
4.net uboot支持的一些网络协议
ping(icmp) tftp arp rarp(根据ip地址获取目标主机mark地址(网卡地址))
5.lib 多有平台通用的代码
string.c
实现了字符串相关操作的代码
6.common uboot支持的命令实现代码
7.driver uboot支持的一些硬件驱动代码
8.boards.cfg
u-boot 支持的板子的配置信息,u-boot编译系统就是根据此配置文件,来识别当前板子的信息
2.3 如何在u-boot工程中添加代码
在uboot的每个子目录下,都有一个Makefile文件
例如:
我想将 driver/net/dm9000x.c
添加uboot代码中,此时只需在它的Makefile中添加所需要编译的文件
COBJS-$(CONFIG_DRIVER_DM9000) += dm9000x.o
注意:只有在CONFIG_DRIVER_DM9000这个宏被定义后,dm9000x.o才会被生成,此时我们只需要在
include/configs/origen.h
头文件定义这个宏就可以了。
2.4 u-boot-2013.01 启动流程
ARM核的设置
1.设置CPU为SVC模式
2.设置异常向量表
3.关闭Cache和MMU
SOC芯片的设置
4.处理唤醒的条件
5.判断是否在内存中运行
6.如果不在内存中运行,则初始化系统时钟和内存控制器
如果在内存中运行,则不需要初始化系统时钟和内存控制器
7.初始化uart
8.设置了sp
9.调用board_init_f
第一阶段代码:
board_init_f 功能将u_boot从存储器搬移到内存,跳到内存中运行
第二阶段代码:
board_init_f
(1)执行了初始化序列表 (板子相关的初始化操作)
(2)为u_boot重定向预留内存
10.对u_boot重定向 (从低端内存搬移到高端内存)
11.清bss段
12.board_init_r
[1]外围硬件初始化
emmc 、网卡
[2]让串口作为标准输入输出设备
[3]main_loop
探测自动启动是否被打断,如果没有被打断则执行bootcmd指定的命令
如果被打断了,则进入u_boot交互界面
3 u-boot 移植
3.1 fs4412(SOC:samsung,exynos4412) 启动
硬件信息
SOC : 三星 exynos4412 (4个cortex-A9 ARM核) 主频 1.4GHZ
board : origen<->fs4412
u-boot版本 : u-boot-2013.01
1.eynos4412内部固化的irom代码先运行
(1)确定启动的设备
(2)初始化启动的设备
(3)将启动设备开始一部分代码(BL1)搬移到exynos4412内部的iram(SRAM)运行
注意:BL1 代码是三星提供的,irom的代码在读取BL1的时候,会对它做验证,如果验证通过则运行它。
2.在iram运行BL1代码
(1)确定启动设备
(2)将启动设备中的BL2代码拷贝到exynos4412内部的iram运行
注意:
BL2指的的是u_boot的第一阶段代码
u-boot代码开始运行
3.在iram运行BL2代码
(1)设置异常向量表,告诉ARM核异常向量表基地址
(2)关闭Cache和MMU
(3)初始化系统时钟
(4)初始化内存
(5)将整个u_boot从存储介质中搬移到内存中(board_init_f)
4.在内存中运行u_boot代码
(1)设置异常向量表,告诉ARM核异常向量表基地址
(2)关闭Cache和MMU
(3) ...
(4) ...
注意:
此时u_boot已经在内存中,不需要初始化系统时钟和内存
(5)_main
<1>设置了sp
<2>调用了board_init_f
(6)board_init_f (板子的第一阶段初始化)
<1>完成基本的初始化
[1]SOC ID的获取
[2]定时器初始化
[3]串口的初始化
[4]从串口中输出了一些信息
<2>为u_boot重定向做准备
在内存最顶端划分空间
(7)重定向u_boot
如果u_boot不是在高端内存,则将u_boot从低端内存搬移到高端内存
(8)清BSS段
为运行C语言程序
(9)board_init_r(板子的第二阶段初始化)
<1>初始化硬件设备
[1]EMMC存储器
[2]DM9000网卡设备
...
<2>从存储介质中读取了环境变量的值
(10)main_loop
获取了bootdelay和bootcmd环境变量的值,如果没有设置bootcmd则进入u_boot交互界面。
如果设置了bootcmd,判断在到计时时间内,如果用户没有打断,则执行bootcmd命令。
如果倒计时时间内,被用户打断,则进入u_boot交互界面。
注意:
u_boot交互界面,循环读取用户输入的命令,然后执行。
3.2 u-boot移植核心思想
\1. 厂家直接提供u-boot -> 烧写 或者 修改(增加新功能) 或 u-boot 版本升级
\2. 芯片公司,让u-boot支持公司的芯片 ,自己仿照别的厂家,添加自己开发板相关代码
\3. 芯片公司根据自己的芯片编写bootloader,仿照u-boot设计思想
-----------------------------------------------------------------------------------
(1)熟悉SOC芯片和u-boot启动流程
(2)系统时钟,内存是否能正常初始化
(3)搬移u-boot到内存过程 (从存储介质中读取数据,然后写到内存)
(4)对存储介质(emmc)如何进行读写
3.3 u-boot移植
这里要屏蔽掉这一句;注意我们使用ctrl + ] (tags)跳转到的是****u-boot-2013-learn.tar.xz 实际我们移植的是u-boot-2013.01.tar.bz2;要修改的代码也是这里面的。所以两边不要弄混淆。
重新编译整个u-boot
make
cp u-boot.bin ../../tftpboot/ /*拷贝生成的u-boot.bin到tftp服务器。*/
cp u-boot.bin ../mkfs4412/ /*拷贝到SD卡烧写文件的目录*/
sdfuse flash bootloader u-boot-fs4412.bin /*在SecureCRT端输命令实现SD卡烧写*/
cp u-boot-2013.01 ../../u-boot-2013.01-bak -r /*备份了一份*/
当前并没有移植网卡驱动,所以ping测试是ping不通的。下一步移植DM9000网卡驱动。
3.4 DM9000网卡移植
3.5 在u-boot中添加eMMC代码
参照实验手册,四、FLASH 移植 (EMMC)
注意:
在头文件中不能出现"//"注释
gedit ./board/samsung/origen/origen.c
采用gedit编辑避免输入法差异导致复制代码时出错;
4 linux内核移植
4.1 linux 内核目录结构
(1)arch 目录 :存放架构相关的代码
arch/arm/boot/compressed
存放的是内核的自解压代码
arch/arm/kernel/head.S
Linux 内核的开始代码
arch/arm/boot/dts
存放的是开发板相关的设备树文件
arch/arm/configs
存放的SOC芯片相关的内核配置文件
(2)driver 目录: 设备驱动代码
(3)net 目录: 网络协议栈的实现代码
(4)Makefile 文件 (指定平台信息和交叉开发工具链)
4.2 针对自己的开发板配置linux内核
4.2.1 修改Makefile
ARCH ?= arm
CROSS_COMPILE ?= arm-none-linux-gnueabi-
4.2.2 使用默认配置文件配置内核 (exynos_defconfig)
make 默认配置文件
例如:
make exynos_defconfig(推荐) (cp arch/arm/configs/exynos_defconfig .config)
4.2.3 通过配置菜单配置内核(menuconfig)
make menuconfig
y:选中编译进内核 n:不编译进内核 m:编译成模块(代码会编译,但是不会连接到内核里面去)
ubuntu@farsight:~/workdir/fs4412/kernel/linux-3.14$ make exynos_defconfig
\#
\# configuration written to .config
\#
ubuntu@farsight:~/workdir/fs4412/kernel/linux-3.14$ vi .config
ubuntu@farsight:~/workdir/fs4412/kernel/linux-3.14$ make menuconfig
*** Unable to find the ncurses libraries or the
*** required header files.
*** 'make menuconfig' requires the ncurses libraries.
***
*** Install ncurses (ncurses-devel) and try again.
***
make[1]: *** [scripts/kconfig/dochecklxdialog] Error 1
make: *** [menuconfig] Error 2
需要安装****libcurses (****curses库是可以在[Linux]终端中写出字符用户界面的一个库****)
sudo dpkg -i .deb
4.2.4 编译Linux 内核
**make**
(1)vmlinux (60M) (elf linux内核镜像)(存放在Linux内核的顶层目录)
(2)Image (5.5M) (去掉elf头和调试信息之后的Linux内核镜像) arch/arm/boot
(3)vmlinux (3.0M) (elf linux内核镜像 : 自解压代码 + gzip压缩后的内核镜像)
(arch/arm/boot/compressed )
(4)zImage (去掉elf头之后的Linux内核镜像 : 自解压代码 + gzip压缩后的内核镜像) arch/arm/boot
arch/arm/boot: (2),(4)
-----------------------------------------------------------------------------------------------
4.2.5 生成uImage格式linux内核镜像
**make uImage**
**ubuntu@farsight:~/workdir/fs4412/kernel/linux-3.14$ cd ./arch/arm/boot/**
**ubuntu@farsight:~/workdir/fs4412/kernel/linux-3.14/arch/arm/boot$ ls**
**bootp compressed dts Image install.sh Makefile uImage zImage**
**ubuntu@farsight:~/workdir/fs4412/kernel/linux-3.14/arch/arm/boot$ cp uImage** **~/workdir/fs4412/tftpboot/**
**ubuntu@farsight:~/workdir/fs4412/kernel/linux-3.14/arch/arm/boot$ cd ~/workdir/fs4412/tftpboot/
ubuntu@farsight:~/workdir/fs4412/kernel/linux-3.14$ cp ./arch/arm/boot/uImage ~/workdir/fs4412/tftpboot/**
**ubuntu@farsight:~/workdir/fs4412/kernel/linux-3.14$ cd ~/workdir/fs4412/tftpboot/**
**ubuntu@farsight:~/workdir/fs4412/tftpboot$ ls -lh**
**total 5.5M**
**-rwxrwxrwx 1 ubuntu ubuntu 34K May 8 19:21 exynos4412-origen.dtb**
**-rwxrwxrwx 1 ubuntu ubuntu 0 May 2 15:09 hello.c**
**-rwxrwxrwx 1 ubuntu ubuntu 2.5M Sep 25 2014 ramdisk.img**
**-rwxrwxrwx 1 ubuntu ubuntu 0 May 2 15:39 test.c**
**-rwxrwxrwx 1 ubuntu ubuntu 213K May 5 15:39 u-boot.bin**
**-rwxrwxrwx 1 root root 2.8M May 9 09:44 uImage
提示这里无法挂载根文件系统;
find命令查找文件名;
make dtbs #生成设备树文件
cp exynos4412-origen.dts exynos4412-fs4412.dts
gedit exynos4412-fs4412.dts
上面的方式无法正常生成exynos4412-fs4412.dtb,所以直接修改exynos4412-origen.dts原文件。
gedit exynos4412-origen.dts
配置内核:
make menuconfig
sudo cp arch/arm/boot/uImage ../../tftpbootcp arch/arm/boot/dts/exynos4412-fs4412.dtb /tftpboot/
改为下面的语句执行:
cp arch/arm/boot/dts/exynos4412-origen.dtb ../../tftpboot/
setenv bootcmd tftp 41000000 uImage;tftp 42000000 exynos4412-origen.dtb;bootm 41000000 – 42000000
setenv bootargs root=/dev/nfs nfsroot=192.168.1.121:/home/ubuntu/workdir/fs4412/fs/rootfs,proto=tcp,nfsvers=3,nolock rw console=ttySAC2,115200 init=/linuxrc ip=192.168.1.133
手动分三次用tftp服务烧录uImage.
把原来tftpboot路径下的多余文件删除,重新拷贝。
sudo cp arch/arm/boot/uImage ../../tftpboot
cp arch/arm/boot/dts/exynos4412-origen.dtb ../../tftpboot/
4.3 Kconfig和Makefile
Kconfig 配置
4.3.1 led 驱动添加实验
提示没有stdio.h文件。
这里在driver/char/led中只需添加led_driver这个文件夹。app文件夹是放在fs/rootfs/下面,单独采用
arm-none-linux-gnueabi-gcc app.c -o fs4412_led 编译
make uImage 生成的镜像文件uImage重新加载到开发板。
4.3.2 Kconfig语法规则
依赖
5 kernel启动流程
5.1 Linux内核解压后的启动流程
5.2 系统启动的时候如何自动执行自己的程序
ubuntu@farsight:~/workdir/fs4412/fs/rootfs/etc$ ls
fstab init.d inittab profile
ubuntu@farsight:~/workdir/fs4412/fs/rootfs/etc$ vi profile
ubuntu@farsight:~/workdir/fs4412/fs/rootfs/etc$ pwd
/home/ubuntu/workdir/fs4412/fs/rootfs/etc
5.3 busybox 命令工具集的安装
拷贝如下动态库(实验手册中有2处错误)
本文来自博客园,作者:耳东Sir,转载请注明原文链接:https://www.cnblogs.com/erdongsir/p/16900287.html