1. 程式人生 > >關於三星cortex A9 Sate4412 開發板 uboot 啟動的一些問題釋疑

關於三星cortex A9 Sate4412 開發板 uboot 啟動的一些問題釋疑

作者:gooogleman                   日期:2013.11.27            

最近,發現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");
        }

查詢一下 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) {

從上面的程式碼看,我以前寫的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是在開機時候讀一次就沒再改過了.........囧!

這個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.

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 的關閉不是指電源關閉,而是關閉了一些功能

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;
}

相關推薦

關於三星cortex A9 Sate4412 開發 uboot 啟動一些問題釋疑

作者:gooogleman                   日期:2013.11.27             最近,發現4412 和S5PV210的一些iNand/TF啟動方式有些不同,4412 的一些磁碟索引不是固定在某一個通道的上的,而S5PV210 是固定的

x210開發uboot啟動引數設定與解析--朱友鵬嵌入式課程總結

x210開發板uboot啟動引數設定與解析 1.1 映象檔案已燒錄到開發板中 1.1.1 引數設定 setenv bootcmd "movi read kernel 30008000;bootm 30008000" setenv bootargs "console=ttyS

入手友善之臂Cortex-A9 Tiny4412 開發

轉眼就到了2016年,時間過得真快,一直以來,部落格更新的比較慢,也比較少,尤其是原創的更少。 從今天開始,準備每週更新4篇文章,讓自己動起來。 淘寶逛了一圈,發現這個還可以。 一個瑕疵就是 音訊驅

移植好uboot和基於initramfs根檔案系統Linux核心的開發啟動過程

我們移植好uboot和Linux核心之後,當我們重啟之後,開發板首先做的事情就是將nandflash前4K的內容複製到SRAM中去,由於SRAM只有4K大小,所以我們必須將初始化CPU、記憶體、中斷、關閉開門狗以及nandflash中uboot拷貝到SDRAM中的的程式都放

【資料分享】使用迅為iTOP-iMX6開發-uboot-修改預設環境變數

iTOP-iMX6 開發板燒寫好之後,預設是 android 系統 9.7 寸螢幕的系統引數和螢幕參 數。如下圖。本文件主要介紹如何修改預設啟動引數。       1、 重要的環境變數 比較重要的環境變數或者說經常使用的環境變數,已經在上圖中的紅色方

開發啟動linux過程分析

開發板下linux啟動過程 2016年05月28日 10:07:52 [email protected] 閱讀數:662 標籤: linux 啟動 更多 個人分類: linux 2440 要在開發板上的Linux開機啟動自己的程式,想著簡單,卻改了很

基於OK6410開發Uboot原始碼簡單分析

2018-04-07 OK6410開發板是基於三星S3C6410晶片設計的一款開發板,資源比較豐富,可是想要使用這些資源就需要編寫相應的啟動載入程式,即BootLoader。當然,想要自己憑空寫出BootLoader那簡直就是天方夜譚,所以我們需要參考行業中現有的BootLoader,在其

Android底層開發(三)在開發啟動Android系統

1》燒錄uboot.bin——路徑:/home/george/src_210 cp uboot-fs210_V5/u-boot.bin /tftpboot/ FS210 # tftp 0x40008000 u-

6818開發uboot、kernel、rootfs編譯記錄

目錄 前言 因為前面編譯過一次6818的uboot、kernel和rootfs。但是是在root使用者下編譯的,結果在開發板上執行出現錯誤。文件上寫必須在普通使用者,所以又在普通使用者下重新編譯一次。但是因為沒有及時記錄下編譯過程,結果又要重新造輪

開發uboot中配置tftp和nfs網路載入檔案

## 配置核心啟動的串列埠引數, root=/dev/nfs是告訴核心使用網路來載入檔案系統,nfsroot為伺服器的nfs共享目錄 ## 注意ip一定要配置為dhcp,否則無法正常啟動nfs檔案系統

開發核心啟動後掛載到nfs上

一、配置網路檔案系統 1>在PC上配置nfs服務 [redis]$ sudo apt-get install nfs-kernel-server [redis]$ sudo vim /etc/exports /redis_root *(rw,sync,no_roo

設定linux開發開機啟動畫面

1,make ARCH=arm menuconfig   Device Drivers  --->    Graphics support  --->   重新編譯核心,然後下載到開發板,就可以看到啟動的時候有小企鵝了.

嵌入式ARM Linux開發啟動,跳過輸入root使用者名稱和密碼

1. 編譯autologin.c程式。autologin.c檔案內容#include <unistd.h>int main() {        execlp("login","login","-f","root",0);        return 0;}編譯#

IMX6開發-迅為imx6開發 Cortex A9四核 硬件介紹

imx6摘要: 處理器:Freescale Cortex-A9四核 i.MX6Q主頻 1 GHz 核心板配置:2GB DDR3內存 16GB EMMC存儲 擴展引腳多大320個 運行溫度-20°到+80°之間 豐富接口:支持全網通4G模塊、GPS模塊、WIFI藍牙、SATA接口、千兆以太網、CAN總線、CAM

恩智浦iMX6Q核心/飛思卡爾Cortex-A9高穩定性低功耗開發

        iMX6Q核心板-商業級       iMX6Q-Plus核心板   iMX6DL核心板-商業級   iMX6Q核心板-工業級    &nbs

2-STM32開發(Cortex-M3)和exynos4412(Cortex-A9)之間的區別和聯絡

一、ARM的簡介——what?? part1:ARM代表什麼?     1)ARM是"Advanced RISC Machine"的縮寫,最早的ARM處理器誕生於80年代的英國,目前總部在英國劍橋     2)ARM公司自己並不生產或者銷售晶片,它採用技術授權模式,通過出

基於Exynos4412 cortex A9開發的無線網絡卡驅動移植過程

移植無線網絡卡的驅動: 準備工作: 1.無線網絡卡 2.首先在這個官網上[www.realtek.com.tw](無線網絡卡),下載相應網絡卡的驅動,本次下載的名稱為: 0001RTL8188

基於ARM Cortex-A9四核CPU的exynos4412開發GPIO程式設計案例

GPIO的英文簡稱為General-Purpose IO port,即通用IO介面。介面至少有兩個暫存器,即“通用IO控制暫存器GPxCON”和“通用IO資料暫存器GPxDAT”。在本次程式設計案例中,我們使用的就是以上兩個暫存器,來控制四個LED燈閃爍,實現跑馬燈的功能

基於QEMU的ARM Cortex-A9開發Vexpress-ca9的Linux核心的編譯和執行

Author: KARL-Duj BAT QQ: 30933706 2011 Q群: 37******* 2012 Q群: 20******* 2013 Q群: 58******* 2014 Q群: 39******* 2015 Q

s3c6410開發研究筆記(一)從SD卡啟動UBOOT(未完待續。。。)

背景 6410支援從SD卡啟動,是否可以在SD卡上燒寫一個UBOOT,開發板的跳線設定為SD卡啟動後,將UBOOT執行起來?在UBOOT中可以操作網口(例如 tftp kernel 根檔案系統)、操作NANDFLASH,NORFALSH,方便的進行升級? 資料收集部分 參考