怎样移植u-boot和linux到s3c2440开发板
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎样移植u-boot和linux到s3c2440开发板相关的知识,希望对你有一定的参考价值。
uboot最主要的功能就是能够引导内核启动。本文就介绍如何实现该功能,并组成一个最简单的系统,这不仅要移植uboot,还要移植linux内核及创建一个根文件系统。首先我们对nandflash进行分区,规划好每个文件存放在nandflash的位置。下面是nandflash的分区:
第0分区:0x000000000000-0x000000080000为uboot区
第1分区:0x000000080000-0x000000100000为参数区
第2分区:0x000000200000-0x000000600000为linux内核区
第3分区:0x000000800000-0x000001000000为根文件系统区
规划好分区后,我们就可以依次完成uboot的移植,linux内核的移植,及创建一个根文件系统。我们选择cramfs作为根文件系统。
一、uboot移植
1.修改机器码,要保证uboot与linux内核的机器码一致,这样才能启动内核。
修改board/samsung/zhaocj2440/zhaocj2440.c文件中的第116行内容,把SMDK2410改为SMDK2440,即:
gd->bd->bi_arch_number = MACH_TYPE_SMDK2440;
因为我们的uboot移植是以uboot自带的SMDK2440开发板为模板的,所以我们还是按照SMDK2440的机器码来移
植,MACH_TYPE_SMDK2440的具体数值在arch/arm/include/asm/mach-types.h文件的第1013行已有定
义:
#define MACH_TYPE_SMDK2440 1008
2.添加bootcmd和bootargs参数。其中bootcmd是为了引导内核,而bootargs是为了在加载根文件系统时,给根文件系统传递必要的参数。
可以有两种方法来设置这两个参数:
第一种方法是在uboot的提示符下直接设置bootcmd和bootargs这两个参数:
ZHAOCJ2440 # setenv bootcmd ' nand read 31000000 200000 400000; bootm 31000000 '
ZHAOCJ2440 # setenv bootargs ' root=/dev/mtdblock3 ro noinitrd
init=/linuxrc console=ttySAC , 115200 rootfstype=cramfs mem=64M'
ZHAOCJ2440 # saveenv
在这里bootcmd的含义是从nandflash中读取kernel,然后利用命令bootm启动。bootargs的含义是在
nandflash中的第3个分区内存放着根文件系统,它的格式是cramfs。最后还要应用saveenv命令来保存这两个变量。这时,如果你在提示符
下敲入printenv命令,则会看到uboot的环境参数多了两项,如:
bootargs=root=/dev/mtdblock3 ro noinitrd init=/linuxrc console=ttySAC,115200 rootfstype=cramfs mem=64M
bootcmd=nand read 31000000 200000 400000 ; bootm 31000000
第二种方法是在include/configs/zhaocj2440.h内定义CONFIG_BOOTARGS和CONFIG_BOOTCOMMAND这两个宏定义:
#define CONFIG_BOOTARGS " root=/dev/mtdblock3 ro noinitrd init=/linuxrc console=ttySAC , 115200 rootfstype=cramfs mem=64M"
#define CONFIG_BOOTCOMMAND " nand read 31000000 200000 400000 ; bootm 31000000"
3.把移植好的uboot烧写到nandflash中的0x00000000至0x000000080000内。
二、linux内核移植
这里我们实现的是最简单的移植,即能够启动即可。
1.在下列网址下载linux内核,linux-3.4.6.tar.bz2
www.kernel.org/pub/linux/kernel/v3.x/
解压到当前目录:
tar -xvjf linux-3.4.6.tar.bz2
2.修改主目录下的Makefile文件,第195行和第196行改写为:
ARCH ?=arm
CROSS_COMPILE ?= arm-linux-
3.添加机器码,使uboot与linux机器码一致,并改变内核时钟
在arch/arm/tools/mach-types文件的第207行添加下列代码:
smdk2440 MACH_SMDK2440 SMDK2440 1008
在arch/arm/mach-s3c24xx/mach-smdk2440.c文件内
第165行中的16934400改为12000000,即
s3c24xx_init_clocks(12000000);
第178行中的S3C2440改为SMDK2440,即
MACHINE_START(SMDK2440,"SMDK2440")
4.修改内核中的分区,使其与我们事先定义的分区一致
在arch/arm/mach-s3c24xx/common-smdk.c文件内
第111行中的smdk_default_nand_part结构体改为:
static struct mtd_partition smdk_default_nand_part[ ] =
[0]=
.name = "UBoot",
.size = SZ_512K,
.offset = 0,
,
[1]=
.name = "Para",
.offset= SZ_512K,
.size = SZ_512K,
,
[2]=
.name = "Kernel",
.offset= SZ_2M,
.size = SZ_4M,
,
[3]=
.name = "rootfs",
.offset = SZ_8M,
.size = SZ_8M,
;
5.改变内核的ECC类型
在drivers/mtd/nand/s3c2410.c文件内
第846行中的NAND_ECC_SOFT改为NAND_ECC_NONE,即:
chip->ecc.mode = NAND_ECC_NONE;
此处如果不改,虽然能够启动linux内核,但无法加载根文件系统。
6.编译内核
退回到linux-3.4.6的根目录下,复制配置文件:
cp arch/arm/configs/s3c2410_defconfig .config
使用menuconfig来配置内核:
make menuconfig
在KernelFeatures下选上两项内容,即
Kernel Features --->
[*]Use the ARM EABI to compile the kernel
[*]Allow old ABI binaries to run with this kernel (EXPERIMENTAL)
如果不选择这两项,则在内核启动完,挂载根文件系统时会出现kernel panic:attempted to kill init的错误。
menuconfig的其他内容可以不需要改变,选择默认即可。
最后执行下面两个命令:
make clean
make zImage
等待一段时间后,在arch/arm/boot/目录下会生成zImage文件。
7.制作内核镜像
在上一步虽然我们已经生成了zImage文件,但它还不能被uboot正确引导,我们还需要给zImage文件加上64个字节的数据头,这部分内容
包括CPU架构(A)、操作系统(O)、镜像类型(T)、压缩类型(C)、镜像名称(n)、镜像加载地址(a)、镜像入口(e)、源文件(d)。只有加上
这些内容uboot才能正确引导内核。
mkimage工具就是uboot用来制作完成上述内容的工具。编译过uboot后,会在tools目录下生成mkimage。为了更方便地应用该工具,我们需要完成下列操作,进入tools目录,以根用户的身份执行下列命令:
cp mkimage /usr/bin
chmod 777 /usr/bin/mkimage
进入linux-3.4.6目录下的arch/arm/boot/目录,执行下列命令:
mkimage -n 'linux' -A arm -O linux -T kernel -C none -a 0x31000000 -e 0x31000040 -d zImage uImage.img
uImage.img为最终我们需要烧写到nandflash中的文件。在这里,我们是把镜像加载到内存0x31000000地址内的。
8.最后,我们把uImage.img文件烧写到nandflash中的0x200000至0x600000中。 参考技术A 网上直接找现成补丁好多的什麼100ask啦 参考技术B U八月就没什么意思了
Linux系统移植:U-Boot常用指令(下)
文章目录
Linux系统移植:U-Boot常用指令(下)
一、U-Boot 常用命令(上)
1.1 EMMC和SD卡命令
uboot 支持 EMMC 和 SD 卡,提供 EMMC 和 SD 卡的操作命令
mmc 指令
命令 | 描述 |
---|---|
mmc info | 输出 MMC 设备信息 |
mmc read | 读取 MMC 中的数据 mmc read addr blk# cnt addr 是数据读取到 DRAM 中的地址,blk 是要读取的块起始地址(十六进制),一个块是 512 字节,这里的块和扇区是一个意思,在 MMC 设备中我们通常说扇区,cnt 是要读取的块数量(十六进制) |
mmc wirte | 向 MMC 设备写入数据 mmc write addr blk# cnt addr 是要写入 MMC 中的数据在 DRAM 中的起始地址,blk 是要写入 MMC 的块起始地址 (十六进制),cnt 是要写入的块大小 |
mmc erase | 擦除 MMC 设备的指定块 mmc erase blk# cnt blk 为要擦除的起始块,cnt 是要擦除的数量,不要乱用 mmc erase 来擦除 MMC 设备! |
mmc rescan | 扫描 MMC 设备,扫描当前开发板上所有的 MMC 设备,包括 EMMC 和 SD 卡 |
mmc part | 列出 MMC 设备的分区 |
mmc dev | 切换 MMC 设备,用于切换当前 MMC 设备 mmc dev 0 切换到 SD 卡,0 为 SD 卡,1 为 eMMC |
mmc list | 列出所有有效的 MMC 设备,查看当前开发板一共有几个 MMC 设备 |
mmc hwpartition | 设置 MMC 设备的分区 |
mmc bootbus…… | 设置指定 MMC 设备的 BOOT_BUS_WIDTH 域的值 |
mmc bootpart…… | 设置指定 MMC 设备的 boot 和 RPMB 分区的大小 |
mmc partconf…… | 设置指定 MMC 设备的 PARTITION_CONFG 域的值 |
mmc rst | 复位 MMC 设备 |
mmc setdsr | 设置 DSR 寄存器的值 |
千万不要写 SD 卡或者 EMMC 的前两个块(扇区),里面保存着分区表
1.2 FAT 格式文件系统命令
对于 FAT 格式文件系统的 emmc 文件,uboot 有 fatinfo、fatls、fstype、fatload 和 fatwrite 相关操作命令
1.2.1 fatinfo 命令
令用于查询指定 MMC 设置指定分区的文件系统信息
fatinfo <interface> [<dev[:part]>]
interface 表示接口,比如 mmc,dev 是查询的设备号,part 是要查询的分区
1.2.2 fatls命令
查询 FAT 格式设备的目录和文件信息
fatls <interface> [<dev[:part]>] [directory]
interface 是要查询的接口,比如 mmc,dev 是要查询的设备号,part 是要查询的分区,directory 是要查询的目录
eg:查询分区1的文件
1.2.3 fstype 命令
查看 MMC 设备某个分区的文件系统格式
fstype <interface> <dev>:<part>
eg:查询emmc三个分区的文件系统
分区 0 格式未知,因为分区 0 存放的 uboot,并且分区 0 没有格式化,所以文件系统格式未知
分区 1 的格式为 fat,分区 1 用于存放 linux 镜像和设备树
分区 2 的格 式为 ext4,用于存放 Linux 的根文件系统(rootfs)
1.2.4 fatload 命令
将指定的文件读取到 DRAM 中
fatload <interface> [<dev[:part]> [<addr> [<filename> [bytes [pos]]]]]
interface 为设备接口,比如 mmc,dev 是设备号,part 是分区,addr 是保存在 DRAM 中的起始地址,filename 是要读取的文件名字。bytes 表示读取多少字节的数据,如果 bytes 为 0 或者省 略的话表示读取整个文件。pos 是要读的文件相对于文件首地址的偏移,如果为 0 或者省略的 话表示从文件首地址开始读取
eg:将 EMMC 分区 1 中的 zImage 文件读取到 DRAM 中的 0X80800000 地址处
1.2.5 fatwrite 命令
将 DRAM 中的数据写入到 MMC 设备中(使用前需要修改板子配置头文件,使能写文件系统,使能如下)
#define CONFIG_FAT_WRITE
fatwrite 格式
fatwrite <interface> <dev[:part]> <addr> <filename> <bytes>
interface 为接口,比如 mmc,dev 是设备号,part 是分区,addr 是要写入的数据在 DRAM 中的起始地址,filename 是写入的数据文件名字,bytes 表示要写入多少字节的数据
1.3 EXT 格式文件系统命令
uboot 有 ext2 和 ext4 这两种格式的文件系统的操作命令,常用的就五个命令,分别为: ext2load、ext2ls、ext4load、ext4ls 和 ext4write
命令 | 功能 |
---|---|
ext2load | 从 ext2 文件系统中读文件数据 |
ext2ls | 以查询文件和目录 |
ext4load | 从 ext4 文件系统中读文件数据 |
ext4ls | 以查询文件和目录 |
ext4write | 写文件数据 |
1.4 NAND 操作命令
uboot 是支持 NAND Flash 的,所以也有 NAND Flash 的操作命令,我的开发板没有 nand ,使用没有 nand 操作指令,这里做简单介绍
1.4.1 nand info命令
打印 NAND Flash 信息
1.4.2 nand device命令
用于切换 NAND Flash
1.4.3 nand erase命令
nand erase 命令用于擦除 NAND Flash,在向 NAND Flash 写数据 之前一定要先对要写入的区域进行擦除
nand erase[.spread] [clean] off size //从指定地址开始(off)开始,擦除指定大小(size)的区域。
nand erase.part [clean] partition //擦除指定的分区
nand erase.chip [clean] //全篇擦除
1.4.4 nand write命令
向 NAND 指定地址写入指定的数据,一般和 nand erase 命令配置使用来更新 NAND 中的 uboot、linux kernel 或设备树等文件
nand write addr off size
1.4.5 nand read命令
从 NAND 中的指定地址读取指定大小的数据到 DRAM 中
nand read addr off size
1.4.6 正点原子 NAND 介绍
I.MX6U-ALPHA 开发板出厂系统 NAND 分区如下
0x000000000000-0x0000003FFFFF : "boot"
0x000000400000-0x00000041FFFF : "env"
0x000000420000-0x00000051FFFF : "logo"
0x000000520000-0x00000061FFFF : "dtb"
0x000000620000-0x000000E1FFFF : "kernel"
0x000000E20000-0x000020000000 : "rootfs"
第一个分区存放 uboot,地址范围为 0x0~0x3FFFFF(共 4MB);
第二个分 区存放 env(环境变量),地址范围为 0x400000~0x420000(共 128KB);
第三个分区存放 logo(启 动图标),地址范围为 0x420000~0x51FFFF(共 1MB);
第四个分区存放 dtb(设备树),地址范围为 0x520000~0x61FFFF(共 1MB);
第五个分区存放 kernel(也就是 linux kernel),地址范围为 0x620000~0xE1FFFF(共 8MB);
最后一个分区,存放 rootfs(根文件系统)
1.5 BOOT操作命令
uboot 有相关的 boot (引导)命令来启动 Linux,常用的跟 boot 有关的命令有:bootz、bootm 和 boot
1.5.1 bootz 命令
将 Linux 镜像和设备树文件存到 DRAM 中就行,然后使用 bootz 命令来启动
bootz [addr [initrd[:size]] [fdt]]
addr 是 Linux 镜像文件在 DRAM 中的位置,initrd 是 initrd 文件在 DRAM 中的地址,如果不使用 initrd 的话使用‘-’代替即可,fdt 就是设备树文件在 DRAM 中 的地址
如果我们要启动 Linux 系统的话,只需要使用命令 fatload 将 zImage 和设备树文件从 EMMC 的分区 1 中拷贝到 DRAM 中,然后使用命令 bootz 启动即可
1.5.2 bootm 命令
bootm 和 bootz 功能类似,但是 bootm 用于启动 uImage 镜像文件
只启动内核指令格式
bootm addr
addr 是 uImage 镜像在 DRAM 中的首地址
启动内核同时使用设备树指令
bootm [addr [initrd[:size]] [fdt]]
addr 是 uImage 在 DRAM 中的首地址,initrd 是 initrd 的地址,fdt 是设备树(.dtb)文件 在 DRAM 中的首地址
1.5.3 boot 命令
boot 命令也是用来启动 Linux 系统的,只是 boot 会读取环境变量 bootcmd 来启动 Linux 系统
bootcmd 是一个很重要的环境变量,这个环境变量保存着引导命令,就是启动的命令集合
bootcmd 很重要,比如我们要想使用 tftp 命令从网络启动 Linux 那么就可以设置 bootcmd 为
“tftp 80800000 zImage; tftp 83000000 imx6ull-14x14-emmc-7-1024x600-c.dtb; bootz 80800000 - 83000000”
然后使用 saveenv 将 bootcmd 保存起来,然后直接输入 boot 命令即可从网络启动 Linux 系统
uboot 倒计时结束以后就启动 Linux 系统,其实就是执行的 bootcmd 中的启动命令!
对原子开发板来说,如果不修改 bootcmd 的话,每次开机 uboot 倒计时结束以后都会自动从 EMMC 里面读取 zImage 和 imx6ull-14x14-emmc-7-1024x600-c.dtb,然后启动 Linux
1.6 其他常用命令
1.6.1 reset 命令
reset 命令顾名思义就是复位的,输入“reset”即可复位重启
1.6.2 go 命令
go 命令用于跳到指定的地址处执行应用
go addr [arg ...]
addr 是应用在 DRAM 中的首地址
1.6.3 run 命令
run 命令用于运行环境变量中定义的命令,比如可以通过 run bootcmd 来运行 bootcmd 中 的启动命令,但是 run 命令最大的作用在于运行我们自定义的环境变量
run 环境变量
1.6.4 mset 命令
mtest 命令是一个简单的内存读写测试命令,可以用来测试自己开发板上的 DDR
mtest [start [end [pattern [iterations]]]]
start是要测试的DRAM 开始地址,end 是结束地址,比如我们测试 0X80000000~0X80001000 这段内存
mtest 80000000 80001000
这里我测试了 284 次
以上是关于怎样移植u-boot和linux到s3c2440开发板的主要内容,如果未能解决你的问题,请参考以下文章