Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1013914
  • 博文数量: 244
  • 博客积分: 6820
  • 博客等级: 准将
  • 技术积分: 3020
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-09 21:33
文章分类

全部博文(244)

文章存档

2013年(1)

2012年(16)

2011年(132)

2010年(3)

2009年(12)

2008年(80)

我的朋友

分类: LINUX

2008-09-10 00:08:42

 
 
 
 
 
 
 
 
 
 
 
 
解决u-boot-1.2.0中go命令的bug

文章说明:calmarrow(lqm)原创

文章引自:http://piaoxiang.cublog.cn

 
    u-boot-1.2.0现在可以使用tftp,支持nand读写。但是在使用go命令时,遇到了问题。现象如下:
 

U-boot # tftp 0x31000000 zImage
TFTP from server 192.168.1.216; our IP address is 192.168.1.110
Filename 'zImage'.
Load address: 0x31000000
Loading: #################################################################
         ################################################################
done
Bytes transferred = 658908 (a0ddc hex)
U-boot # go 0x31000000
## Starting application at 0x31000000 ...
Uncompressing Linux................................................ done, booting the kernel.

Error: a

 
    可见,跳转地址0x31000000传递成功,zImage头部的解压缩程序也成功了,解压完成之后真正进入内核执行阶段出现问题。这说明参数传递有问题,标志就是出现Error:a。读过vivi的汇编代码知道,我们还需要传递两个参数,保证R0为0,R1为mach type。另外呢,需要设定Linux启动的命令行参数。所以,需要查看uboot的源代码,在【common/cmd_boot.c】中。
 

#if defined(CONFIG_I386)
DECLARE_GLOBAL_DATA_PTR;
#endif

int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
        ulong addr, rc;
        int rcode = 0;

        if (argc < 2) {
                printf ("Usage:\n%s\n", cmdtp->usage);
                return 1;
        }

        addr = simple_strtoul(argv[1], NULL, 16);

        printf ("## Starting application at 0x%08lX ...\n", addr);

        
/*
         * pass address parameter as argv[0] (aka command name),
         * and all remaining args
         */

#if defined(CONFIG_I386)
        
/*
         * x86 does not use a dedicated register to pass the pointer
         * to the global_data
         */

        argv[0] = (char *)gd;
#endif
#if !defined(CONFIG_NIOS)
        rc = ((ulong (*)(int, char *[]))addr) (--argc, &argv[1]);
#else
        
/*
         * Nios function pointers are address >> 1
         */

        rc = ((ulong (*)(int, char *[]))(addr>>1)) (--argc, &argv[1]);
#endif
        if (rc != 0) rcode = 1;

        printf ("## Application terminated, rc = 0x%lX\n", rc);
        return rcode;
}

 
    可以看出,这里没有开放宏DECLARE_GLOBAL_DATA_PTR,这样gd就无法使用。以前看过gd部分,相关的环境变量等都与此数据结构有关。读源代码发现,这个go并没有适合s3c2410的代码。所以应该根据情况添加自己的部分。传递参数采用tag方式,前面vivi中的代码稍作修改就可以拿过来用了,关键的语句:
 

rc = ((ulong (*)(int, char *[]))addr)(0, gd->bd->bi_arch_number);

 
    这句比较难理解。其实就是执行函数的指针,带有两个参数,然后调转到函数地址执行。等价于vivi中的call(0, mach_type, addr)。patch内容如下,参考修改:    完成后测试成功,如下:
 

U-Boot 1.2.0 (Sep 20 2007 - 15:57:54)

U-Boot code: 33F80000 -> 33F97A90 BSS: -> 33F9C340
RAM Configuration:
Bank #0: 30000000 64 MB
NAND: 32 MB
In: serial
Out: serial
Err: serial
U-boot # tftp 0x30008000 zImage
TFTP from server 192.168.1.216; our IP address is 192.168.1.110
Filename 'zImage'.
Load address: 0x30008000
Loading: #################################################################
         ################################################################
done
Bytes transferred = 658908 (a0ddc hex)
U-boot # go 0x30008000
## Starting application at 0x30008000 ...
Setup linux parameters at 0x30000100
linux command line is: "noinitrd root=/dev/mtdblock3 console=ttyS0"
Uncompressing Linux................................................ done, booting the kernel.
Linux version 2.4.18-rmk7-pxa1 (armlinux@lqm) (gcc version 2.95.3 20010315 (release)) #10 Thu Sep 20 10:09:50 CST 2007
CPU: ARM/CIRRUS Arm920Tsid(wb) revision 0
Machine: Embest EduKit III (S3C2410)
On node 0 totalpages: 16384
zone(0): 16384 pages.
zone(1): 0 pages.
zone(2): 0 pages.
Kernel command line: noinitrd root=/dev/mtdblock3 console=ttyS0
DEBUG: timer count 15626
Console: colour dummy device 80x30
Calibrating delay loop... 49.86 BogoMIPS
Memory: 64MB = 64MB total
Memory: 62860KB available (1251K code, 294K data, 60K init)
Dentry-cache hash table entries: 8192 (order: 4, 65536 bytes)
Inode-cache hash table entries: 4096 (order: 3, 32768 bytes)
Mount-cache hash table entries: 1024 (order: 1, 8192 bytes)
Buffer-cache hash table entries: 4096 (order: 2, 16384 bytes)
Page-cache hash table entries: 16384 (order: 4, 65536 bytes)
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
Initializing RT netlink socket
CPU clock = 200.000 Mhz, HCLK = 100.000 Mhz, PCLK = 50.000 Mhz
Starting kswapd
devfs: v1.10 (20020120) Richard Gooch (rgooch@atnf.csiro.au)
devfs: devfs_debug: 0x0
devfs: boot_options: 0x1
ttyS%d0 at I/O 0x50000000 (irq = 52) is a S3C2410
ttyS%d1 at I/O 0x50004000 (irq = 55) is a S3C2410
ttyS%d2 at I/O 0x50008000 (irq = 58) is a S3C2410
Console: switching to colour frame buffer device 30x40
Installed S3C2410 frame buffer
pty: 256 Unix98 ptys configured
s3c2410-ts initialized
S3C2410 Real Time Clock Driver v0.1
block: 128 slots per queue, batch=32
eth0: cs8900 rev K(3.3 Volts) found at 0xd0000300
cs89x0 media RJ-45, IRQ 37
NAND device: Manufacture ID: 0xec, Chip ID: 0x75 (Samsung KM29U256T)
Creating 4 MTD partitions on "Samsung KM29U256T":
0x00000000-0x00020000 : "bootloader"
0x00020000-0x00030000 : "param"
0x00030000-0x00300000 : "kernel"
0x00300000-0x02000000 : "root"
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP, IGMP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 4096 bind 4096)
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
NetWinder Floating Point Emulator V0.95 (c) 1998-1999 Rebel.com
VFS: Mounted root (cramfs filesystem).
Mounted devfs on /dev
Freeing init memory: 60K
init started: BusyBox v1.00 (2005.06.09-02:02+0000) multi-call binary
Starting pid 11, console /dev/console: '/etc/init.d/rcS'
Bummer, could not run '/etc/init.d/rcS': No such file or directory
Bummer, could not run '/etc/init.d/rcS': No such file or directory

Please press Enter to activate this console.
Starting pid 12, console /dev/console: '/bin/sh'
/ #

 
    现在uboot基本上好用了,可以支持cramfs烧写,用go和bootm都可以引导成功,tftp也很好用。很方便,最终的移植patch如下:
 

[armlinux@lqm patch]$ ls
uboot_go.patch vivi_lxdialog.patch vivi_reset_handler.patch vivi_s3c2410_nand.patch
[armlinux@lqm patch]$ cat uboot_go.patch
--- cmd_boot.c.orig 2007-09-21 12:45:20.000000000 +0800
+++ cmd_boot.c 2007-09-21 12:45:42.000000000 +0800
@@ -28,9 +28,52 @@
 #include <command.h>
 #include <net.h>
 
-#if defined(CONFIG_I386)
 DECLARE_GLOBAL_DATA_PTR;
-#endif
+
+#define LINUX_PAGE_SIZE 4096
+
+
/*
+ * pram_base: base address of linux paramter
+ */

+static void setup_linux_tag(ulong param_base)
+{
+ struct tag *params = (struct tag *)param_base;
+ char *linux_cmd;
+ char *p;
+
+ printf("Setup linux parameters at 0x%x\n", param_base);
+ memset(params, 0, sizeof(struct tag));
+
+ /* step1: setup start tag */
+ params->hdr.tag = ATAG_CORE;
+ params->hdr.size = tag_size(tag_core);
+ params->u.core.flags = 0;
+ params->u.core.pagesize = LINUX_PAGE_SIZE;
+ params->u.core.rootdev = 0;
+ params = tag_next(params);
+
+ /* step2: setup cmdline tag */
+ params->hdr.tag = ATAG_CMDLINE;
+ linux_cmd = getenv("bootargs");
+ if (linux_cmd == NULL) {
+ printf("cannot find linux cmdline.use default.\n");
+ params->hdr.size = (sizeof(struct tag_header)+strlen(CONFIG_BOOTARGS)+1+4) >> 2;
+ memcpy(params->u.cmdline.cmdline, CONFIG_BOOTARGS, strlen(CONFIG_BOOTARGS)+1);
+ } else {
+ /* eat leading white space */
+ for (p=linux_cmd; *p==' '; p++) {
+ /* do nothing */;
+ }
+ params->hdr.size = (sizeof(struct tag_header)+strlen(linux_cmd)+1+4) >> 2;
+ memcpy(params->u.cmdline.cmdline, linux_cmd, strlen(linux_cmd)+1);
+ }
+ printf("linux command line is: \"%s\"\n", params->u.cmdline.cmdline);
+ params = tag_next(params);
+
+ /* step3: setup end tag */
+ params->hdr.tag = ATAG_NONE;
+ params->hdr.size = 0;
+}
 
 int do_go (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
@@ -58,7 +101,8 @@
        argv[0] = (char *)gd;
 #endif
 #if !defined(CONFIG_NIOS)
- rc = ((ulong (*)(int, char *[]))addr) (--argc, &argv[1]);
+ setup_linux_tag(gd->bd->bi_boot_params);
+ rc = ((ulong (*)(int, char *[]))addr)(0, gd->bd->bi_arch_number);
 #else
        

 
文件: uboot_s3c2410_nand.patch.gz
大小: 8KB
下载: 下载
     备份吧。
 
    今天还思考了vivi和uboot在参数存储的不同,也想清楚了设置情况。同时也弄清楚mtd分区和vivi自己加的bon分区到底怎么回事。关于bon分区与mtd分区,vivi和uboot的比较,留待明天总结。

 
2007-09-21
 
    昨天go已经修正好了,所以今天早上设置了一下bootcmd,利用bootcmd已经实现自动引导了。具体设置如下:
 

U-boot # setenv bootcmd nand read 0x30008000 0x00030000 0x002d0000\;go 0x30008000
U-boot # saveenv
Saving Environment to NAND...
Erasing Nand...Writing to Nand... done
?boot # reset
U-Boot 1.2.0 (Sep 20 2007 - 15:57:54)

U-Boot code: 33F80000 -> 33F97A90 BSS: -> 33F9C340
RAM Configuration:
Bank #0: 30000000 64 MB
NAND: 32 MB
In: serial
Out: serial
Err: serial
Hit any key to stop autoboot: 0

NAND read: device 0 offset 196608, size 2949120 ...
 2949120 bytes read: OK
## Starting application at 0x30008000 ...
Setup linux parameters at 0x30000100
linux command line is: "noinitrd root=/dev/mtdblock3 console=ttyS0"
Uncompressing Linux................................................ done, booting the kernel.
Linux version 2.4.18-rmk7-pxa1 (armlinux@lqm) (gcc version 2.95.3 20010315 (release)) #10 Thu Sep 20 10:09:50 CST 2007
CPU: ARM/CIRRUS Arm920Tsid(wb) revision 0

下略,挂载文件系统也成功。

 
    使用bootcmd也可以,不过此时的内核映象应该是在zImage前面加0x40个字节的头信息,利用bootm在前面也成功了,道理是相同的。具体可以看lufuchong的介绍文章
 
阅读(923) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~