主题 : mini2440使用uboot(详细) 复制链接 | 浏览器收藏 | 打印
水滴石穿,绳锯木断
级别: 新手上路
UID: 14892
精华: 0
发帖: 3
金钱: 15 两
威望: 3 点
贡献值: 0 点
综合积分: 6 分
注册时间: 2010-02-24
最后登录: 2010-10-19
楼主  发表于: 2010-04-17 16:03

 mini2440使用uboot(详细)

管理提醒: 本帖被 kasim 执行加亮操作(2012-03-20)
文章写于2010.4.17,总结了友善之臂的mini2440开发板使用自带uboot的具体方法,希望能对正在使用mini2440开发板,而且又想使用uboot引导系统的朋友们有所帮助。
Google一下会发现网上类似的帖子不少,但是对mini2440开发板是哪一个版本都没有具体的说明,个人感觉mini2440开发板的版本是经常更新的,可能不同的版本的开发板在移植uboot时会稍有不同,因此这里我把自己使用的开发板的详细信息都罗列一下,希望网友少走弯路。
另外,要感谢illidan和Martin两位的文章:
http://www.martinliu.info/2009/05/mini2440使用u-boot/
http://www.ardendev.com/bbs/viewthread.php?tid=14

使用的mini2440开发板的详细信息:
kernel:linux-2.6.29-mini2440-20090708.tgz
gcc:arm-linux-gcc-4.3.2.tgz
uboot:bootloader.tgz(该压缩包内含有u-boot-1.1.6)
roots:root_qtopia-64M.img
注:我的nand flash由原来的128M换成了64M。

问题源于:
(1)使用128M NAND Flash mini2440开发板的用户都知道,此时开发板附带的supervivi-64M和supervivi-128M都不再支持“空格”进入supervivi的menu菜单,而是改成了使用开发板上的k1~k6任何一个按键触发进入menu(而我需要空格键触发menu的方式);
(2)开发板附带的supervivi不支持网络下载kernel和root(文件系统)。

具体的修改步骤如下:
注1:arm-linux-gcc的安装方法见《mini2440-um-20090817.pdf》第5.3小节。
注2:mini2440开发板附带的uboot源码已经是经过移植的,适用s3c2440处理器,我们只需要修改一些uboot参数即可。

一、修改uboot源码
(1)解压出源码
创建工作目录
mkdir /tmp/workspace
cd /tmp/workspace
解压mini2440开发板光盘附带的uboot源码,bootloader.tgz同时包含了u-boot-1.1.6和vivi的源码
tar -xvf bootloader.tgz
cd u-boot-1.1.6
(2)修改u-boot-1.1.6/include/configs/open24x0.h文件

修改NAND FLASH MTD分区表:

56 /*
57 #define MTDPARTS_DEFAULT "mtdparts=nandflash0:2m@0(kernel)," \
58                             "8m(jffs2)," \
59                             "-(yaffs)"
60 */
61 #define MTDPARTS_DEFAULT "mtdparts=nandflash0:" \
62                          "256k@0(boot)," \
63                          "64k(env)," \
64                          "2m(kernel)," \
65                          "-(yaffs)"

注:该分区表一定要与内核中的分区表一致,后面我会给出kernel中分区表的修改。


修改内核启动参数:
把“mtdblock2” 改为“ mtdblock3

133 //#define CONFIG_BOOTARGS       "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0"
134 #define CONFIG_BOOTARGS         "noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0"
注:此处一定要改,否则文件系统会加载失败(此处是让我最痛苦的地方,费了大量时间才找到这个症结所在)


修改env参数保存位置:

221 //#define       CFG_ENV_IS_IN_FLASH     1
222 #define CFG_ENV_IS_IN_NAND  1
223 #define CFG_ENV_OFFSET          0x40000
224 #define CFG_ENV_SIZE            0x10000 /* Total Size of Environment Sector */
注1:env是uboot引导系统时用到的一系列参数,是可修改的,如果不改动此处,env修改后,即使执行saveenv命令,断电后也会丢失。
注2:注意一下223和224行,这两行定义了env保存在nand flash的具体位置,与MTD分区表中的"64k(env)," 是对应的(64K=0x40000 - 0x10000)。


(3)修改u-boot-1.1.6/include/asm-arm/mach-types.h文件
修改machine ID

377 //#define MACH_TYPE_S3C2440              362
378 #define MACH_TYPE_S3C2440              1999

注1:查看linux-2.6.29/include/asm/mach-types.h会发现machine ID为1999
1985 #define MACH_TYPE_MINI2440             1999
注2:对于此处的修改Martin给出了他的经验:

“查看u-boot-1.1.6/board/open24×0/open24×0.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没有设置为预想的值。好吧,这个问题就留在这里吧,也是一种不和谐美。”


注3:Martin用的可能是较老的mini2440开发板,我这一版已经解决了他提的这个问题,如果跟我的kernel一样,应该改为1999。

(4)修改uboot功能菜单,增加tftp下载功能选项
修改u-boot-1.1.6/common/cmd_menu.c文件,

在原文件中添加146~149行:

142 void main_menu_usage(void)
143 {
144     printf("\r\n##### uboot for mini2440 #####\r\n");
145
146     printf("[1] TFTP Install U-boot\r\n");
147     printf("[2] TFTP Install Linux kernel\r\n");
148     printf("[3] TFTP Install JFFS2 root\r\n");
149     printf("[4] TFTP Install YAFFS root\r\n");

150     printf(" Download u-boot\r\n");
151
152 #ifdef CONFIG_SURPORT_WINCE
153         printf("[e] Download Eboot\r\n");
154 #endif
155     printf("[k] Download Linux kernel\r\n");
156 #ifdef CONFIG_SURPORT_WINCE
157     printf("[w] Download WinCE NK.bin\r\n");
158 #endif
159     printf("[j] Download JFFS2 image\r\n");
160     printf("[y] Download YAFFS image\r\n");
161     printf("[d] Download to SDRAM & Run\r\n");
162     printf(" Boot the system\r\n");
163     printf("[f] Format the Nand Flash\r\n");
164     printf("[s] Set the boot parameters\r\n");
165     printf("[r] Reboot u-boot\r\n");
166     printf("[q] Quit from menu\r\n");
167     printf("Enter your selection: ");
168 }


在原文件menu_shell函数中添加200~235行


171 void menu_shell(void)
172 {
173     char c;
174     char cmd_buf[200];
175     char *p = NULL;
176     unsigned long size;
177     unsigned long offset;
178     struct mtd_info *mtd = &nand_info[nand_curr_device];
179
180     while (1)
181     {
182         main_menu_usage();
183         c = awaitkey(-1, NULL);
184         printf("%c\n", c);
185         switch (c)
186         {
187             case 'u':
188             {
189                 if (bBootFrmNORFlash())
190                 {
191                     strcpy(cmd_buf, "usbslave 1 0x30000000; protect off all; erase 0 +$(filesize); cp.b 0x30000000 0 $(filesize)");
192                 }
193                 else
194                 {
195                     strcpy(cmd_buf, "usbslave 1 0x30000000; nand erase bios; nand write.jffs2 0x30000000 bios $(filesize)");
196                 }
197                 run_command(cmd_buf, 0);
198                 break;
199             }
200             case '1':
201             {
202                 if (bBootFrmNORFlash())
203                 {
204                     strcpy(cmd_buf, "tftp 0x30000000 u-boot.bin; protect off all; erase 0 +$(filesize); cp.b 0x30000000 0 $(filesize)");
205                 }
206                 else
207                 {
208                     strcpy(cmd_buf, "tftp 0x30000000 u-boot.bin; nand erase boot; nand write.jffs2 0x30000000 boot $(filesize)");
209                 }
210                 run_command(cmd_buf, 0);
211                 break;
212             }

213             case '2':
214             {
215                 strcpy(cmd_buf, "tftp 0x30000000 uImage; nand erase kernel; nand write.jffs2 0x30000000 kernel $(filesize)");
216                 run_command(cmd_buf, 0);
217 #ifdef CONFIG_SURPORT_WINCE
218                 if (!TOC_Read())
219                     TOC_Erase();
220 #endif
221                 break;
222             }
223             case '3':
224             {
225                 strcpy(cmd_buf, "tftp 0x30000000 rootfs.jffs2; nand erase jffs2; nand write.jffs2 0x30000000 jffs2 $(filesize)");
226                 run_command(cmd_buf, 0);
227                 break;
228             }
229
230             case '4':
231             {
232                 strcpy(cmd_buf, "tftp 0x30000000 rootfs.yaffs; nand erase yaffs; nand write.yaffs 0x30000000 yaffs $(filesize)");
233                 run_command(cmd_buf, 0);
234                 break;
235             }

236
237 #ifdef CONFIG_SURPORT_WINCE
238             case 'e':
239             {
240                 offset = EBOOT_BLOCK * mtd->erasesize;
241                 size   = EBOOT_BLOCK_SIZE * mtd->erasesize;
242                 sprintf(cmd_buf, "nand erase 0x%x 0x%x; usbslave 1 0x30000000; nand write 0x30000000 0x%x $(filesize)", offset, size, offset);
243                 run_command(cmd_buf, 0);
244                 break;
245             }
246 #endif
247
248             case 'k':
249             {
250                 strcpy(cmd_buf, "usbslave 1 0x30000000; nand erase kernel; nand write.jffs2 0x30000000 kernel $(filesize)");
251                 run_command(cmd_buf, 0);
252 #ifdef CONFIG_SURPORT_WINCE
253                 if (!TOC_Read())
254                     TOC_Erase();
255 #endif
256                 break;
257             }




(5)重新编译
cd /tmp/workspace/u-boot-1.1.6
make clean
make distclean
make
编译完成后会在tmp/workspace/u-boot-1.1.6目录下发现u-boot.bin文件,即是我们需要的uboot镜像文件。

(6)安装mkimag工具
cp /tmp/workspace/u-boot-1.1.6/tools/mkimage /usr/sbin
注:该工具必须安装,后面编译内核要用到。因为,uboot不支持zImage格式,我们需要mkiamge将内核编译成uImage格式。

二、修改kernel源码
(1)解压源码
cd /tmp/workspace
tar -xvf linux-2.6.29-mini2440-20090708.tgz
cd linux-2.6.29

(2)修改inux-2.6.29/arch/arm/plat-s3c24xx/common-friendly-arm.c文件
cd  /tmp/workspace/inux-2.6.29

49 /*
50 static struct mtd_partition friendly_arm_default_nand_part[] = {
51         [0] = {
52                 .name   = "supervivi",
53                 .size   = 0x00060000,
54                 .offset = 0,
55         },
56         [1] = {
57                 .name   = "Kernel",
58                 .offset = 0x00060000,
59                 .size   = 0x00200000,
60         },
61         [2] = {
62                 .name   = "root",
63                 .offset = 0x00260000,
64                 .size   = 1024 * 1024 * 1024, //64U * 1024 * 1024 - 0x00260000,
65         },
66         [3] = {
67                 .name   = "nand",
68                 .offset = 0x00000000,
69                 .size   = 1024 * 1024 * 1024, //64U * 1024 * 1024 - 0x00260000,
70         }
71 };
72 */
73 //modified by sunny, 2010.4.16 13:24
74 static struct mtd_partition friendly_arm_default_nand_part[] = {
75         [0] = {
76                 .name   = "boot",
77                 .size   = 0x00040000,
78                 .offset = 0,
79         },
80         [1] = {
81                 .name   = "env",
82                 .offset = 0x00040000,
83                 .size   = 0x00010000,
84         },
85         [2] = {
86                 .name   = "kernel",
87                 .offset = 0x00050000,
88                 .size   = 0x00200000, //64U * 1024 * 1024 - 0x00260000,
89         },
90         [3] = {
91                 .name   = "root",
92                 .offset = 0x00250000,
93                 .size   = 0x03db0000, //64U * 1024 * 1024 - 0x00260000,
94         }
95 };
注:该分区表是与u-boot-1.1.6/include/configs/open24x0.h文件对应的,自己可以研究一下。


(3)重新编译内核,详细见《mini2440-um-20090817.pdf》第六章  定制 Linux 内核及制作文件系统
cd /tmp/workspace/linux-2.6.29
cp config_mini2440_t35 .config
make uIamge
注1:注意是make uImage而不是zImage了,编译uImage也会生成zImage,生成的位置仍然在 /tmp/workspace/linux-2.6.29/arch/arm/boot/
注2:此处需要根据自己实际用的开发板选择,我用的开发板带的是T35的显示屏,因此选用onfig_mini2440_t35


三、安装tftpserver工具到xp
(1)将mini2440光盘中带的tftpd32拷贝到自己的PC上,具体位置在"windows平台工具\tftpboot",整个目录都拷贝下来,放在任何地方皆可。
(2)打开tftpd32.exe,设置一下“Current Directory”,选择你要存放u-boot.bin,uImage,rootfs.yaffs的目录(假设为C:\Program Files\tftpboot\download)。
(3)“Server Interface”选择你的网口的IP(假设ip地址为192.168.1.10)。
(4)单击“Show Dir”,如果能看到C:\Program Files\tftpboot\download目录下的文件,则说明你的tftpd设置成功。
注1:root_yaffs实际为mini2440带的root镜像文件(root_qtopia-64M.img或root_qtopia-128M.img)
注2:这三个镜像文件的名字必须为u-boot.bin(uboot),uImage(内核),rootfs.yaffs(文件系统),这与uboot的功能菜单程序有关。


四、烧写u-boot.bin,uImage,root_yaffs
(1)用网线将pc和开发板连接,将u-boot.bin,uImage,rootfs.yaffs镜像文件拷贝到C:\Program Files\tftpboot\download目录。
(2)烧写u-boot.bin
对于该文件的烧写你可以直接用norflash带的supervivi烧写(用【a】选项即可);也可以用jtag电缆从并口烧写。
烧写完u-boot.bin后,从nand flash启动,发现uboot启动后,按下空格键进入uboot功能菜单;

进入uboot功能菜单后,按下空格键,进入uboot命令窗口;
输入printenv命令,可显示当前的env设置;
发现serverip=192.168.1.1,更改为192.168.1.10(因为你的PC当前的ip为192.168.1.10),输入下面的命令:
setenv serverip 192.168.1.10
saveenv
或者你也可以改变自己pc的ip为192.168.1.1
输入menu命令重新回到uboot功能菜单
按下1键重新下载u-boot.bin到nand flash(也可以不用重新下载)

(3)烧写kernel
在uboot功能菜单按下2键下载uImage到nand flash
(4)烧写root_yaffs
在uboot功能菜单按下4键下载root_yaffs到nand flash

注:开始我下载的时候,PC机与mini2440开发板是通过交换机连接的,下载uImage和u-boot.bin都没问题,但是下载root_yaffs是总是会出现crc error提示,
后来用一根网线直连的方式下载时,crc error消失,可能是我的交换机不好吧,如果大家用交换机时也出现这个问题,我们共同讨论一下。


终于写完了,写的比较匆忙,如有错误还望大家指正!
[ 此帖被sunny92294在2010-04-19 18:50重新编辑 ]
我分享,我快乐!
级别: 新手上路
UID: 52894
精华: 0
发帖: 23
金钱: 115 两
威望: 23 点
贡献值: 0 点
综合积分: 46 分
注册时间: 2011-07-27
最后登录: 2015-05-24
1楼  发表于: 2011-08-06 10:37
256Mflash能用吗?