支持6410从SD卡启动的Uboot

2012-01-16 由 创建在标签 开发

友善提供的Superboot确实很好用,但是samsung提供的uboot版本比较低,从友善的官网也看到对应的uboot介绍,了解到它启动的时候并不能很好地支持SD卡,尤其是SDHC的支持很不好,那个是因为uboot版本太低,而且SD卡也不能超过2G。最让人头疼的是不能从SD卡直接启动系统,只能将img拷贝到NAND,然后再从NAND中启动(参考友善官网6410的bootloader介绍)。对于想定制自己的Bootloader人就会遇到想不到的麻烦,所以就想着找一个能够很好支持SD卡启动Linux的Uboot。

SD/MMC的启动原理

要想知道启动的原理,就必须先了解芯片的特性和它的启动过程,需要查看厂商提供的Datasheet和芯片相关的资料。对于6410,samsung提供了一份启动相关的文档——《SMDK6410_IROM_APPLICATION NOTE_REV 1.00》,想了解的人可以自己在网上搜一下,我只简单说一下我看了之后对我比较有用的东西,肯定会有信息遗漏。

6410最开始启动的时候先执行固化在芯片里面的代码,iRom(BL0)它所做的事情很简单,主要完成系统时钟、堆栈、设备控制器和启动设备标识的初始化,确定下一阶段(BL1)的启动设备和起始地址,拷贝BL1到启动区域,然后将执行权交给启动区域,开始BL1的执行。其中iRom初始化了很多函数指针和全局变量,这些都为BL1阶段的执行和代码的拷贝做好准备;6410通过从引脚来判断是从Nand还是从SD卡拷贝数据的,在6410中就有一个开关来选择是从NAND还是从SD卡启动的。BL1就已经是Bootloader的代码了,但是BL1的大小是有8k的限制,不能完成所有的Bootloader的工作,还需要BL2的配合才能真正完成所有的引导过程。

Uboot的移植

其实写到这里就已经没有多少我的东西了,因为自己并没有真正去移植,所以后面说的有点人云亦云,我只是从网上下了一份tekkamanninja移植好的代码(亲自测试,可以运行,运行时有启动背景),自己做了一些比较,说说他的这份代码是如何移植的,而且作者的博客上也有很多关于Uboot移植的代码和一些关于这方面原理的分析。如果有机会自己移植的话再写一些关于Uboot移植的东西。

/u-boot-2011.06mini6410/arch/arm/include/asm/arch-s3c64xx
# ls -l
total 80
-rw-rw-r--. 1 root root 1995 Sep  7 07:30 hardware.h
-rw-rw-r--. 1 root root 2066 Sep  7 07:30 mmc.h
-rw-rw-r--. 1 root root 13667 Sep  7 07:30 regs-fb.h
-rw-rw-r--. 1 root root 5470 Sep  7 07:30 regs-fb-v4.h
-rw-rw-r--. 1 root root 36503 Sep  7 07:30 s3c6400.h
-rw-rw-r--. 1 root root 9205 Sep  7 07:30 s3c64x0.h

上面列出了初始化时需要调用的一些公共函数、结构体、宏等相关的声明,主要增加了SD卡和mini6410的LCD支持,完成他们的初始化,使得开机时能够显示Logo、背景以及SD卡启动系统。

/u-boot-2011.06mini6410/arch/arm/cpu/arm1176
# ls -l
total 56
-rw-rw-r--. 1 root root 1319 Sep  7 07:30 config.mk
-rw-rw-r--. 1 root root 1717 Sep  7 07:30 cpu.c
-rw-rw-r--. 1 root root 1496 Sep  7 07:30 Makefile
drwxrwxr-x. 2 root root 4096 Jan 14 00:26 s3c64xx
-rw-rw-r--. 1 root root 15078 Sep  7 07:30 start.S
-rw-rw-r--. 1 root root 1712 Sep  7 07:30 u-boot.lds
# cd s3c64xx/
# ls -l
total 76
-rw-rw-r--. 1 root root 1319 Sep  7 07:30 config.mk
-rw-rw-r--. 1 root root 5424 Sep  7 07:30 cpu_init.S
-rw-rw-r--. 1 root root 1459 Sep  7 07:30 Makefile
-rw-rw-r--. 1 root root 1109 Sep  7 07:30 reset.S
-rw-rw-r--. 1 root root 3441 Sep  7 07:30 speed.c
-rw-rw-r--. 1 root root 4363 Sep  7 07:30 timer.c

上面列出了与芯片有关的初始化代码,作者修改了cpu_init.S和start.S,其中cpu_init.S主要是自动检测内存大小的代码(参考Mini6410自动识别内存大小);star.S主要是增加启动时自动检测内存、确定是从SD卡还是从NAND启动以及LED功能。

/u-boot-2011.06mini6410/arch/arm/lib
# ls -l
-rw-rw-r--. 1 root root 17540 Sep  7 07:30 board.c

上面列出了lib中修改了的文件,它的修改主要是为了添加LED功能。

/u-boot-2011.06mini6410/drivers/mmc
# ls -l
-rw-rw-r--. 1 root root 24139 Sep  7 07:30 mmc.c
-rw-rw-r--. 1 root root 11091 Sep  7 07:30 s3c64x0_mmc.c

上面新增了s3c64x0_mmc.c文件,它主要完成6410 SD卡的初始化;mmc.c主要添加了一些打印信息。

/u-boot-2011.06mini6410/drivers/video
# ls -l
total 552
-rw-rw-r--. 1 root     root     49102 Sep  7 07:30 cfb_console.c
-rw-rw-r--. 1 root     root      9151 Jan 14 00:14 s3c64x0_fb.c
-rw-rw-r--. 1 root     root      8945 Sep  7 07:30 videomodes.c
-rw-rw-r--. 1 root     root      3480 Sep  7 07:30 videomodes.h

上面主要增加了对LCD的支持,支持开机时使用友善的上自带的LCD,可以显示开机Logo和背景。

/u-boot-2011.06mini6410/mmc_spl/board/samsung/mini6410
# ls -l
lrwxrwxrwx. 1 root     root       86 Jan  5 22:58 cpu_init.S
lrwxrwxrwx. 1 root     root       85 Jan  5 22:58 lowlevel_init.S
-rw-rw-r--. 1 root     root     2417 Sep  7 07:30 mmc_boot.c
lrwxrwxrwx. 1 root     root       75 Jan  5 22:58 start.S
-rw-rw-r--. 1 root     root     1725 Sep  7 07:30 u-boot.lds

上面这个目录为新增目录,它们就是针对mini6410启动初始化的过程,其实cpu_init.S等汇编代码其实只是上面体系结构目录下的符号链接,它们将烧写在BL1中,作为iRom执行后第一个执行的部分,主要就是完成初始化,并调用mmc_boot.c中的初始化函数,其中copy_uboot_to_ram函数从BL2中拷贝代码到内存,并跳转到对应的区域执行,从而进入BL2的代码段执行。

其他修改过的文件都只是一些配置相关的,因为作者增加了很多新的功能,所以在编译的时候还需要让其他部分也编译进去。

烧写Uboot

在Linux中可以通过命令和网友Amankwah提供的工具(下载地址)。但是在使用的时候要获得root权限,我在Fedora下面也是可以正常工作的。但是在使用的时候注意将BL1的目录选择mmc_spl目录下,否则默认的是NAND那个目录下。烧写的命令如下:

$ sudo fdisk /dev/sdb

Command (m for help): p
Disk /dev/sdb: 7969 MB, 7969177600 bytes
246 heads, 62 sectors/track, 1020 cylinders
Units = cylinders of 15252 * 512 = 7809024 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1   *           1           6       45755+   b  W95 FAT32
/dev/sdb2   *           7        1020     7732764   83  Linux

##################################################################
# 所以总块数是7969177600/512=15564800
# IROM所认为的总块数15563776(15564800-1024)(仅在SDHC时需要减去1024)
# 所以nand_spl/u-boot-spl-16k.bin烧写的位置是15563758块(15563776-18)
# u-boot.bin烧写的位置是15557632块(15563776-6144(3MB))(根据我的Uboot配置文件)
###################################################################
# 烧写命令:
sudo dd if='(Uboot源码)/nand_spl/u-boot-spl-16k.bin'     of=/dev/(SD卡的设备节点) bs=512   seek=15563758
sudo dd if='/(Uboot源码)/u-boot.bin'      of=/dev/(SD卡的设备节点) bs=512   seek=15557632

其实觉得友善的Superboot和这个应该差不多,友善的烧写工具应该也是将他们分成两步来做的,因为我用这个版本的Uboot编译后用友善的烧写工具烧写发现打开的文件格式错误,再加上看了6410的启动过程,所以感觉友善的编译出来的Uboot和Superboot应该是将两个打包成一个了,然后在烧写时再做区分,分别写到对应的区域中去。

现在我已经用网友提供的 Uboot引导成功,能够正常进入了,也设置了开机画面和背景。其实这篇文章主要是参考的别人的博客,自己只是把别人的博客和代码拿过来整理了一下,希望能够对6410学习的人和想移植Uboot的人有所帮助。

参考网站

Tekkaman Ninja的博客

标签:, , ,

一条评论

  • Excellent information however I’d like to let you know that I think there is problem with your RSS feeds as they seem to not be working for me. May be just me but I thought overall I would cite it.
    [url=http://www.digitalcamerabuzz.com]Digital SLR Reviews[/url]

发表评论