社区导航

 
查看: 11663|回复: 23

[原创] 关于三星cortex A9 4412 uboot 启动的一些问题释疑

[复制链接]

1081

TA的帖子

0

TA的资源

五彩晶圆(中级)

Rank: 8Rank: 8

发表于 2013-11-27 09:58:21 | 显示全部楼层 |阅读模式
最近,发现4412 和S5PV210的一些iNand/TF启动方式有些不同,4412 的一些磁盘索引不是固定在某一个通道的上的,而S5PV210 是固定的,这就导致一些人在烧写4412 ,分区格式化的时候会莫名其妙,不知所以然,现在看看代码,看是4412 代码到底是为何会这样了。
首先看从iNand 启动时候uboot打印信息。
U-Boot 2010.12 (Jul 29 2013 - 10:01:49) for SMDK4412


CPU: S5PC220 [Samsung SOC on SMP Platform Base on ARM CortexA9]
APLL = 1200MHz, MPLL = 800MHz
DRAM:  1023 MiB
TrustZone Enabled BSP
BL1 version: 20120711
OM_STAT=0x00000029
Checking Boot Mode ... EMMC4.41
REVISION: 1.1
NAME: S5P_MSHC4
MMC Device 0: 7576 MB
MMC Device 1: 0 MB
MMC Device 2 not found
Using default environment


MMC read: dev # 0, block # 26624, count 1 ... 1 blocks read: OK
Hit 'a' key to stop autoboot:  0
SMDK4412 #
查找OM_STAT 所在位置
unsigned int OmPin;
OmPin = INF_REG3_REG;
        printf("OM_STAT=0x%08x\n", *((unsigned int *)(0x10020000)));
        printf("Checking Boot Mode ...");
        if(OmPin == BOOT_ONENAND) {
                printf(" OneNand\n");
        } else if (OmPin == BOOT_NAND) {
                printf(" NAND\n");
        } else if (OmPin == BOOT_MMCSD) {
                printf(" SDMMC\n");
        } else if (OmPin == BOOT_EMMC) {
                printf(" EMMC4.3\n");
        } else if (OmPin == BOOT_EMMC_4_4) {
                printf(" EMMC4.41\n");
        }

[ 本帖最后由 Wince.Android 于 2013-11-27 14:36 编辑 ]
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460


回复

使用道具 举报

1081

TA的帖子

0

TA的资源

五彩晶圆(中级)

Rank: 8Rank: 8

 楼主| 发表于 2013-11-27 10:14:02 | 显示全部楼层
查询一下 OmPin 所用到的位置,这个变量的确非常重要,决定了到底烧写哪个存储器(nandflash ,还是mmc,还是iNand.........等等)
common/cmd_fastboot.c:extern unsigned int OmPin;
common/cmd_fastboot.c:                        if (OmPin == BOOT_MMCSD) {
common/cmd_fastboot.c:                        } else if (OmPin == BOOT_EMMC_4_4 || OmPin == BOOT_EMMC) {
common/cmd_fastboot.c:                        } else if (OmPin == BOOT_ONENAND) {
common/cmd_fastboot.c:                        if (OmPin == BOOT_MMCSD) {
common/cmd_fastboot.c:                        } else if(OmPin == BOOT_EMMC_4_4 || OmPin == BOOT_EMMC) {
common/cmd_fastboot.c:                        else if(OmPin == BOOT_ONENAND) {
common/cmd_fastboot.c:....                                if (OmPin == BOOT_ONENAND) {
common/cmd_fastboot.c:                                } else if (OmPin == BOOT_MMCSD) {
common/cmd_fastboot.c:                                } else if (OmPin == BOOT_EMMC_4_4 || OmPin == BOOT_EMMC) {
common/cmd_fastboot.c:                                if (OmPin == BOOT_ONENAND) {
common/cmd_fastboot.c:                                } else if (OmPin == BOOT_MMCSD) {
common/cmd_fastboot.c:                                } else if (OmPin == BOOT_EMMC_4_4 || OmPin == BOOT_EMMC) {
common/cmd_fastboot.c:                                        if (OmPin == BOOT_ONENAND) {
common/cmd_fastboot.c:                                        } else if (OmPin == BOOT_MMCSD) {
common/cmd_fastboot.c:                                        } else if (OmPin == BOOT_EMMC_4_4 || OmPin == BOOT_EMMC) {
common/cmd_fastboot.c:        switch(OmPin) {
common/cmd_fastboot.c:        switch(OmPin) {
drivers/mmc/s5p_mshc.c:extern unsigned int OmPin;
drivers/mmc/s5p_mshc.c:        if (OmPin == BOOT_EMMC_4_4 || OmPin == BOOT_EMMC) {
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460


回复

使用道具 举报

1081

TA的帖子

0

TA的资源

五彩晶圆(中级)

Rank: 8Rank: 8

 楼主| 发表于 2013-11-27 10:32:54 | 显示全部楼层

从上面的代码看,我以前写的Sate4412 开发板镜像烧写方法似乎是错误的,但是...........那个步骤是我一边烧写一边写的,的的确确是能够烧写成功启动的,why?
我觉得其中程序必有一些暗藏的东西,继续找找......
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460


回复

使用道具 举报

1081

TA的帖子

0

TA的资源

五彩晶圆(中级)

Rank: 8Rank: 8

 楼主| 发表于 2013-11-27 11:01:11 | 显示全部楼层

找到4412 uboot玄妙的地方了

关键代码如下:

从上面的代码看,我以前写的Sate4412 开发板镜像烧写方法似乎是错误的,但是...........那个步骤是我一边烧写一边写的,的的确确是能够烧写成功启动的,why?
我觉得其中程序必有一些暗藏的东西,继续找找......


#if defined(CFG_FASTBOOT_SDMMCBSP)
#if defined(CONFIG_S5P6450) && !defined(CONFIG_EMMC_4_4)
#define        DEV_NUM 1
#else
#define        DEV_NUM 0
#endif
static int write_to_ptn_sdmmc(struct fastboot_ptentry *ptn, unsigned int addr, unsigned int size)
{

   .......

/* use the partition name that can be understood by a command, movi */
                if (!strcmp(ptn->name, "bl_uboot"))
                {
                        strncpy(part, "bl_uboot", 10);
                        sprintf(run_cmd,"emmc open 0");
                        run_command(run_cmd, 0);
                }

..............................

if (INF_REG3_REG == 7 && (!strcmp(ptn->name, "bl_uboot"))){
                        sprintf(run_cmd,"emmc close 0");
                        run_command(run_cmd, 0);
}

前面看到了吧INF_REG3_REG 这个不是OM 的寄存器啊,只是在启动阶段读OM寄存器,然后存到INF_REG3_REG,也够恶心的。这里居然不用OM,直接用这个,用意何在?!INF_REG3_REG == 7 这个值正是OM为 EMMC4.4 时候的值(INF_REG3_REG不是OM寄存器的值,只是一个强制的赋值,所以不要混淆,不是Sate4412 开发板TF 小卡启动的配置),这里判断到是iNand启动,烧写完毕镜像那么就关闭了emmc?
所以一般人找不到,总以为OM是在开机时候读一次就没再改过了.........囧!

先看看怎么回事再说吧,继续。

[ 本帖最后由 Wince.Android 于 2013-11-27 14:46 编辑 ]
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460


回复

使用道具 举报

1081

TA的帖子

0

TA的资源

五彩晶圆(中级)

Rank: 8Rank: 8

 楼主| 发表于 2013-11-27 11:06:52 | 显示全部楼层
试试执行 emmc close 0 会有什么结果
SMDK4412 # emmc close 0
there are pending interrupts 0x00000001
eMMC CLOSE Success.!!
然后操作这个 iNand ,居然照样操作,压根没关闭,看来不是操作了这个iNand。
SMDK4412 # fdisk -c 0
NAME: S5P_MSHC4
fdisk is completed

partion #    size(MB)     block start #    block count    partition_Id
   1           500            67584         1024000          0x83
   2           150          1091584          307200          0x83
   3          6893          1398784        14116864          0x83
SMDK4412 #

[ 本帖最后由 Wince.Android 于 2013-11-27 11:08 编辑 ]
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460


回复

使用道具 举报

33

TA的帖子

2

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

发表于 2013-11-27 11:21:59 | 显示全部楼层
我也发现这个问题很奇怪.不知我用的烧写文档是否来自你手? 
OM开机就已经定了, 这个INF_REG3_REG 只是被系统用来存放OM设置值而已.请看lowlevel_init.S中的read_om函数, 
        ldr        r0, =S5PV310_POWER_BASE
        ldr        r1, [r0,#OMR_OFFSET]
        bic        r2, r1, #0xffffffc1
这个就是读取OM设置pin状态,并写入r2.
        /* SD/MMC BOOT */
        cmp     r2, #0x4
        moveq   r3, #BOOT_MMCSD

        /* eMMC BOOT */
        cmp        r2, #0x6
        moveq        r3, #BOOT_EMMC

        /* eMMC 4.4 BOOT */
        cmp        r2, #0x8
        moveq        r3, #BOOT_EMMC_4_4
        cmp        r2, #0x28
        moveq        r3, #BOOT_EMMC_4_4
上面就是根据r2值,记入相应的启动方式到r3
        ldr        r0, =INF_REG_BASE
        str        r3, [r0, #INF_REG3_OFFSET]
        mov        pc, lr
上面就是将存放在r3中的OM设置值存入INF_REG3_REG.

点评

原帖由 seanew 于 2013-11-27 11:21 发表 http://bbs.eeworld.com.cn/images/common/back.gif 我也发现这个问题很奇怪.不知我用的烧写文档是否来自你手?  OM开机就已经定了, 这个INF_REG3_REG 只是被系统用来  详情 回复 发表于 2013-11-27 15:13


回复

使用道具 举报

33

TA的帖子

2

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

发表于 2013-11-27 11:59:45 | 显示全部楼层
!INF_REG3_REG == 7 这个值正是Sate4412 开发板TF 小卡启动的配置,这里判断到是TF 小卡启动,那么就关闭了emmc?

不对吧? #define BOOT_EMMC_4_4 7
/* eMMC 4.4 BOOT */
        cmp        r2, #0x8
        moveq        r3, #BOOT_EMMC_4_4
        cmp        r2, #0x28
        moveq        r3, #BOOT_EMMC_4_4
从eMMC启动的时候,才会向r3写入7, 然后INF_REG3_REG的值才会是7.

点评

你说的对,我上面搞错了,已经纠正, INF_REG3_REG 这个也太扯了吧,本身就有OM_STAT 寄存器的,为啥这么搞,其实可以随时对OM_STAT 来判断的。[/backcolor] 上面的INF_REG3_REG 这个不是OM 的寄存器啊,只是在启  详情 回复 发表于 2013-11-27 15:02


回复

使用道具 举报

1081

TA的帖子

0

TA的资源

五彩晶圆(中级)

Rank: 8Rank: 8

 楼主| 发表于 2013-11-27 15:02:11 | 显示全部楼层
原帖由 seanew 于 2013-11-27 11:59 发表
!INF_REG3_REG == 7 这个值正是Sate4412 开发板TF 小卡启动的配置,这里判断到是TF 小卡启动,那么就关闭了emmc?
不对吧? #define BOOT_EMMC_4_4 7
/* eMMC 4.4 BOOT */
        cmp        r2, #0x8
   ...
你说的对,我上面搞错了,已经纠正,
INF_REG3_REG 这个也太扯了吧,本身就有OM_STAT 寄存器的,为啥这么搞,其实可以随时对OM_STAT  来判断的。
上面的INF_REG3_REG 这个不是OM 的寄存器啊,只是在启动阶段读OM寄存器,然后存到INF_REG3_REG,也够恶心的。这里居然不用OM,直接用这个,用意何在?!INF_REG3_REG == 7 这个值正是OM为 EMMC4.4 时候的值(INF_REG3_REG不是OM寄存器的值,只是一个强制的赋值,所以不要混淆,不是Sate4412 开发板TF 小卡启动的配置),这里判断到是iNand启动,烧写完毕镜像那么就关闭了emmc?
去看看emmc close 命令的代码,发现有一些注释,就是要求镜像烧写完毕以后,需要关闭这个成功烧写的emmc,难道不关闭会被刷掉吗?

int do_emmc(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
        int rc = 0;
        u32 dev;

        switch (argc) {
        case 5:
                if (strcmp(argv[1], "partition") == 0) {
                        dev = simple_strtoul(argv[2], NULL, 10);
                        struct mmc *mmc = find_mmc_device(dev);
                        u32 bootsize = simple_strtoul(argv[3], NULL, 10);
                        u32 rpmbsize = simple_strtoul(argv[4], NULL, 10);

                        if (!mmc)
                                rc = 1;

                        rc = emmc_boot_partition_size_change(mmc, bootsize, rpmbsize);
                        if (rc == 0) {
                                printf("eMMC boot partition Size is %d MB.!!\n", bootsize);
                                printf("eMMC RPMB partition Size is %d MB.!!\n", rpmbsize);
                        } else {
                                printf("eMMC boot partition Size change Failed.!!\n");
                        }
                } else {
                        printf("Usage:\n%s\n", cmdtp->usage);
                        rc =1;
                }
                break;

        case 3:
                if (strcmp(argv[1], "open") == 0) {
                        int dev = simple_strtoul(argv[2], NULL, 10);
                        struct mmc *mmc = find_mmc_device(dev);

                        if (!mmc)
                                rc = 1;

                        rc = emmc_boot_open(mmc);

                        if (rc == 0) {
                        printf("eMMC OPEN Success.!!\n");
                        printf("\t\t\t!!!Notice!!!\n");
                        printf("!You must close eMMC boot Partition after all image writing!\n");
                        printf("!eMMC boot partition has continuity at image writing time.!\n");
                        printf("!So, Do not close boot partition, Before, all images is written.!\n");
                        } else {
                                printf("eMMC OPEN Failed.!!\n");
                        }
                } else if (strcmp(argv[1], "close") == 0) {
                        int dev = simple_strtoul(argv[2], NULL, 10);
                        struct mmc *mmc = find_mmc_device(dev);

                        if (!mmc)
                                rc = 1;

                        rc = emmc_boot_close(mmc);

                        if (rc == 0) {
                                printf("eMMC CLOSE Success.!!\n");
                        } else {
                                printf("eMMC CLOSE Failed.!!\n");
                        }
                } else {
                        printf("Usage:\n%s\n", cmdtp->usage);
                        rc =1;
                }
                break;
        case 0:
        case 1:               
        case 2:
        case 4:
        default:
                printf("Usage:\n%s\n", cmdtp->usage);
                rc = 1;
                break;
        }
       
        return rc;
}


注意这里emmc 的关闭不是指电源关闭,而是关闭了一些功能
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460


回复

使用道具 举报

1081

TA的帖子

0

TA的资源

五彩晶圆(中级)

Rank: 8Rank: 8

 楼主| 发表于 2013-11-27 15:04:23 | 显示全部楼层
int emmc_boot_open(struct mmc *mmc)
{
        int err;
        struct mmc_cmd cmd;

        /* Boot ack enable, boot partition enable , boot partition access */
        cmd.cmdidx = MMC_CMD_SWITCH;
        cmd.resp_type = MMC_RSP_R1b;
        cmd.cmdarg = ((3<<24)|(179<<16)|(((1<<6)|(1<<3)|(1<<0))<<8));
        cmd.flags = 0;

        err = mmc_send_cmd(mmc, &cmd, NULL);
        if (err)
                return err;

        /* 4bit transfer mode at booting time. */
        cmd.cmdidx = MMC_CMD_SWITCH;
        cmd.resp_type = MMC_RSP_R1b;
        cmd.cmdarg = ((3<<24)|(177<<16)|((1<<0)<<8));
        cmd.flags = 0;

        err = mmc_send_cmd(mmc, &cmd, NULL);
        if (err)
                return err;

        return 0;
}

int emmc_boot_close(struct mmc *mmc)
{
        int err;
        struct mmc_cmd cmd;

        /* Boot ack enable, boot partition enable , boot partition access */
        cmd.cmdidx = MMC_CMD_SWITCH;
        cmd.resp_type = MMC_RSP_R1b;
        cmd.cmdarg = ((3<<24)|(179<<16)|(((1<<6)|(1<<3)|(0<<0))<<8));
        cmd.flags = 0;

        err = mmc_send_cmd(mmc, &cmd, NULL);
        if (err)
                return err;

        return 0;
}
上面可以知道,有一个判断,判断是iNand启动烧写后 才关闭了mmc ,但是TF 卡却没有,这个就是OM 在TF 烧写模式下,TF 烧写完毕会连bootloader 都会被冲掉的原因。囧。S5pv210 没有这个现象,难道这个是4412 有什么特殊的原因要这么样的?三星不可能会这么混的啊。

点评

是的,我现在就是这样的,每次烧写完后,TF卡必须重新烧卡.我认为,这个烧写方式一定是有问题的.三星没有这么混的.  详情 回复 发表于 2013-11-27 17:22
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460


回复

使用道具 举报

1081

TA的帖子

0

TA的资源

五彩晶圆(中级)

Rank: 8Rank: 8

 楼主| 发表于 2013-11-27 15:13:29 | 显示全部楼层
原帖由 seanew 于 2013-11-27 11:21 发表
我也发现这个问题很奇怪.不知我用的烧写文档是否来自你手? 
OM开机就已经定了, 这个INF_REG3_REG 只是被系统用来存放OM设置值而已.请看lowlevel_init.S中的read_om函数, 
        ldr        r0, =S5PV310_POWER_BASE
        l ...


INF_REG3_REG  应该是这个 ,就是Base Address: 0x1002_0000 +0x080C
INFORM3  0x080C  Information register 3  0x0000_0000

比较奇怪, 0x1002_0000 本身就是OM 寄存器地址但是却转存到INFORM3  ,再看看,三星不可能绕一大圈来做这个无谓的事情。
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460


回复

使用道具 举报

1081

TA的帖子

0

TA的资源

五彩晶圆(中级)

Rank: 8Rank: 8

 楼主| 发表于 2013-11-27 15:16:39 | 显示全部楼层
8.8.1.40 INFORM3
  Base Address: 0x1002_0000
  Address = Base Address + 0x080C, Reset Value = 0x0000_0000
Name  Bit  Type  Description  Reset Value
INFORM  [31:0]  RW
User-defined information register. By asserting
XnRESET pin, PMU clears INFORM0 to 3
registers.   
0x0
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460


回复

使用道具 举报

1081

TA的帖子

0

TA的资源

五彩晶圆(中级)

Rank: 8Rank: 8

 楼主| 发表于 2013-11-27 15:24:38 | 显示全部楼层
Table 8-8
Reset Type
INFORM0
INFORM1
INFORM2
INFORM3
Hardware reset  Reset
Watchdog timer reset  Reset
Software reset  Keep its value
Warm reset  Keep its value
Wakeup reset  Keep its value


4412 完整版本datasheet 624page 上有图
这个值可以再适当时候保存不变,这个是要用的原因之一。
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460


回复

使用道具 举报

33

TA的帖子

2

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

发表于 2013-11-27 16:39:25 | 显示全部楼层
就当是4412留给开发者的"NVRAM"用的就好啦.原来我的烧写文档是你写的啊,这里面是很奇怪,不带电切换烧写模式,这个才让人摸不着头脑的步骤. 切换开关只是在最后烧写完才用的的步骤,结果被用在下载img时使用,不对的地方........


回复

使用道具 举报

1081

TA的帖子

0

TA的资源

五彩晶圆(中级)

Rank: 8Rank: 8

 楼主| 发表于 2013-11-27 17:07:18 | 显示全部楼层

烧写这个环节最好在前面增加一个擦除uboot的环节即可无往而不利了

先把薄码开关拨到MMC2启动,即OM[5:1] 为b'00010,把启动TF卡插入MMC2,上电启动,进入uboot命令行模式后执行命令:
mmc erase boot 0 0 10240
即可擦除uboot分区最前面的引导部分。注意,不要此时烧写uboot,此时烧写会把uboot烧写到TF卡上而不是INAND上。接着断电,薄码开关调回INAND启动,即OM[5:1] B'10100,上电就会检查iNand,但是iNand 没有uboot启动代码,所以就会自动切换到TF卡启动,这时就可以烧写uboot到inand上了

——这个里面有笔误,上面应该改成如下就可以了。
先把薄码开关拨到MMC2启动,即OM[5:1] 为b'00010,把启动TF卡插入MMC2,上电启动,进入uboot命令行模式后执行命令:
mmc erase boot 1 0 1024 (当从mmc2 TF卡启动时i,TF卡设备索引号是0,而nand 设备索引号应该是1)
即可擦除iNand uboot分区最前面的引导部分。注意,不要此时烧写uboot,此时烧写会把uboot烧写到TF卡上而不是INAND上。接着断电,薄码开关调回INAND启动,即OM[5:1] B'10100,上电就会检查iNand,但是iNand 没有uboot启动代码,所以就会自动切换到TF卡启动,但是此时的OM值是iNand 模式的,所以iNand 设备索引值是0,而mmc2 TF卡是1,所以能够正常用fdisk -c 0 ,ext3format mmc 0:1 等分区命令进行烧写。这时就可以烧写uboot到inand上了。整个过程终于明白了,今天主要看了Sate4412 的uboot代码,并且举一反三,终于明白4412 烧写是怎么回事。终于清静了......

intdo_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
         int rc = 0;
         int part = 0;

         switch (argc) {
         case 3:
                   if (strcmp(argv[1],"rescan") == 0) {
                            int dev =simple_strtoul(argv[2], NULL, 10);
                            struct mmc *mmc =find_mmc_device(dev);

                            if (!mmc)
                                     return 1;

                            mmc_init(mmc);

                            return 0;
                   }

         case 0:
         case 1:
         case 4:
                   printf("Usage:\n%s\n",cmdtp->usage);
                   return 1;

         case 2:
                   if (!strcmp(argv[1],"list")) {
                            print_mmc_devices('\n');
                            return 0;
                   }
                   return 1;
         case 6:
                   if (strcmp(argv[1],"erase") == 0) {
                            /* Read inputvariable */
                            int dev =simple_strtoul(argv[3], NULL, 10);
                            u32 start =simple_strtoul(argv[4], NULL, 10);
                            u32 block =simple_strtoul(argv[5], NULL, 10);

                            struct mmc *mmc =find_mmc_device(dev);

                            if (!mmc)
                                     return 1;

                            u32 count = 0;

                            /* Select erasepartition */
                            if (strcmp(argv[2],"boot") == 0) {
                                     part = 0;
                                     /* ReadBoot partition size. */
                                     count =((mmc->ext_csd.boot_size_multi)*256);
                            } else if(strcmp(argv[2], "user") == 0) {
                                     part = 1;
                                     /* ReadUser partition size. */
                                     count =mmc->capacity;
                            } else {
                                     part = 1;
                                     count =mmc->capacity;
                                     printf("Defaulterase user partition\n");
                            }

                            /* If input counteris larger than max counter */
                            if ((start + block)> count) {
                                     block =(count - start) - 1;
                                     printf("Blockcount is Too BIG!!\n");
                            }

                            /* If input counteris 0 */
                            if (!block ) {
                                     block =(count - start) - 1;
                                     printf("Eraseall from %d block\n", start);
                            }

                            rc = mmc_erase(mmc,part, start, block);

                            if (rc == 0) {
                                     printf("MMCerase Success.!!\n");
                            } else {
                                     printf("MMCerase Failed.!!\n");
                                     return -1;
                            }
                            return 0;
                   } else if (strcmp(argv[1],"read") == 0) {
                            int dev =simple_strtoul(argv[2], NULL, 10);
                            void *addr = (void*)simple_strtoul(argv[3], NULL, 16);
                            u32 cnt =simple_strtoul(argv[5], NULL, 10);
                            u32 n;
                            u32 blk =simple_strtoul(argv[4], NULL, 10);
                            u32 read_cnt;
                            u32 cnt_to_read;
                            void *addr_to_read =addr;
                            struct mmc *mmc =find_mmc_device(dev);

                            if (!mmc)
                                     return 1;

                            printf("\nMMCread: dev # %d, block # %d, count %d ... ",
                                     dev, blk,cnt);

                            n = 0;
                            addr_to_read = addr;
                            do {
                                     if (cnt - n> MAXIMUM_BLOCK_COUNT)
                                               cnt_to_read= MAXIMUM_BLOCK_COUNT;
                                     else
                                               cnt_to_read= cnt - n;

                                     read_cnt =mmc->block_dev.block_read(dev, blk, cnt_to_read, addr_to_read);
                                     n +=read_cnt;
                                     blk +=read_cnt;
                                     addr_to_read+= read_cnt * 512;
                                     if(cnt_to_read!= read_cnt) {
                                               printf("%dblocks read: %s\n",
                                                        n,"ERROR");
                                               return-1;
                                     }
                            } while(cnt > n);

                            /* flush cache afterread */
                            flush_cache((ulong)addr,cnt * 512); /* FIXME */

                            printf("%dblocks read: %s\n",
                                     n, (n==cnt)? "OK" : "ERROR");
                            return (n == cnt) ?0 : 1;
                   } else if (strcmp(argv[1],"write") == 0) {
                            int dev =simple_strtoul(argv[2], NULL, 10);
                            void *addr = (void*)simple_strtoul(argv[3], NULL, 16);
                            u32 cnt =simple_strtoul(argv[5], NULL, 10);
                            int blk =simple_strtoul(argv[4], NULL, 10);
                            u32 n;
                            u32 written_cnt;
                            u32 cnt_to_write;
                            void *addr_to_write= addr;
                            struct mmc *mmc =find_mmc_device(dev);


                            if (!mmc)
                                     return 1;

                            printf("\nMMCwrite: dev # %d, block # %d, count %d ... ",
                                     dev, blk,cnt);

                            n = 0;
                            addr_to_write =addr;
                            do {
                                     if (cnt - n> MAXIMUM_BLOCK_COUNT)
                                               cnt_to_write= MAXIMUM_BLOCK_COUNT;
                                     else
                                               cnt_to_write= cnt - n;

                                     written_cnt= mmc->block_dev.block_write(dev, blk, cnt_to_write, addr_to_write);
                                     n +=written_cnt;
                                     blk +=written_cnt;
                                     addr_to_write+= written_cnt * 512;
                                     if(cnt_to_write!= written_cnt) {
                                               printf("%dblocks written: %s\n",
                                                        n,"ERROR");
                                               return-1;
                                     }
                            } while(cnt > n);

                            printf("%dblocks written: %s\n",
                                     n, (n ==cnt) ? "OK" : "ERROR");
                            return (n == cnt) ?0 : 1;
                   } else {
                            printf("Usage:\n%s\n",cmdtp->usage);
                            rc = 1;
                   }

                   return rc;
         default: /* at least 5 args */
                   printf("Usage:\n%s\n",cmdtp->usage);
                   return 1;
         }
}


[ 本帖最后由 gooogleman 于 2013-11-27 23:22 编辑 ]
如果对linux,Android,wince 等嵌入式底层有兴趣的,请加这个QQ群吧,群号:27100460


回复

使用道具 举报

33

TA的帖子

2

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

发表于 2013-11-27 17:22:08 | 显示全部楼层
原帖由 Wince.Android 于 2013-11-27 15:04 发表
int emmc_boot_open(struct mmc *mmc)
{
        int err;
        struct mmc_cmd cmd;

        /* Boot ack enable, boot partition enable , boot partition access */
        cmd.cmdidx = MMC_CMD_SWITCH;
        cmd.resp_type = MMC_RS ...
是的,我现在就是这样的,每次烧写完后,TF卡必须重新烧卡.我认为,这个烧写方式一定是有问题的.三星没有这么混的.


回复

使用道具 举报

559

TA的帖子

0

TA的资源

纯净的硅(高级)

Rank: 6Rank: 6

荣誉会员勋章

发表于 2013-11-27 22:40:36 | 显示全部楼层
晚上搞定这个事情先。
iNand启动时候
SKD4X12 # mmc list
S5P_MSHC4: 0
S3C_HSMMC2: 1
SKD4X12 #

不关机切换成
SD/TF MM2 启动的时候一样
SKD4X12 # mmc list
S5P_MSHC4: 0
S3C_HSMMC2: 1
SKD4X12 #
SKD4X12 # mmc list
S5P_MSHC4: 0
S3C_HSMMC2: 1
fdisk -c 0 分区仍然是给iNand 分的区
SKD4X12 # fdisk -c 0
NAME: S5P_MSHC4
fdisk is completed

partion #    size(MB)     block start #    block count    partition_Id
   1           500           102400         1024000          0x83
   2           150          1126400          307200          0x83
   3          6876          1433600        14082048          0x83
SKD4X12 #

设置SD/TF MM2 启动,关机,重启
发现变了。索引号 mmc2 和inand 颠倒了位置所以对应分区命令也跟着变了。

SMDK4412 # mmc list
S3C_HSMMC2: 0
S5P_MSHC4: 1
SMDK4412 #
SMDK4412 # fdisk -c 0
fdisk is completed

partion #    size(MB)     block start #    block count    partition_Id
   1           500            67584         1024000          0x83
   2           150          1091584          307200          0x83
   3          6777          1398784        13879296          0x83
SMDK4412 # fdisk -c 1
NAME: S5P_MSHC4
fdisk is completed

partion #    size(MB)     block start #    block count    partition_Id
   1           500            67584         1024000          0x83
   2           150          1091584          307200          0x83
   3          6893          1398784        14116864          0x83
SMDK4412 #

[ 本帖最后由 gooogleman 于 2013-11-27 22:56 编辑 ]

点评

为什么变? 我前面已经给出代码分析了.可以看看.  详情 回复 发表于 2013-11-28 09:26


回复

使用道具 举报

559

TA的帖子

0

TA的资源

纯净的硅(高级)

Rank: 6Rank: 6

荣誉会员勋章

发表于 2013-11-27 23:23:13 | 显示全部楼层
先把薄码开关拨到MMC2启动,即OM[5:1] 为b'00010,把启动TF卡插入MMC2,上电启动,进入uboot命令行模式后执行命令:
mmc erase boot 0 0 10240
即可擦除uboot分区最前面的引导部分。注意,不要此时烧写uboot,此时烧写会把uboot烧写到TF卡上而不是INAND上。接着断电,薄码开关调回INAND启动,即OM[5:1] B'10100,上电就会检查iNand,但是iNand 没有uboot启动代码,所以就会自动切换到TF卡启动,这时就可以烧写uboot到inand上了

——这个里面有笔误,上面应该改成如下就可以了。
先把薄码开关拨到MMC2启动,即OM[5:1] 为b'00010,把启动TF卡插入MMC2,上电启动,进入uboot命令行模式后执行命令:
mmc erase boot 1 0 1024 (当从mmc2 TF卡启动时i,TF卡设备索引号是0,而nand 设备索引号应该是1)
即可擦除iNand uboot分区最前面的引导部分。注意,不要此时烧写uboot,此时烧写会把uboot烧写到TF卡上而不是INAND上。接着断电,薄码开关调回INAND启动,即OM[5:1] B'10100,上电就会检查iNand,但是iNand 没有uboot启动代码,所以就会自动切换到TF卡启动,但是此时的OM值是iNand 模式的,所以iNand 设备索引值是0,而mmc2 TF卡是1,所以能够正常用fdisk -c 0 ,ext3format mmc 0:1 等分区命令进行烧写。这时就可以烧写uboot到inand上了。整个过程终于明白了,今天主要看了Sate4412 的uboot代码,并且举一反三,终于明白4412 烧写是怎么回事。终于清静了......


SMDK4412 # mmc erase boot 1 0 1024
START: 0 BLOCK: 1024
high_capacity: 1
Capacity: 15515648

Erase
..........
                        *** NOTICE ***
*** High Capacity(higher than 2GB) MMC's erase minimum size is 512KB ***

512 KB erase Done
MMC erase Success.!!
SMDK4412 #
用fastboot 下载所有镜像。
最后自动启动到android系统,重启发现已经正常从iNand启动。
切换到mmc2 启动,依然能够正常从TF卡启动,TF卡并没有被冲刷掉。主要是现在过程对了。经过这么一折腾,说明三星原版的bootloader 没有经过改进,没有做好限制,防止一些误操作导致烧写失败,看来等我把Sate210 和Sate-F 开发板的智能型bootloader 改好以后再来改进这个Sate4412 uboot吧,其实很简单,只要固定住这个iNand 索引号是1 ,其他索引也一直固定住就好了,这样就不会出错。还是信念啊,一个人做事的要求很重要。呵呵,是可以正常启动的了。
SMDK4412 # OK

U-Boot 2010.12-svn1 (Jun 07 2013 - 08:26:59) for SMDK4412


CPU: S5PC220 [Samsung SOC on SMP Platform Base on ARM CortexA9]
APLL = 1200MHz, MPLL = 800MHz
DRAM:  1023 MiB
TrustZone Enabled BSP
BL1 version: 20120711
OM_STAT=0x00000005
Checking Boot Mode ... SDMMC
REVISION: 1.1
MMC Device 0: 7460 MB
there are pending interrupts 0x00000001
NAME: S5P_MSHC4
MMC Device 1: 7576 MB
MMC Device 2 not found
Using default environment


MMC read: dev # 0, block # 26624, count 1 ... 1 blocks read: OK
Hit 'a' key to stop autoboot:  0
SMDK4412 #

如果输入mmc erase boot 0 0 1024 就会进入死循环,不停的打印如下点
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................

[ 本帖最后由 gooogleman 于 2013-11-27 23:42 编辑 ]

点评

从TF启动,就是mmc erase boot 1 0 0, 从eMMC启动,mmc erase boot 0 0 0 , 不用那个1024. 它最终调用mmc_erase的 [ 本帖最后由 seanew 于 2013-11-28 16:18 编辑 ]  详情 回复 发表于 2013-11-28 16:16
呵呵,所以我说你们的烧写文档有问题,你们还否认.在给客户设计前自己一定要明白原理,这是最起码的,因为迟早会出问题的......  详情 回复 发表于 2013-11-28 09:20


回复

使用道具 举报

1111

TA的帖子

0

TA的资源

五彩晶圆(初级)

Rank: 7Rank: 7Rank: 7

发表于 2013-11-28 08:35:57 | 显示全部楼层
高级货,看不懂


回复

使用道具 举报

33

TA的帖子

2

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

发表于 2013-11-28 09:20:50 | 显示全部楼层
原帖由 gooogleman 于 2013-11-27 23:23 发表
先把薄码开关拨到MMC2启动,即OM[5:1] 为b'00010,把启动TF卡插入MMC2,上电启动,进入uboot命令行模式后执行命令:
mmc erase boot 0 0 10240
即可擦除uboot分区最前面的引导部分。注意,不要此时烧写uboot,此时 ...
呵呵,所以我说你们的烧写文档有问题,你们还否认.在给客户设计前自己一定要明白原理,这是最起码的,因为迟早会出问题的......

点评

我试过,文档这样烧写在正常情况下是没有问题的, 因为正常情况下,iNand是不会出现你那种 情况的,我们也经常这么烧写,但是一旦出现你那种iNand 前面一些分区出问题时候就会导致启动不了,无解的情况。 所以为了  详情 回复 发表于 2013-11-28 09:52


回复

使用道具 举报

33

TA的帖子

2

TA的资源

一粒金砂(高级)

Rank: 3Rank: 3

发表于 2013-11-28 09:26:22 | 显示全部楼层
原帖由 gooogleman 于 2013-11-27 22:40 发表
晚上搞定这个事情先。
iNand启动时候
SKD4X12 # mmc list
S5P_MSHC4: 0
S3C_HSMMC2: 1
SKD4X12 #

不关机切换成
SD/TF MM2 启动的时候一样
SKD4X12 # mmc list
S5P_MSHC4: 0
S3C_HSMMC2: 1
SKD4X12 # ...
为什么变? 我前面已经给出代码分析了.可以看看.

点评

你的那个只是一个小的起点,昨晚我看了一下,这个主要还是uboot代码里面他自己这么做了,这样做也没什么不好,或者这样做有他的好处,就是他可以自由选择从mmc2 还是iNand 通道启动系统应该都没问题,不过内核那些  详情 回复 发表于 2013-11-28 10:16


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456

GMT+8, 2018-8-19 01:50 , Processed in 0.550314 second(s), 18 queries , Gzip On, Redis On.

快速回复 返回顶部 返回列表