linux系统移植

1 linux环境搭建

1.1 添加交叉开发工具链

新建如下工程目录:

img

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 测试环境变量是否添加成功。

img

file 命令查看文件属性

1.2 配置tftp服务(文件传输)

(1)安装软件包

(2)修改默认的配置文件 /etc/default/tftpd-hpa

(3)重新启动tftp服务 sudo /etc/init.d/tftpd-hpa restart

img

注意源文件的路径一定要是在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 **)

img

tar -Jxvf rootfs.tar.xz

1.3 配置nfs服务(设置目录为网络上的共享目录)

(1)安装软件包

(2)修改默认的配置文件 /etc/exportssudo vi /etc/exports

(3)重新启动nfs服务 sudo /etc/init.d/nfs-kernel-server restart

img

注:前面的路径要填写自己rootfs所在的路径。(pwd指令)

ubuntu@farsight:~/workdir/fs4412/fs/rootfs$ pwd

/home/ubuntu/workdir/fs4412/fs/rootfs

注意格式一定要一致。

挂载:

img

取消挂载:

img

1.4 网络方式加载Linux内核(开发阶段)

img

img

img

网络方式加载linux内核故障判断

1)、网络不通 ping测试,与虚拟机ping测试确认网络连接是否OK;

2)、tftp 服务测试;

a)重启tftp服务确认故障是否解决;

b)其次是文件的读写权限,通过chmod 777 修改/workdir/fs4412/tftpboot路径下的文件权限;

3)、serverip确认,确认IP地址是否正确;这里是服务器也就是虚拟机那边的IP地址;

img

1.5 从EMMC加载内核和文件系统(产品发布阶段)

img

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)关闭CacheMMU

​ (3)初始化系统时钟

​ (4)初始化内存

​ (5)将整个u_boot从存储介质中搬移到内存中(board_init_f

4.在内存中运行u_boot代码

​ (1)设置异常向量表,告诉ARM核异常向量表基地址

​ (2)关闭CacheMMU

​ (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

​ 获取了bootdelaybootcmd环境变量的值,如果没有设置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移植

img

img

img

img

这里要屏蔽掉这一句;注意我们使用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 /*备份了一份*/

img

img

当前并没有移植网卡驱动,所以ping测试是ping不通的。下一步移植DM9000网卡驱动。

img

3.4 DM9000网卡移植

img

3.5 在u-boot中添加eMMC代码

​ 参照实验手册,四、FLASH 移植 (EMMC)

​ 注意:

​ 在头文件中不能出现"//"注释

img

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-

img

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:编译成模块(代码会编译,但是不会连接到内核里面去)

img

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

img

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/

img

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

img

img

提示这里无法挂载根文件系统;

img

img

find命令查找文件名;

img

make dtbs #生成设备树文件

cp exynos4412-origen.dts exynos4412-fs4412.dts

gedit exynos4412-fs4412.dts

上面的方式无法正常生成exynos4412-fs4412.dtb,所以直接修改exynos4412-origen.dts原文件。

gedit exynos4412-origen.dts

img

配置内核:
make menuconfig

img

sudo cp arch/arm/boot/uImage ../../tftpbootcp arch/arm/boot/dts/exynos4412-fs4412.dtb /tftpboot/

改为下面的语句执行:

cp arch/arm/boot/dts/exynos4412-origen.dtb ../../tftpboot/

img

img

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

img

手动分三次用tftp服务烧录uImage.

img

img

把原来tftpboot路径下的多余文件删除,重新拷贝。

sudo cp arch/arm/boot/uImage ../../tftpboot

img

img

cp arch/arm/boot/dts/exynos4412-origen.dtb ../../tftpboot/

4.3 Kconfig和Makefile

img

Kconfig 配置

4.3.1 led 驱动添加实验

img

img

提示没有stdio.h文件。

这里在driver/char/led中只需添加led_driver这个文件夹。app文件夹是放在fs/rootfs/下面,单独采用

arm-none-linux-gnueabi-gcc app.c -o fs4412_led 编译

img

make uImage 生成的镜像文件uImage重新加载到开发板。

img

img

4.3.2 Kconfig语法规则

依赖

img

img

5 kernel启动流程

5.1 Linux内核解压后的启动流程

img

img

img

5.2 系统启动的时候如何自动执行自己的程序

img

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

img

img

5.3 busybox 命令工具集的安装

img

拷贝如下动态库(实验手册中有2处错误)

img

img

posted @ 2022-11-17 17:48  耳东Sir  阅读(341)  评论(0编辑  收藏  举报