#系统移植

系统移植导学

什么是系统移植

将操作系统移植到对应的硬件平台

linux系统移植到S5P6818开发板

学习系统移植目的

在众多嵌入式操作系统中,Linux目前发展最快、应用最为广泛。

Linux具有源码开放、内核可裁减、网络功能完善、体积小、可移植性强、性能优良的等诸多优点,非常适合作为嵌入式操作系统。

根据产品需求(软硬件可裁剪)

1)为后面的驱动开发学习搭建一个系统环境

2)就业、工作的需要(公司新的硬件平台--->移植linux系统到硬件)

3)嵌入式(软+硬)开发离不开操作系统

系统移植过程

Linux系统移植:

1.准备Linux内核镜像、SD卡启动盘

2.通过拨码开关选择启动方式(SD启动)

3.通过SD卡中的引导程序安装系统

4.安装Linux驱动程序

5.安装Linux应用程序

开发板启动过程

1)开发板上电后首先运行SOC内部,也就是片上系统的ROM中固化的代码(BL0),这段代码先对基本的软硬件环境进行初始化,包括时钟等。

2)然后再检测拨码开关位置获取启动方式,再将对应存储器中的bootloader搬移到内存,然后跳转到bootloader运行。

3)bootloader开始运行后首先对开发板上的软硬件环境做进一步初始化

4)然后将linux内核、设备树(dtb、描述硬件结构和设备连接关系的数据结构)、根文件系统(rootfs)从外部存储器(或网络)搬移到内存,然后跳转到linux运行

5)Linux开始运行后先对系统环境做初始化,当系统启动完成后

6)Linux再从内存中(或网络)挂载根文件系统

交叉开发环境搭建

本地开发和交叉开发

本地开发:PC端编写代码,编译代码,运行代码

交叉开发:PC端编写代码,编译代码,Target(目标板)运行代码

PC ——> X86/64架构   

Target ——> arm架构

PC:gcc

交叉编译工具链:arm-none-linux-gnueabi-gcc

arm-none-linux-gnueabi- :交叉编译工具链的名字,名字就是一个代号

不同的公司做的交叉编译工具链的名字不同

用交叉编译工具链将源码编译成支持ARM架构的可执行程序

再将可执行程序拷贝到目标板上运行。

安装交叉编译环境

获取交叉编译工具链

将代码编译成ARM架构的可执行程序

一般交叉编译工具链和uboot和linux内核源码,都具有配套的关系。

1. 去gnu官网获取交叉编译工具链的源码。不推荐:编译过程很繁琐

2. 直接从芯片厂家要

3 .直接跟开发板的生成厂家要

4. 直接找单位领导要

安装交叉编译工具链

1. 在ubuntu的家目录(~)下,创建toolchain

mkdir toolchain

2. 拷贝gcc-4.6.4.tar.xz到toolchain目录下

cp 目录/gcc-4.6.4.tar.xz ~/toolchain

3. 解压缩交叉编译工具链

tar -vxf gcc-4.6.4.tar.xz

4. 配置环境变量

sudo vi /etc/bash.bashrc

在最后一行添加以下内容,修改为自己的路径

export PATH=$PATH:/home/hq/toolchain/gcc-4.6.4/bin/

5. 使环境变量立即生效

source /etc/bash.bashrc

6. 测试交叉编译工具链是否安装成功

arm-none-linux-gnueabi-gcc -v

打印以下内容,表示成功

gcc version 4.6.4 (crosstool-NG hg+default-2685dfa9de14 - tc0002)

PC和开发板进行硬件连接

串口线的作用

打印各种调试信息到串口工具上

网线的作用

用于下载uboot和内核的镜像(可执行程序)

通过网络去挂载根文件系统

tftp及其安装配置

TFTP是一个传输文件的简单协议,它基于UDP协议而实现,进行小文件传输的,传输8位数据。不具备通常FTP的许多功能,只能从文件服务器上获得或写入文件,不能列出目录,不进行认证。

tftp服务器环境搭建

【实验目的】

掌握tftp环境搭建的基本方法,能够在开发板上使用tftp传输文件

【实验环境】

ubuntu  FS6818 开发板

【注意事项】

实验步骤中以“$”开头的命令表示在 ubuntu 环境下执行,以“#”开头的命令表示在开发板下执行

【实验步骤】

1. ubuntu中使用命令查看是否安装了tftp服务器

dpkg -s tftpd-hpa

显示包含如下信息表示安装了

Status: install ok installed

Architecture: i386

Source: tftp-hpa

Version: 5.2-7ubuntu3.1

2. 如果没有安装、确保Ubuntu正常联网,输入下面命令。安装了直接执行步骤3

sudo apt-get update  // 更新源

sudo apt-get install -f  // 更新依赖

sudo apt-get install tftpd-hpa tftp-hpa

3. 修改tftp服务器配置文件,配置tftp服务的环境变量

sudo vi /etc/default/tftpd-hpa

修改为如下内容,保存退出

# / etc / default / tftpd - hpa

TFTP_USERNAME="tftp"

//tftp用户名,不需要修改

TFTP_DIRECTORY="/tftpboot"

//tftp服务下载文件的存放的路径,需要修改

//改成自己的对应的tftpboot的路径

TFTP_ADDRESS="0.0.0.0:69"

//tftp服务默认使用的69端口号

TFTP_OPTIONS="-c -s -l"

//tftp服务的参数,这个需要修改

注:TFTP_DIRECTORY是tftp服务器的工作目录,即客户端要下载的文件需要放到该目录下

4. 创建服务器工作目录并设置为最高的权限

tftpboot目录下存放的是要下载到开发板上的可执行文件

$sudo mkdir /tftpboot

$sudo chmod 777 /tftpboot

5. 重启tftp服务,使配置生效。(这里要注意每次重新打开Ubuntu都需要重启)

sudo service tftpd-hpa start   // 启动TFTP服务

sudo service tftpd-hpa restart    // 重启TFTP服务

6. 本地测试tftp服务器是否配置成功

ping 其它机器过程:本机网卡驱动,到内核,内核处理这个驱动,发送ping的包到另一个系统的网卡,处理这个包,把包的内容放到协议站(在内核里面),识别到ping的包,然后通过网卡驱动,到网卡,返回一个包(都会到真正物理硬件)
$ tftp 127.0.0.1

tftp> get 1.txt # 从tftpboot目录下下载

# 1.txt文件到当前目录 (本例子就是,

在tftpboot下面touch 1.txt,然后在家目录下面运行)

tftp 127.0.0.1;然后get 1.txt,就把tftpboot下面的1.txt下载到家目录下面了)

tftp> put 2.txt # 把当前目录中的2.txt文件,上传到tftpboot文件夹中

tftp> q <回车> 退出

测试tftp文件获取,进入到服务器工作目录,并创建文件

hq@Ubuntu:~$ cd /tftpboot/
hq@Ubuntu:/tftpboot$ ls
hq@Ubuntu:/tftpboot$ vi test.txt
hq@Ubuntu:/tftpboot$ cd
hq@Ubuntu:~$ tftp localhost
tftp> get test.txt
tftp> q
hq@Ubuntu:~$ ls
test.txt    

和我们刚刚在tftp目录下创建的内容一致,证明成功通过tftp服务器获取到了tftp目录下的文件。

7. 可能出现的问题:下载或上传时一直卡

原因:

tftp服务安装成功,需要重启tftp服务

tftp服务安装不成功

关闭windows和ubuntu的防火墙(防火墙会阻碍数据传输)

nfs及其安装配置

NFS是基于UDP/IP协议的应用,其实现主要是采用远程过程调用RPC机制,RPC提供了一组与机器、操作系统以及底层传送协议无关的存取远程文件的操作。

nfs服务器环境搭建

【实验目的】

掌握nfs环境搭建的基本方法,能够在开发板上使用nfs挂载根文件系统

【实验环境】

ubuntu FS6818 开发板

【注意事项】

实验步骤中以“$”开头的命令表示在 ubuntu 环境下执行,以“#”开头的命令表示在开发板下执行

【实验步骤】

1. 打开ubuntu,终端执行如下命令,查看是否安装了nfs服务器,显示ok表示安装了,直接执行步骤3就可以了。

dpkg -s nfs-kernel-server

2. 执行安装命令,安装nfs服务器

sudo apt-get install nfs-kernel-serve

3. 配置nfs服务

1)在根目录下创建文件夹

sudo mkdir -p /opt/6818/rootfs/rootfs

2)设置文件夹的权限最大

sudo chmod -R 777 /opt/*

3)配置nfs服务的环境变量

sudo vi /etc/exports

在文件的最后一行添加以下内容:

/opt/6818/rootfs/rootfs/ *(rw,sync,no_subtree_check,no_root_squash)

解析:

/opt/6818/rootfs/rootfs:根文件系统的路径

*:所有的用户,注:*和后边的左括号"("之间不可以出现空格.

rw:可读可写的权限

sync:同步文件

no_subtree_check:不对子目录检查文件的权限

no_root_squash:如果客户端为root用户,那么他对整个文件具有root的权限

注意:这段话前边不要加#,#号是这个文件中的注释符号

4. 重启nfs服务

sudo service nfs-kernel-server start  // 启动nfs服务

sudo service nfs-kernel-server restart   // 重启nfs服务

5. 本地测试nfs服务是否安装成功

1)回到家目录下

cd ~

2)

sudo mount -t nfs localhost:/opt/6818/rootfs/rootfs /mnt

本机IP地址:ubuntu 的IP

nfs:使用nfs服务,将本机IP地址:/opt/6818/rootfs/rootfs

文件挂载到/mnt目录下

3)检查/mnt目录下是否挂载成功,此时mnt下面的东西应该和rootfs下面一样。

hq@Ubuntu:~$ ls /mnt
a.out  dev              hello.ko       mjpg-streamer  root            tmp
app    drv              insmoddemo.sh  mnt            sbin            usr
bin    etc              lib            mycdev.ko      storage_mamage  var
boa    farsight_irq.ko  linuxrc        proc           sys             warehouse.db


hq@Ubuntu:~$ ls /opt/6818/rootfs/rootfs
a.out  dev              hello.ko       mjpg-streamer  root            tmp
app    drv              insmoddemo.sh  mnt            sbin            usr
bin    etc              lib            mycdev.ko      storage_mamage  var
boa    farsight_irq.ko  linuxrc        proc           sys             warehouse.db

4)卸载挂载的文件

sudo umount /mnt

注意:不可以在/mnt目录下执行卸载的命令

Uboot概述

Bootloader简介

Bootloader是在操作系统运行之前执行的一段小程序,其本质为一段裸机程序不是操作系统本身。

通过这段小程序,我们可以初始化硬件设备、建立内存空间的映射表,从而建立适当的系统软硬件环境,为最终调用操作系统内核做好准备。

在嵌入式系统中,Bootloader是基于特定硬件平台来实现的,不同的处理器架构都有不同的Bootloader。例如,U-Boot就同时支持PowerPC、ARM、MIPS和X86等体系结构。

注:bootloader是启动引导程序的统称,嵌入式linux常用的bootloader是uboot

Bootloader基本功能

  • 初始化软硬件环境
  • 引导加载linux内核
  • 给linux内核传参
  • 执行用户命令

常见的Bootloader   

 

Uboot的工作方式

1. Uboot首先被加载到内存中,并开始执行。

2. 初始化硬件设备,例如CPU、内存、串口等。

3. 读取存储设备(例如Flash)中的内核镜像,并将其加载到内存中。

4. 设置内核启动参数,例如根文件系统的位置、内存大小等。

5. 跳转到内核的入口点,启动内核。

6. 一旦内核启动成功,Uboot的使命就完成了,它的生命周期也就结束了。

Uboot烧写及使用

SD卡启动盘制作

【实验目的】

掌握SD卡启动盘的制作

【实验环境】

ubuntu FS6818 实验平台

【注意事项】

实验步骤中以“$”开头的命令表示在 ubuntu 环境下执行,以“#”开头的命令表示在开发板下执行。

【实验步骤】

方法一:(不建议)

烧写工具默认从0扇区开始烧写,这里我们自己在Uboot之前放一个512字节的空镜像。

1. 将资料中“源文件”中的ubootpak.bin文件放到Ubuntu内,新建一个目录

Linux_6818/uboot,可以根据自己的需求创建,或者直接家目录

2. 终端输入如下命令,制作一个512字节的空镜像(存从0扇区,读从1扇区,丢失512字节,把0扇区占满)

sudo dd if=/dev/zero of=zero.bin count=1

3. 执行如下命令,将uboot追加到zero.bin之后生成uboot.bin

$cat zero.bin ubootpak.bin>uboot.bin

4. 再执行如下命令,制作一个1M的空镜像(用于擦除SD卡中原有的数据)

$sudo dd if=/dev/zero of=clear.bin count=2048

5. 将生成的文件uboot.bin和clear.bin,拷贝到Win下

6. 双击打开“Win32DiskImager”

7. 打开烧写镜像,烧写两次第一次烧写clear.bin,第二次烧写uboot.bin

8. 将SD卡插入开发板的卡槽,调整拨码开关为SD卡启动,查看uboot是否能正常启动

注:uboot正常启动后LED2灯会点亮且终端上也会打印uboot相关的信息。

方法二:

1. 虚拟机-->可移动设备-->realtek USB3.0-CRW--->连接

2. 把sdtool压缩包放到虚拟机里,并解压

sudo tar -xvf sdtool.tar.xz

3. 在ubuntu中执行命令

sudo ./s5p6818-sdmmc.sh /dev/sdb ubootpak.bin

如果打印一下信息successfully表示,部署成功

688+1 records in

689+0 records out

352768 bytes (353 kB, 344 KiB) copied, 0.445815 s, 791 kB/s

^_^ The image is fused successfully

注:报SD卡只读的错误,将sd卡中开关拨到lock的位置,lock靠近sd卡的触点位置

4. 测试sd卡是否制作成功,将sd卡插到开发板板上,设置开发板上的拨码开关,为sd卡启动

5. 开发板重新上电,启动成功。

SD卡的存储以扇区为单位,每个扇区的大小为512Byte, 其中零扇区存储分区表(即分区信息)后续的扇区可自行分区和格式化;

若选择SD卡启动,处理器上电后从第一个扇区开始将其中的内容搬移到内存,所以我们把uboot放到从第一个扇区开始之后的空间根据个人需求可进行分区和格式化

uboot模式

自启动模式

uboot启动后若没有用户介入,倒计时结束后会自动执行自启动环境变量bootcmd中设置的命令(一般作加载和启动内核)

交互模式

倒计时结束之前按下任意按键uboot会进入交互模式,交互模式下用户可输入uboot命令

uboot帮助命令

help              查看uboot支持的所有命令

help 命令      查看当前命令的使用方法

常用环境变量

ipaddr       uboot的IP地址

serverip    服务器的IP地址(即ubuntu的IP)

bootdelay 进入自启动模式之前倒计时的秒数

uboot环境变量命令

printenv  打印uboot中所有的环境变量

setenv    设置指定的环境变量(保存在RAM中)

setenv    环境变量 环境变量的值

saveenv 保存所有环境变量到EMMC中

网络传输命令

loadb 地址              通过Kermit协议下载二进制文件到指定的内存地址()

tftp 地址 文件名      通过tftp协议下载文件到指定的内存地址

存储器访问命令

mmc read 将EMMC中指定扇区中的内容读取到内存中指定的地址

mmc read <addr> <blk#> <cnt>

addr: 内存地址

blk#: EMMC中的扇区编号

cnt: 读取的扇区的个数

mmc write 将内存中指定地址中的内容写入到EMMC中指定的扇区

mmc write <addr> <blk#> <cnt>

addr:对应着内存的地址

blk#:mmc设备的块号(开始写入的块地址)

cnt:mmc设备块的个数(要写入的块数,每块通常是 512 字节)

mmc erase 将mmc的起始块号为blk#,cnt块大小的数据,进行擦除

mmc erase <blk#> <cnt>

blk#:mmc设备的块号

cnt:mmc设备块的个数

擦除的时间,受cnt块的个数有影响

自启动环境变量

该环境变量(bootcmd)可以设置成一到多个uboot命令的集合(若有多个使用 \; 分割)

自启动模式下uboot就会按照bootcmd中命令的顺序逐条执行

把printenv命令写进去,开机之后不做干预,倒计时结束就会自动打印环境

网络环境搭建

搭建网络环境可以搭建公网的也可以搭建局域网的,这里搭建的是局域网的。

【实验目的】

掌握 ubuntu 下网络配置的基本方法,能够通过网线连通 ubuntu 和开发板

【实验环境】

ubuntu FS6818开发板

【注意事项】

实验步骤中以“$”开头的命令表示在 ubuntu 环境下执行,以“#”开头的命令表示在开发板下执行

【实验步骤】

windows网络配置

我们的Ubuntu没有真实的物理网卡,需要找一个物理网卡进行配置,而物理网卡在windows下所以需要我们配置网络,具体步骤如下

找到WALN选项->更改适配器选项点击打开,找到自己的网络端口(连接开发板的,这里留意下我画横线处的名字,之后会用到),右键属性,选择IPV4双击

配置IP、子网掩码和默认网关,我们要配置的是局域网所以IP需要保证开发板和Ubuntu以及Windous保持同网段不同名,即最后一段不同前面相同。

子网掩码三者之间保持一致因为子网掩码确定了网段,网关可以不配置。

Win下网卡配置完了但是和Ubuntu没有建立连接,我们通过虚拟机桥接的方式把网卡桥接到Ubuntu使用

虚拟机网络配置

编辑->虚拟网络编辑器,配置为桥接模式、选择上面Win网络配置时让记住的网卡名字,然后应用、确定。如果这个界面是灰的右下角帮助上面那会有个更改设置点击即可、如果还不行关闭退出以管理员身份运行虚拟机。

虚拟机设置、网络适配器,按照如图配置确认

配置Ubuntu网络

Ubuntu 网络配置方法有很多,图形化界面配置使用命令行进行配置都可以,这里我们演示使用图形化界面进行静态配置作为参考。

将配置信息或者数据删除

sudo vi /etc/network/interfaces

配置文件中只保留如下信息就可以了

如图所示点击桌面右上角图标执行,进行网络配置

点击add添加,name栏随便写个自己的网络名字

Method栏选择Manual(手动的)

Address填写为同我们之前Win下配置的IP同网段的IP

例如我们之前填的192.168.1.100这里可以填192.168.1.125

剩下两栏填写和Win下一致即可(分别是子网掩码和默认网关)

配置好之后点击Save保存退出,到桌面点击桌面右上角图标选择自己刚刚配置的网络。

开发板网络配置

连接串口并打开超级终端

开发板上电或者复位

倒计时结束之前按任意键进入Uboot交互界面

执行printenv命令查看配置

使用setenv和saveenv配置并保存

ipaddr和Ubuntu ip同网段,例如192.168.1.200

gatawayipserverip、netmask和Ubuntu配置的一致就可以了,使用saveenv保存

网关需要ubuntu win下网卡三者都一致

setenv gatewayip 192.168.1.1

开发板的IP,需要和ubuntu ip网段一致最后200这起一个自己的名字

setenv ipaddr 192.168.1.200

子网掩码需要全部一致

setenv netmask 255.255.255.0

服务器ip(ubuntu的),与ubuntu一致

setenv serverip 192.168.1.125

保存

saveenv

Ping主机ip 192.168.1.125 服务器ip

is alive表示ping通

not alive表示没ping通

1)windows的防火墙可能没关

2)检查开发板和电脑之间的网线

3)重启tftp服务

4)检查tftp服务的环境配置是否正确

5)百兆全双工是否设置

linux内核的安装与加载

产品阶段,即:Linux内核、根文件系统、uboot全部存储到硬盘内

研发阶段因为需要反复调试,所以需要我们把根文件系统放到NFS内使用共享的方式,Linux内核放到tftp下进行传输,uboot最好使用SD卡的方式。

【实验目的】

掌握 ubuntu 下网络配置的基本方法,能够通过网线连通 ubuntu 和开发板

【实验环境】

ubuntu FS6818开发板

【注意事项】

实验步骤中以“$”开头的命令表示在 ubuntu 环境下执行,以“#”开头的命令表示在开发板下执行

【实验步骤】

通过EMMC加载内核和根文件系统(产品阶段)

eMMC:Embedded Multi Media Card

根据字面意思,翻译为 嵌入式多媒体卡

eMMC的结构和特点

eMMC=NAND Flash + 主控IC(控制器)

eMMC增加了主控IC,省去了外围硬件电路,规避了主机直接连接到NAND Flash,通过控制器对外通信,采用的协议和SD卡、TF卡的协议是一致。

主控IC包括协议、擦写均衡、坏块管理、ECC校验、电源管、时钟管理、数据存取等功能。设计人员不需要再处理NAND Flash的坏块等问题,eMMC实行内部管理,简化了设计。

通过前面提到的方式我们虽然可以加载Linux内核和根文件系统并正常运行,

但上述方式我们是把内核镜像、根文件系统镜像都放到了tftp服务器上,然后开发板上电之后再通过tftp去下载这些文件到开发板的内存中运行

但在实际做一个产品的时候我们不可能每次开机都通过网络去服务器上下载这些镜像,

所以以下步骤我们就将这些镜像安装到开发板上的EMMC中,然后从EMMC启动内核。

给开发板重新上电,在uboot交互模式下,去下载并安装这些镜像下载内核镜像到内存中

uImage放到/tftpboot目录下

sudo chmod 777 *

给开发板重新上电,在uboot交互模式下,去下载并安装这些镜像

tftp 0x41000000 uImage

将内核镜像写入到EMMC 中指定的扇区

mmc write 0x41000000 0x800 0x4000

将根文件系统镜像ramdisk.img移到tftpboot目录下

下载根文件系统镜像到内存中

tftp 0x41000000 ramdisk.img
将根文件系统镜像写入到EMMC 中指定的扇区
mmc write 0x41000000 0x20800 0x20800
因为要从EMMC驱动,所以还要修改uboot的启动参数,并保存
setenv bootcmd mmc read 0x48000000 0x800 0x4000\;mmc read 0x49000000 0x20800 0x20800\;bootm 0x48000000 0x49000000

setenv bootargs root=/dev/ram rw initrd=0x49000040,0x1000000 rootfstype=ext4 init=/linuxrc console=ttySAC0,115200

saveenv

setenv 设置环境变量的命令

bootcmd 是U-Boot中用于定义启动命令的环境变量

mmc read 0x48000000 0x800 0x4000: 从MMC的0x800地址开始读取0x4000字节的数据到内存地址0x48000000。

mmc read 0x49000000 0x20800 0x20800: 从MMC的0x20800地址开始读取0x20800字节的数据到内存地址0x49000000

bootm 0x48000000 0x49000000: 使用bootm命令启动内核,其中0x48000000是内核的地址,0x49000000是initrd(初始化RAM磁盘)的地址。

root=/dev/ram: 设置根文件系统为RAM设备。

rw: 以读写模式挂载根文件系统。

initrd=0x49000040,0x1000000: 指定初始化RAM磁盘的位置和大小。

rootfstype=ext4: 根文件系统的类型为ext4。

init=/linuxrc: 设置init进程为/linuxrc。

console=ttySAC0,115200: 设置控制台输出为ttySAC0,波特率为115200。

给开发板重新上电,上电之后观察内核是否能通过EMMC加载和启动内核,启动完成后是否能挂载根文件系统(ext4),在终端上输入linux下的shell命令测试是否正常。

通过EMMC加载uboot(产品阶段)

以上的几种方式中我们既可以通过网络启动内核,也可以将内核安装到EMMC中从本地启动。
但是对于uboot我们一直使用的是从SD卡启动,所以我们也可以将uboot安装到EMMC中然后从EMMC启动uboot,这样就可以不使用SD卡了

“ubootpak.bin”拷贝到ubuntu中tftp工作目录

给开发板重新上电,在uboot交互模式下,去下载并安装uboot

tftp 0x41000000 ubootpak.bin

将内核镜像安装到EMMC 中指定的扇区

update_mmc 2 2ndboot 0x41000000 0x200 0x78000

关闭开发板电源,调整拨码开关位置为EMMC启动(拔掉SD卡)

给开发板重新上电,观察uboot是否能正常启动,在终端上输入linux下的shell命令测试是否正常。

通过tftp加载内核、nfs挂载根文件系统(开发阶段)

我们会经常修改内核的源码,也会经常向根文件系统中添加一些驱动或应用程序,这样每次修改之后我们都要重新将内核或根文件系统安装到EMMC中,步骤会比较繁琐,开发效率也比较低,所以在开发阶段我们经常使用的方式是通过tftp加载内核和设备树再通过nfs挂载根文件系统,这样步骤简单,效率也比较高,待产品定型之后在安装到EMMC中。

进入nfs工作目录

cd /opt/6818/rootfs/

将“rootfs-A53-ok.tar”拷贝到ubuntu中nfs工作目录下

解压根文件系统到nfs工作目录

sudo tar -xvf rootfs-A53-ok.tar.xz

修改uboot启动参数,并保存(在倒计时之前)

setenv bootcmd tftp 0x48000000 uImage\;bootm 0x48000000

setenv bootargs root=/dev/nfs nfsroot=192.168.1.125:/opt/6818/rootfs/rootfs,v3 rw console=ttySAC0,115200 init=/linuxrc ip=192.168.1.200

saveenv

setenv:用于设置环境变量。

bootcmd:用于存储启动命令。

tftp 0x48000000 uImage:使用TFTP(Trivial File Transfer Protocol)从TFTP服务器下载uImage文件到内存地址0x48000000。

bootm 0x48000000:使用bootm命令从内存地址0x48000000启动内核。

bootargs:用于传递内核启动参数。

root=/dev/nfs:设置根文件系统为NFS(Network File System)。

nfsroot=192.168.1.125:/opt/6818/rootfs/rootfs,v3:指定NFS服务器的IP地址和NFS挂载点的路径,以及NFS的版本(这里为v3)。

rw:表示文件系统是可读写的。

console=ttySAC0,115200:设置控制台为ttySAC0,波特率为115200。

init=/linuxrc:设置init进程为/linuxrc。

ip=192.168.1.200:本地IP地址为192.168.1.200。

虚拟机重启nfs服务器

sudo service nfs-kernel-server restart

给开发板重新上电,上电之后观察内核是否能通过tftp加载和启动内核
启动完成后是否能挂载根文件系统(nfs)在终端上输入linux下的shell命令测试是否正常,若启动正常我们向nfs的工作目录中添加了新的文件之后可以在开发板直接看到

简单测试一下

Uboot移植

自己做ubootpak.bin

uboot源码获取

1. uboot官网获取  ftp://ftp.denx.de/pub/u-boot/

2. 芯片厂家获取

3. 开发板厂家 --->目前市面上的6818的开发板,开发板厂家只提供u-boot.bin

4. 上级主管 --->推荐

本次移植课程使用:u-boot-2014.07-netok.tar.bz2

uboot版本命名

前期:u-boot-1.3.2

现在:u-boot-2024.07

08年以前uboot是1.1.几1.3.几这样命名08年开始以年份和月份命名。

uboot版本选择

支持对应的硬件平台

相对成熟的版本(资料多)

每当发布新的芯片后uboot就会增加对应芯片的版本。一般和处理器同一时期发布的uboot版本对处理器的支持较好。

uboot的特点

1. u-boot是一个开源的软件

2. u-boot支持多种架构的平台(ARM powerPC MIPS x86)

3. u-boot的源码短小精悍

4. u-boot就是一个裸机代码

5. u-boot引导加载内核,启动内核,并给内核传递参数

6. u-boot可以完成部分硬件的初始化:uart,内存,emmc,网卡

7. u-boot生命周期短,启动完内核,给内核传递完参数(告诉内核从什么地方去挂载根文件系统),u-boot的生命周期结束。

uboot源码结构

由于uboot的源码特别多所以是由很多个文件夹组成的,同类型的源码放到一个文件夹里

平台相关代码

即与CPU架构或开发板硬件相关的源码,硬件的改动对应的代码也需要进行修改

api:这个目录下有很多的用户接口

arch与CPU架构相关的源代码

board与开发板相关的源代码,包含各种官方评估板对应的源码

boards.cfg这个文件是配置信息

common:这下面全是uboot命令的.c文件

config.mk也是一个配置文件

COPYING这是版权文件虽然是开源软件但是也不能乱用

CREDITS这里是代码贡献者名单包括他们的邮箱

disk:磁盘操作的命令文件夹

doc:这里是详细的说明书

drivers:这里面全是驱动文件

dts:设备树文件夹,后面学习驱动时在详细学习。

examples:里面是例程,在不会写的时候可以参考一下

fs:文件系统,这里面每个文件夹内都是文件系统的源代码和makefile文件这里面ext4是嵌入式领域常用的文件系统。

include:这里是头文件

lib:这里是库

makefile:方便我们编译uboot镜像。它这个makefile是层层调用的每个文件夹下都有,使用make命令后总的makefile文件会调用每层的马克file文件来共同编译出uboot镜像

net:网络文件夹,这里面是uboot支持的一些网络

post:上电自检程序

README:一个说明书或者说帮助文档,这个说明书有5000多行都是一些介绍性的的东西。

tools:工具

移植前的准备工作

获取基本的硬件信息

cpu(内核):cortex-a53

arch:armV8

vendor:samsung

SoC:S5P6818

board(公板): S5P6818

公板:芯片厂家根据芯片设计的一套参考电路板

NEXELL:韩国一个芯片生成厂家,三星将S5P6818芯片授权给NEXELL

移植uboot

根据此手册的步骤进行执行uboot移植icon-default.png?t=N7T8https://docs.qq.com/doc/DQXpMa0FBYWZHWUd4

开始准备移植uboot

在ubuntu的家目录下创建bootloader

mkdir bootloader

拷贝u-boot-2014.07-netok.tar.bz2到bootloader中

解压缩uboot源码

先解压u-boot-2014.07-netok.tar.bz2 修改完名字,再解压u-boot-2014.07.tar.bz2

tar -vxf u-boot-2014.07-netok.tar.bz2

mv u-boot-2014.07 u-boot-2014.07-6818

tar -vxf u-boot-2014.07.tar.bz2(官网下载的)

可以下载解压后对比查看

u-boot目录的介绍

平台相关代码:和硬件挂钩

arch(架构)

而官网上面下载的支持多个平台:

board(板子,可以支持的板子)

上面两个和硬件有关系。

平台无关代码:和硬件无关代码可以共用

fs

drivers

include

tools

....

读README

uboot配置与编译

配置交叉编译工具链

为了保证uboot适用所有开发板,uboot把所有的开发板都写出来了,需要哪个编译哪个

1.指定当前使用的硬件平台

make <board_name>_config(咱们用的是make fs6818_config)

注1:<board_name>为当前使用的开发板的名字

注2:执行该命令的前提是uboot源码支持该开发板

注3:该命令必须在uboot源码的顶层目录下执行

/ home / hq / bootloader / u - boot - 2014.07 - 6818 / mkconfig - A fs6818

Configuring for fs6818 board...

2.指定编译uboot源码使用的编译器

打开u-boot源码顶层目录的Makefile

vi Makefile

将以下内容(咱们使用的源码是改过的,但是要知道这个流程)

198 ifeq ($(HOSTARCH),$(ARCH))
199 CROSS_COMPILE ?=                                      
200 endif

修改为

198 ifeq (arm,arm)   //(里面的两个相等即可,写ARM的原因是我们用的是arm)
199 CROSS_COMPILE ?= arm-none-linux-gnueabi-   //(不要有空格)
200 endif

1. 编译u-boot源码,生成ubootpak.bin

make

make all(编译的时间比较长)

注1:该命令必须在uboot源码的顶层目录下执行

注2:该命令执行后在uboot源码顶层目录下生成u-boot.bin

编译需要大概一分钟。编译完多了几个文件,多了一个system.map文件和那些u-boot开头的。

make在编译的过程中先将.c和.s编译成.o文件。最后把他们链接(ld)成一个可执行文件绿色的那个u-boot。他是elf格式的。我们肯定不能把他刷到板子上。不过在这之后它还会用objcopy把利用elf文件生成bin文件。这里还有一个srec文件这是符合摩托罗拉的二进制文件。

2. 清除编译过程中生成的中间文件

make clean

make distclean

注1:该命令必须在uboot源码的顶层目录下执行

这些中间文件就是.o文件。执行make clean只是清除这些.o文件。执行distclean会把生成的可执行文件和二进制文件也删除。恢复刚下载的源码状态。

编译问题解决

Make的时候可能出现上面问题,出现上面问题,如下方法解决:

3. 配置u-boot源码支持fs6818开发板 make <board_name>_config

make fs6818_config

如果打印以下信息,表示成功:

Configuring for fs6818 board...

如果打印以下信息,表示u-boot不支持此开发板:

make: *** No rule to make target `maxiaoli_config'. Stop.

make: *** [maxiaoli_config] Error 1

4. 将生成的ubootpak.bin文件下载到开发板,测试是否可以使用。

    如何将uboot放到flash(EMMC)中,前提:SD卡必须提前烧录一个uboot

       1> 通过SD卡的方式启动uboot,进入到FS6818#界面

       2> 拷贝ubootpak.bin到/tftpboot目录下,重启tftp

cd bootloader/u-boot-2014.07-6818

cp ubootpak.bin /tftpboot

sudo service tftpd-hpa restart

       3> 将ubootpak.bin使用tftp命令烧写到内存中

tftp 0x41000000 ubootpak.bin

       4> update_mmc

update_mmc <dev no> <type> <mem> <addr> <length>

- type : 2ndboot | boot | raw | part

<dev no>:flash设备编号 EMMC:2

<type>:类型 2ndboot

<mem>:uboot在内存中的起始地址,以字节为单位

<addr>:flash的起始地址:以块为单位

<length>:往flash中下载多少块空间

Bytes transferred = 352296 (56028 hex)

一块的大小是512字节

length的大小 > 352296 / 512

fastboot=flash=mmc,

2:ubootpak:2nd:0x200,0x78000; flash=mmc,2:2ndboot:2nd:0x200,0x4000;

执行命令:

update_mmc 2 2ndboot 0x41000000 0x200 0x78000

打印以下内容表示成功

head boot dev = 2

update mmc.2 type 2ndboot = 0x200(0x1) ~ 0x78000(0x3c0): Done

       5> 测试是否更新ubootpak.bin到EMMC中,设置拨码开关,切换EMMC启动,开发板重新上电。

如果正常进入调试界面,说明没问题

总结

  1. 获取uboot源码(开发---》领导)
  2. 修改源码(架构、开发板)
  3. 支持架构----》配置编译器(让他支持CPU)----》修改Makefile的编译器
  4. 清除中间件-----》make clean
  5. 支持开发板-----》make xxxxxx_config
  6. make------>ubootpak.bin
  7. ubootpak.bin放到TFTP服务器下。

uboot代码分析(自己看)

u_boot分析-s5p6818icon-default.png?t=N7T8https://docs.qq.com/doc/DQXZJcnpBZ3lKd3B2

Linux内核移植

内核与操作系统

内核

内核是一个操作系统的核心,提供了操作系统最基本的功能,是操作系统工作的基础,决定着整个系统的性能和稳定性

操作系统

操作系统是在内核的基础上添加了各种工具集、桌面管理器、库、shell、应用程序等(我们使用的网络协议都是基于TCP/IP或者UDP/IP协议开发的)(我们使用rm、mv、cp。。。这些命令都不是内核提供的)

shell翻译过来就是贝壳,他把内核很好的保护了起来。Linux内核内有文件管理系统。所以可以操作磁盘。那现在我们要操作一些文件就需要去操作内核让内核再去操作文件。但是内核很复杂,我们时候一个误操作可能就会把内核搞坏了。

所以我们操作shell让shell再去操作内核就会很安全了。

库这些lib也不是内核包含的,图形化界面也不属于内核,内核本身只支持大黑框。

Shell

Linux层次结构

进程管理、内存管理、文件系统、网络管理、驱动管理

Linux内核的特点

linux内核源码开源

linux支持多种架构平台 arm x86(手机和Ubuntu都使用的是Linux内核)

linux内核代码采用模块化的方式(模块化—》把功能独立处理 安全性比较高)

linux内核代码采用分层的思想

linux内核源码具有良好的移植特性和裁剪特性

linux内核源码都是使用汇编和c语言实现的

Linux内核源码结构

Linux内核源码获取

The Linux Kernel Archives

1)可以从linux内核官方获取 Index of /pub/linux/kernel/

2)从芯片厂家获取

3)从开发板厂家获取

4)从技术主管获取 --》推荐

Linux内核版本命名

linux-主版本号.次版本号.修订版本号.tar.xz

主版本号:内核源码有较大跟新,才会升级主版本号

次版本号:

次版本号为偶数:表示稳定版本

次版本号为奇数:表示测试版本

修订版本号:内核源码中只要有代码更新就会,

升级修订版本号

Linux内核版本选择

三星公司没有对S5P6818的源码开源到Linux内核中,所以不能从官网下载linux内核源码,使用samsung提供的内核源码。

本课程使用的内核源码为:kernel-3.4.39-ok.tar.xz

LInux内核源码结构

把源码拖到ubuntu里解压

在ubuntu的家目录下创建kernel文件夹

将内核源码压缩包拷贝到kernel文件夹中

对内核源码进行解压缩

tar -vxf kernel-3.4.39-ok.tar.xz

进入到内核源码目录中,分析内核源码的目录结构

cd kernel-3.4.39

ls

平台相关代码

arch: 与CPU架构相关的源代码 (跟硬件有关的,代码不可以共享

block:磁盘设备的支持

crypto:加密相关

drivers:设备驱动

firmware:固件

fs:文件系统

include:头文件

一般格式化磁盘都格式化成ntfs

init:内核初始化

ipc:进程间通信(共享内存消息队列什么的都是再ipc目录下实现的)

kernel:内核核心调度机制等

lib:库 内核的核心算法。

mm:内存管理 net:网络协议

scripts:工具、脚本等

security:安全

usr:打包与压缩

virt:虚拟

COPYING: 版权 gpl版权,GNU开源协议

CREDITS: 内核贡献者

README: 说明文档

Documentation: 帮助文档

Makefile: 编译管理

samples: 示例

tools: 工具

Kconfig:内核自带的图形化界面

... ...

Linux内核源码配置和编译

配置交叉编译工具链

打开内核源码顶层目录的Makefile,搜索CROSS_COMPILE

195 ARCH        ?= 
196 CROSS_COMPILE   ?= 
修改为:
195 ARCH        ?= arm
196 CROSS_COMPILE   ?= arm-none-linux-gnueabi- 

读README

拿到内核源码之后,应该先清除,内核源码中的中间文件

make clean

make distclean

make mrproper   //清除更干净

配置内核源码支持当前的硬件平台

打开README文件

翻译后:

"make ${PLATFORM}_defconfig"

使用 arch/$ARCH/configs/${PLATFORM}_defconfig 中的默认符号值创建 ./.config 文件。使用“make help”获取体系结构的所有可用平台的列表。

方法1:

make help

得到以下信息:

fs6818_defconfig - Build for fs6818

方法2:

进入arch/arm/configs/目录

发现以下文件fs6818_defconfig ,所以PLATFORM=fs6818.

让当前的内核支持自己的硬件平台

执行make fs6818_defconfig

执行结果,打印以下信息:

执行完命令将板子的配置信息写到内核源码顶层目录下的.config文件中

Uboot--初始化了部分硬件(部分硬件是可以被驱动的(可以用))

Linux内核--根据用户的需求,当使用板子上面模块(摄像头,灯,蜂鸣器等)用什么我Linux内核初始化什么(驱动),用这个设备我就安装这个设备的驱动,不用这个设备我就不安装这个设备的驱动。

板子上面有这么多外设:我怎么把这些外设的代码放在uImage里面呢?

驱动配置

执行命令:make menuconfig (一定在顶层目录运行)

实际开发中随内核进行菜单选项的配置,都是使用make menuconfig命令

问题1:

第一次使用make menuconfig 需要安装图形化界面的工具

配置之前需要安装图形图(make meuconfig)

sudo apt-get install libncurses5-dev

问题2:

出现以下错误:

cripts/kconfig/mconf Kconfig

Your display is too small to run Menuconfig!

It must be at least 19 lines by 80 columns.

make[1]: *** [menuconfig] Error 1

make: *** [menuconfig] Error 2

原因:终端的字体太大,缩小一点

内核编译

编译内核生成uImage : make uImage

编译得时候可能会相对于比较长

time make uImage -jx

-time:回显编译的时间

-jx:使用多线程的方式进行编译,x可以是2,4,6,8

问题:

在编译的过程中可能出现如下错误:

错误的原因:

找不到mkimage命令,根据提示分析出来mkimage应该存在uboot源码目录中

uboot源码必须进行编译之后才会有mkimage可执行程序

解决问题的方法:

将uboot源码的tools目录下的mkimage,

~/bootloader/u-boot-2014.07-6818/tools/mkimage

拷贝到到ubuntu的/usr/bin目录下:

sudo cp ~/bootloader/u-boot-2014.07-6818/tools/mkimage /usr/bin/

再次对内核源码进行编译即可通过。

测试内核

将arch/arm/boot/目录下的uImage拷贝到/tftpboot目录下

cp arch/arm/boot/uImage /tftpboot

测试uImage是否可以正常启动,并且挂载根文件系统

重启开发板

自动方式:先将uImage下载到内存里面,然后bootcmd启动内核,然后给内核传递参数。

先使用pri命令查看。

通过tftp的方式下载uImage到内存中,通过nfs的方式挂载根文件系统。

注意检查bootcmd和bootargs设置是否正确。

如果不正确,按照以下步骤执行

进入nfs工作目录

cd /opt/6818/rootfs/

将资料中“源文件”目录下的“rootfs-A53-ok.tar”拷贝到ubuntu中nfs工作目录下

解压根文件系统到nfs工作目录

sudo tar -xvf rootfs-A53-ok.tar.xz

setenv bootcmd tftp 0x48000000 uImage\;bootm 0x48000000

setenv bootargs root=/dev/nfs nfsroot=192.168.1.125:/opt/6818/rootfs/rootfs,v3 rw console=ttySAC0,115200 init=/linuxrc ip=192.168.1.200

saveenv

修改uboot启动参数,并保存(在倒计时之前)

虚拟机重启nfs服务器

sudo service nfs-kernel-server restart

给开发板重新上电,上电之后观察内核是否能通过tftp加载和启动内核,启动完成后是否能挂载根文件系统(nfs),在终端上输入linux下的shell命令测试是否正常,若启动正常我们向nfs的工作目录中添加了新的文件之后可以在开发板直接看到

简单测试一下

Makefile .config Kconfig文件之间的关系 ?

可以根据实验去理解三者的关系 驱动移植

驱动移植

需要有一个驱动对应的.c的代码

自己创建一个

第一步:修改Kconfig:(Kconfig是产生菜单的文件)

config RUAN_JIAYU  //在.config中生成选项
	bool "RUAN_JIAYU said welcome to hqyj!"  //选项菜单中的名字(OBJ目标文件名:obj-$(CONFIG_RUANJIAYU))
	help
		welcome to hqyj

bool:两态 两种选择 y(编译到内核) n(不编译到内核)

tristate:有三种选项

三态(Y(把驱动编译到内核中)M(编译生成模块)N(不编译驱动))

添加完选项以后,回到最顶层目录执行make menuconfig

在这个目录下面执行

make menuconfig

通过选项选择要安装的驱动,图形界面能让我们快速的找到想安装的驱动

找到上图的device drivers,然后按回车,出现下面界面,找到character devices,

按回车

看到上面的自己的添加的内容,根据自己的需求按键盘上面的Y,M,N三选一

选中以后到exit退出即可,选择yes

vi .config

CONFIG_RUAN_JIAYU=y

进入:打开Makefile的路径

cd ~/kernel/kernel-3.4.39/drivers/char

vi Makefile 

66 obj-$(CONFIG JS RTC)  += js-rtc.0
67 js-rtc-y= rtc.0
68
69 obj-$(CONFIG TILE SROM) += tile-srom.0
70 obj-$(CONFIG name) += name.o

添加完选项以后,回到最顶层目录执行

编译:

make uImage

-->uImage(包含了新的驱动的内核)

在板子上对应路径(/dev)就有了name的驱动文件。

将其设置成模块

想配置成模块就不能使用bool,这里需要把NAME配置成tristate

在顶级目录输入

make menuconfig

vi .config

编译:

make modules

-->demo.ko(M(编译生成模块))

make uImage

-->uImage (包含了新的驱动的内核)

在板子上对应路径(/dev)就有了name的驱动文件。

Makefile

modules:

编译模块的规则

Y(要编译到内核中) M(编译生成模块) N(不编译驱动)

sudo insmod demo.ko 安装驱动

sudo rmmod demo 卸载驱动

在实际开发中,都是使用模块化的方式进行驱动的开发,

需要使用驱动时,通过insmod命令加载到内核中,

不需要使用驱动时,通过rmmod命令卸载驱动。

好处

1. 开发更加的方便便捷

2. 节约开发的时间

3. 容易发现错误

如果编译到内核中,内核一旦崩溃,不确定是内核的问题换是驱动的问题。

如果使用模块化的方式进行编译,启动内核可以成功,说明内核没有问题,

如果加载驱动是,内核崩溃,说明驱动有问题。

Makefile .config Kconfig文件之间的关系 ?

Makefile:指导内核进行编译

.config:存放的是内核的配置的信息+硬件

Kconfig:存放菜单选项

执行make fs6818_defconfig命令,根据fs6818_config文件和Kconfig文件中的配置信息生成.config文件

make menuconfig 执行时根据Kconfig生成菜单的图形化界面

如果根据菜单图形化界面进行配置之后,会更新.config文件

Makefile文件根据.config文件中的信息,决定将哪些文件编译到uIamge中,哪些不编译到uImage中。

实验

将led灯的驱动编译到内核和编译成模块icon-default.png?t=N7T8https://docs.qq.com/doc/DQVNRZXpPS1VRc3Zr

根文件系统

概念

根文件系统:系统运行所必须依赖的一些文件(比如脚本、库、配置文件...),本质就是目录和文件。

根文件系统镜像:将根文件系统按照某种格式进行打包压缩后生成的单个文件

rootfs-----> ramdisk.img

文件系统:一种管理和访问磁盘的软件机制,不同文件系统管理和访问磁盘的机制不同

移植根文件系统的工具

Index of /downloads

BusyBox 是一个集成了三百多个最常用Linux命令和工具的软件。BusyBox 包含了一些简单的工具,例如ls、cat和echo等等,还包含了一些更大、更复杂的工具,例grep、findmount以及telnet。有些人将 BusyBox 称为 Linux 工具里的瑞士军刀。简单的说BusyBox就好像是个大工具箱,它集成压缩了 Linux 的许多工具和命令,也包含了 Linux 系统的自带的shell

短小精悍

版本更新较快,版本之间差异不大

根文件系统目录介绍

注释:各文件功能解析

bin: 命令文件(通过busybox工具制作)

dev: 设备文件(被操作系统识别的设备才有对应的文件,即设备运行时)

etc: 配置文件(配置内核相关的一些信息)

lib: 库文件、比如C的标准库(从交叉编译工具链中复制的)

linuxrc:根文件系统被挂载后运行的第一个程序(通过busybox工具制作)

mnt: 共享目录(非必要)比如挂载SD卡等时将SD卡挂载在该目录

proc: 与进程相关的文件(当有进程运行时才会有文件)

root: 用户权限(板子本身就是以root用户运行)

sbin: 超级用户命令、一般用户不可用(板子本身是超级用户 通过busybox工具制作)

sys: 系统文件(系统运行时,系统加载后才会有文件)

tmp: 临时文件(比如插入新的设备时会产生临时文件)

usr: 用户文件(通过busybox工具制作)

var: 存放下载的文件和软件 (可有可无)

mkdir lib mnt proc root sys tmp var

busybox的使用

关于busybox的使用,可查阅此文档

使用busybox制作根文件系统

busybox制作根文件系统
1. 配置交叉编译工具链

使用busyBox工具制作根文件系统需要使用gcc-4.6.4版本的交叉编译工具链,

需要重新配置交叉编译工具链

之前安装的就是这个版本,所以不需要再重新安装

在ubuntu的家目录(~)下,创建toolchain

mkdir toolchain

拷贝gcc-4.6.4.tar.xz到toolchain目录下

解压缩交叉编译工具链

tar -vxf gcc-4.6.4.tar.xz

配置环境变量

打开 sudo vi /etc/bash.bashrc

在最后一行添加以下内容:

export PATH=$PATH:/home/hqyj/toolchain/gcc-4.6.4/bin/

注意:修改为自己的路径(需要将gcc-4.5.1的注释掉)

使环境变量立即生效

source /etc/bash.bashrc

测试交叉编译工具链是否安装成功

切换完交叉编译工具链,ubuntu的终端需要重新开

arm-none-linux-gnueabi-gcc -v

打印以下内容,表示成功

gcc version 4.6.4 (Sourcery G++ Lite 2010.09-50)

2. 开始制作rootfs根文件系统

拷贝busybox-1.31.1.tar.bz2到ubuntu的家目录下

对根文件系统进行解压缩,并切换到busybox-1.31.1目录下

tar -vxf busybox-1.31.1.tar.bz2

cd busybox-1.31.1

3. 分析README ,没有获取太多重要的信息
4. 通过make help 获取编译的帮助信息(不用一一执行)

清除中间文件:(不用执行)

make clean (delete temporary files created by build)

make distclean (delete all non-source files (including .config))

编译 :

make all - Executable and documentation

通过图形化界面的配置:

make menuconfig (interactive curses-based configurator)

安装:

make install (install busybox into CONFIG_PREFIX)

卸载:

make uninstall

5. 修改Makefile,配置为交叉编译工具链

打开Makefile

将一下内容:

164 CROSS_COMPILE ?=

190 ARCH ?= $(SUBARCH)

修改为:

164 CROSS_COMPILE ?= arm-none-linux-gnueabi-

190 ARCH ?= arm

6. 执行make menuconfig 命令,对busybox进行配置

1》 使用静态库,不使用共享库,共享库的话当移植到板子上面的时候,就不能使用了

1、Settings --->

2、[*] Build static binary (no shared libs) (NEW)

2》 配置为vi风格的行编辑命令

1、Settings --->

2、[*] vi-style line editing commands (NEW)

3》 配置根文件系统的安装路径

Settings --->

(./_install) Destination path for 'make install'

修改./_install 为 /home/hq/rootfs

4》配置支持驱动模块化的命令

Linux Module Utilities --->

此前前边默认是*,将*修改为空

[ ] Simplified modutils

[*] depmod (27 kb) (NEW)

[*] insmod (22 kb) (NEW)

[*] lsmod (1.9 kb) (NEW)

[*] Pretty output (NEW)

[*] modinfo (24 kb) (NEW)

[*] modprobe (28 kb) (NEW)

[*] Blacklist support (NEW)

[*] rmmod (3.3 kb) (NEW)

7.对源码进行编译

make / make all

8.安装根文件系统到/home/hq/rootfs

执行:make install(回到顶层目录执行)

9.测试根文件系统,对根文件系统进行部署

1》首先将nfs目录的的rootfs跟换一个其他的名字

cd /opt/6818/rootfs/

mv rootfs rootfs-ok

2》将自己制作的rootfs文件拷贝到~/nfs

cp ~/rootfs/ ./ -raf

10. 重启开发板,测试rootfs是否可以正常使用

前提,使用tftp下载uImage 使用nfs挂载根文件系统

问题解决

都是在根文件系统(/opt/6818/rootfs/rootfs下操作)

1. 挂载成功,但是打印一下错误信息

解决办法:

cd /opt/6818/rootfs/rootfs/

创建dev文件夹,创建etc/init.d文件夹,

sudo mkdir dev

sudo mkdir -p etc/init.d

在etc/init.d目录下创建rcS文件

cd etc/init.d

sudo touch rcS

继续重启开发板,进行测试

2. 出现以下问题

can't run '/etc/init.d/rcS': Permission denied

此问题解决办法:修改rcS的权限最大

sudo chmod 777 rcS

在rcS文件中必须添加以下内容:

#!/bin/sh 
/bin/mount -a
echo /sbin/mdev > /proc/sys/kernel/hotplug 
/sbin/mdev -s 

解释:

mount -a:系统会自动解析fstab配置文件,系统根据

此配置文件进行一系列的挂接动作

echo /sbin/mdev > /proc/sys/kernel/hotplug:

向文件/proc/sys/kernel/hotplug写入字符串"/sbin/mdev" 其实就是告诉内核驱动将来创建设备文件的程序是/sbin/mdev

mdev -s:系统启动,将内核驱动对应的设备文件进行自动创建

can't open /dev/tty2: No such file or directory

can't open /dev/tty3: No such file or directory

can't open /dev/tty4: No such file or directory

此问题,后边会解决

再次重启开发板:

3. 在根文件系统的etc目录下创建文件fstab inittab

cd etc

touch fstab

touch initt

打开inittab文件添加以下内容:

::sysinit:/etc/init.d/rcS 
::askfirst:-/bin/sh
::restart:/sbin/init 
::ctrlaltdel:/sbin/reboot 

解释:系统启动的流程

打开fstab文件添加以下内容

#device mount-point type options dump fsck orde
proc /proc proc defaults 0 0
tpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0

解析:

第一列:设备类型

第二列:挂载点

第三列:类型

第4,5,6列:访问权限

再次重启开发板,基本上成功,

4. 创建其他文件

在根文件系统的顶层目录创建

mkdir lib mnt proc root sys tmp var

再次重启开发板,根文件系统制作成功。

5. 添加用户名

在根文件系统的etc目录下创建profile文件,

打开profile文件,添加以下内容:

export HOSTNAME=HQYJ    #可修改主机名
export USER=root        #可修改用户名
export HOME=root    #建议加绝对路径
#export PS1="\[\u@\h \W\]\$ "
#cd root
export PS1="[$USER@$HOSTNAME \W\]\# " 
PATH=/bin:/sbin:/usr/bin:/usr/sbin
LD_LIBRARY_PATH=/lib:/usr/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH

重启开发板

6. 移植共享库到根文件系统中

在ubuntu中创建test.c 编写以下代码 (也可直接在NFS中执行)

#include <stdio.h>
int main(int argc, char *argv[])
{
    printf("hello world!\n");
    return 0;
}

使用交叉编译工具链编译test.c生成test可执行程序

arm-none-linux-gnueabi-gcc test.c -o test

拷贝test可执行程序到新制作的文件系统中

cp test /opt/6818/rootfs/rootfs

重启开发板,在超级终端终端上,运行应用程序test

./test

出现以下错误提示:

问题原因:缺少应用程序运行必要的动态库

解决办法:将交叉编译工具链中的库,拷贝到根文件系统的lib目录

sudo cp ~/toolchain/gcc-4.6.4/arm-arm1176jzfssf-linux-gnueabi/sysroot/lib/* /opt/6818/rootfs/rootfs/lib/ -r
根文件系统(镜像)制作

根据实验文档进行进行实验

注意:交叉编译工具链,132M,太大,不往板子里面装交叉编译工具链

  • 9
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值