下载:
u-boot.bin
u-boot-1.1.6-mini2440.tar.gz
同学买了一块FriendlyARM(友善之臂)做的mini2440的板子,板上有友善之臂自己扩展的SuperVIVI,很简便易用的一个bootloader,特别是菜单功能做的很贴心。然而美中不足的是,SuperVIVI需要通过USB来更新NAND上的内容,这个USB驱动却又只支持Windows 2000(Windows XP勉强能用),但我的同学现在只有MacOS X和Vista机器了,用起来很是不便。
友善之臂提供了一个u-boot,心想刷到NAND上就好了,用不了几分钟。于是我考虑给他的mini2440换上网络功能强大的u-boot。显然后面的进展远没有这么顺利,不然就不会特别来记述一番了。
刷上自带的u-boot后,发现MTD的分区很怪异,kernel区是从0开始的。心想,不至于有这么怪异的错误留在这里吧,几秒种后恍然大悟,原来mini2440板上有NOR和NAND 2个存储器,这个u-boot是为NOR准备的。好吧,自己动手改改。
找到源代码,发现居然还是1.1.6,真够老的。上友善之臂的网站去下载,发现依然是1.1.6,这个…难道u-boot不受欢迎?不过我在友善之臂的网站上发现了移植好的2.6.29的内核,可以顺便拿来试试。
友善之臂用的是open24x0的config,修改了u-boot-1.1.6/include/configs/open24x0.h,重新安排了MTD的分区,并使u-boot采用NAND来存放env。然后修改linux-2.6.29/arch/arm/plat-s3c24xx/common-friendly-arm.c,把MTD的分区信息调整成与u-boot的一致。然后编译,刷写NAND,关掉板子,默默祈祷了一下之后,满怀希望的按下红色的电源开关…果然,启动不了。
串口console上打印出来的信息,停在了”done, booting the kernel.”。也就是说,解压缩成功了,也许是跳转到入口失败了,也许是在打印出”Linux version”之前出了什么问题。当然,也有可能是信息没有打印到串口console上。可惜手边没有仿真器,瞎猜没有用。mini2440的板子应该有不少用户,这些用户中应该不止一个人试过u-boot。Google一下吧。
看来这个问题还真不止我一个人遇到过,不过大家似乎都选择自己重新移植u-boot,而不是修正原有的u-boot 1.1.6。这个活儿太花时间了,不行,继续Google。在继续Google了近一个小时之后,总结大家的问题一般是3种情况:
- console设置没有传递到内核
- u-boot的时钟设置不在405MHz,与Kernel的不一致
- Machine ID设置的与Kernel不一致
第1种情况可以排除,我设置了CMDLINE。第2种情况,检查了u-boot-1.1.6/board/open24x0/boot_init.c,貌似也没问题。看来是Machine ID的问题。
查看u-boot-1.1.6/board/open24x0/open24x0.c与linux-2.6.29/include/asm/mach-types.h,发现Machine ID果然设置的不对。mini2440的ID是1999,而u-boot中设置的是三星官方的362。改完,刷写,重启。
依然不灵。
这就有点土了。没有仿真器,没有打印信息,我和mini2440之间又不能通过脑电波交流…冥思苦想中,我进入了准无意识状态,大脑在迷惘,手指在不停地用NOR或者NAND启动mini2440。突然,我感到有什么东西不对。隐隐约约的,我似乎看到了什么东西,不应该出现的东西。定定神,一行一行地翻看串口console日志,貌似每一行都很正常,但最后我停在了SuperVIVI启动的一行语句上面:”Machine ID: 782″。
782?为什么会是782?我grep了一下linux-2.6.29/include/asm/mach-types.h,782是MACH_TYPE_PNX4008。先不想那么多,改成782试试。改完,刷写,重启。
Kernel成功启动了。
回过头研究782,不由哑然失笑。原来是这个linux-2.6.29移植的有点潦草,defconfig中的宏定义前后不一致,使得Machine ID没有设置为预想的值。好吧,这个问题就留在这里吧,也是一种不和谐美。
附linux-2.6.29/arch/arm/plat-s3c24xx/common-friendly-arm.c中的MTD分区设置:
static struct mtd_partition friendly_arm_default_nand_part[] = { [0] = { .name = “boot”, .size = 0×00040000, .offset = 0, }, [1] = { .name = “env”, .offset = 0×00040000, .size = 0×00010000, }, [2] = { .name = “kernel”, .offset = 0×00050000, .size = 0×00200000, }, [3] = { .name = “root”, .offset = 0×00250000, .size = 0x03db0000, } };