레이블이 Uboot인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Uboot인 게시물을 표시합니다. 모든 게시물 표시

3/29/2020

Uboot 설정 과 Device Tree 처리방법

1. Uboot 구성 및 설정 

Uboot 기본 Manual
  https://www.denx.de/wiki/DULG/Manual

Uboot 의 전체 구성 과 설정방법
  https://gitlab.denx.de/u-boot/u-boot/raw/HEAD/README


  • Uboot 의 명령어
  https://www.denx.de/wiki/view/U-Bootdoc/BasicCommandSet
  https://www.digi.com/resources/documentation/digidocs/PDFs/90000852.pdf
  https://sites.google.com/site/manisbutareed/bringing-my-beagles-to-heel/u-boot-commands
  https://sites.google.com/site/manisbutareed/bringing-my-beagles-to-heel/selected-annotated-u-boot-commands


  • Uboot 환경값
  https://sites.google.com/site/manisbutareed/bringing-my-beagles-to-heel/u-boot-environment-variables


1.1 Uboot 와 DTB 결합구성 


  • Uboot Image 의 구성
  1. Uboot의 DTS를 DTC를 이용하여 DTB 파일생성 
  2. Uboot  Build를 진행 Uboot 파일생성
  3. cat를 이용하여 상위 두개 파일을 하나로 결합 
  4. mkimage를 이용하여 최종 Image 생성 

DTB Image를 최종 합쳐서 Uboot Image로 만들어서 제공

https://rocketboards.org/foswiki/Documentation/A10GSRDV1511GeneratingUBootAndUBootDeviceTree

  • Uboot Build 된곳에서 기본적인확인 
상위 그림처럼 Uboot 와 Uboot의 DTB를 결합하여 최종 Uboot 생성

$ cat dts/.dt.dtb.cmd  //Uboot DTB 파일 
cmd_dts/dt.dtb := cat arch/arm/dts/imx6sx-sdb-emmc.dtb > dts/dt.dtb

$ cat .u-boot-nodtb.bin.cmd  // 일반 Uboot bin 생성 (objcopy)
cmd_u-boot-nodtb.bin := arm-poky-linux-gnueabi-objcopy --gap-fill=0xff  -j .text -j .secure_text -j .secure_data -j .rodata -j .hash -j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn -j .binman_sym_table -j .text_rest -j .dtb.init.rodata -j .efi_runtime -j .efi_runtime_rel -O binary   u-boot u-boot-nodtb.bin

$ cat .u-boot-dtb.bin.cmd    //Uboot 와 DTB 결합 
cmd_u-boot-dtb.bin := cat u-boot-nodtb.bin dts/dt.dtb > u-boot-dtb.bin

$ cat .u-boot.bin.cmd      // Uboot 이름변경 및 최종 uboot
cmd_u-boot.bin := cp u-boot-dtb.bin u-boot.bin   

$ cat .u-boot.imx.cmd // 최종 u-boot image
cmd_u-boot.imx := ./tools/mkimage -n u-boot.cfgout -T imximage -e 0x87800000 -d u-boot.bin u-boot.imx >u-boot.imx.log  && cat u-boot.imx.log

Uboot 와 Kernel 는 각각 DTS 존재하며, 두 DTS가 동일하지만, Uboot의 DTB 와 Kernel DTB는 각각 별도로 사용이 되어지고 있다.

내 개인적인 생각으로는 1st Boot Loader가 Uboot에게 전달하고, Uboot가 다시 Kernel에게 전달하여 전부 공유할 것이라고 생각했는데,
설정을 바꿔서 어떻게 공유할 수 있는지를 알아봐야겠다.
(환경변수 fdtcontroladdr 와  fdt_addr를 동일하게 공유)

Device Tree Boot 기본 구조
아래링크의 그림부분 참조
  https://ahyuo79.blogspot.com/2015/08/am437x-kernel-device-tree.html

TI-Sitara 의 Uboot / Kernel 의 Device Tree 관련부분 복습
  https://ahyuo79.blogspot.com/2015/08/kernel-boot-kernel-device-tree.html
  https://elinux.org/Device_Tree_Reference

Uboot 관련정보정리
  https://www.denx.de/wiki/pub/U-Boot/MiniSummitELCE2014/uboot2014_kconfig.pdf

1.2 Uboot 와 DTB 관련소스분석 

  • Uboot fdt 확인
=> version
U-Boot 2019.04-4.19.35-1.1.0+g4d37753 (May 13 2020 - 07:43:31 +0000)

arm-poky-linux-gnueabi-gcc (GCC) 8.3.0
GNU ld (GNU Binutils) 2.32.0.20190204

=> bdinfo
arch_number = 0x00000000
boot_params = 0x80000100
DRAM bank   = 0x00000000
-> start    = 0x80000000
-> size     = 0x40000000
baudrate    = 115200 bps
TLB addr    = 0xbfff0000
relocaddr   = 0xbff45000
reloc off   = 0x38745000
irq_sp      = 0xbdf359f0
sp start    = 0xbdf359e0
FB base     = 0x00000000
Early malloc usage: fc / 400
fdt_blob    = 0xbdf35a08  //uboot용 dtb (device tree blob) 주소

  • Uboot Config 설정확인 
$ vi .config   // Uboot Config 
....
#
# Partition Types
#
CONFIG_PARTITIONS=y
# CONFIG_MAC_PARTITION is not set
CONFIG_DOS_PARTITION=y
# CONFIG_ISO_PARTITION is not set
# CONFIG_AMIGA_PARTITION is not set
CONFIG_EFI_PARTITION=y
CONFIG_EFI_PARTITION_ENTRIES_NUMBERS=128
CONFIG_EFI_PARTITION_ENTRIES_OFF=0
CONFIG_PARTITION_UUIDS=y
# CONFIG_PARTITION_TYPE_GUID is not set
CONFIG_SUPPORT_OF_CONTROL=y
CONFIG_DTC=y

#
# Device Tree Control
#
## 아래 설정으로 Uboot에서 Device Tree 사용 (fdt 사용가능)
CONFIG_OF_CONTROL=y          
# CONFIG_OF_BOARD_FIXUP is not set
# CONFIG_OF_LIVE is not set
## 아래 설정때문에 cat u-boot.bin u-boot.dtb >image.bin 결합 
CONFIG_OF_SEPARATE=y
# CONFIG_OF_EMBED is not set
# CONFIG_OF_BOARD is not set
# CONFIG_OF_PRIOR_STAGE is not set
CONFIG_DEFAULT_DEVICE_TREE="imx6sx-sdb-emmc"
# CONFIG_MULTI_DTB_FIT is not set
CONFIG_MKIMAGE_DTC_PATH="dtc"

#
# Environment
#
# CONFIG_ENV_DEFAULT_NOWHERE is not set
# CONFIG_ENV_IS_IN_EEPROM is not set
# CONFIG_ENV_IS_IN_FAT is not set
# CONFIG_ENV_IS_IN_EXT4 is not set
# CONFIG_ENV_IS_IN_FLASH is not set
CONFIG_ENV_IS_IN_MMC=y
.....


  • Uboot Linker Script 
$ vi arch/arm/cpu/u-boot.lds  

        .rel_dyn_end :
        {
                *(.__rel_dyn_end)
        }

        .end :
        {
                *(.__end)
        }

        _image_binary_end = .;

//binary 로 변경시 아래부분은 필요없음 

        /*
         * Deprecated: this MMU section is used by pxa at present but
         * should not be used by new boards/CPUs.
         */
        . = ALIGN(4096);
        .mmutable : {
                *(.mmutable)
        }
.....
$ vi u-boot.map // System.map 재확인 

  • Uboot Source 확인
Uboot Config 기반으로 소스확인

$ vi common/board_r.c
......
static init_fnc_t init_sequence_r[] = {
        initr_trace,
        initr_reloc,
...
#ifdef CONFIG_MMC
        initr_mmc,
#endif
        initr_env,
....
        run_main_loop,
};

static int initr_env(void)
{
        /* initialize environment */
        if (should_load_env())
                env_relocate();
        else
                set_default_env(NULL, 0);
// 매번 Booting 때마다 fdtcontroladdr 변수설정하기 때문에 User가 변경해도 소용없음 
// Uboot에서 printenv로 확인가능하며 상위 CONFIG확인 
#ifdef CONFIG_OF_CONTROL
        env_set_hex("fdtcontroladdr",
                    (unsigned long)map_to_sysmem(gd->fdt_blob));  
#endif

        /* Initialize from environment */
        load_addr = env_get_ulong("loadaddr", 16, load_addr);

        return 0;
}

상위 설정대로 했을 경우 아래 bold 체가 실행

$ vi lib/fdtdec.c  // Uboot의 dtb부분 처리를 이해가능 

#if defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE)
/*
 * For CONFIG_OF_SEPARATE, the board may optionally implement this to
 * provide and/or fixup the fdt.
 */
__weak void *board_fdt_blob_setup(void)
{
        void *fdt_blob = NULL;
#ifdef CONFIG_SPL_BUILD
        /* FDT is at end of BSS unless it is in a different memory region */
        if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS))
                fdt_blob = (ulong *)&_image_binary_end;
        else
                fdt_blob = (ulong *)&__bss_end;
#else
        //CONFIG_OF_SEPARATE만 사용해서 uboot 끝에서 fdt를 가져옴 (Linker Script 참조)
        /* FDT is at end of image */
        fdt_blob = (ulong *)&_end;     
#endif
        return fdt_blob;
}
#endif

int fdtdec_setup(void)
{
#if CONFIG_IS_ENABLED(OF_CONTROL)   // 현재설정 CONFIG_OF_CONTROL=y

# if CONFIG_IS_ENABLED(MULTI_DTB_FIT) // 현재 미설정 # CONFIG_MULTI_DTB_FIT is not set
        void *fdt_blob;
# endif

# ifdef CONFIG_OF_EMBED  // 현재 미설정 # CONFIG_OF_EMBED is not set
        /* Get a pointer to the FDT */
#  ifdef CONFIG_SPL_BUILD // 현재 미설정 
        gd->fdt_blob = __dtb_dt_spl_begin;
#  else
        gd->fdt_blob = __dtb_dt_begin;
#  endif
# elif defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) // 현재 이부분만 실행 
        /* Allow the board to override the fdt address. */
        gd->fdt_blob = board_fdt_blob_setup();  // 상위함수 참고 CONFIG_OF_BOARD는 미설정
# elif defined(CONFIG_OF_HOSTFILE)
        if (sandbox_read_fdt_from_file()) {
                puts("Failed to read control FDT\n");
                return -1;
        }
# endif
# ifndef CONFIG_SPL_BUILD  // 현재 미설정 
        /* Allow the early environment to override the fdt address */
#  if CONFIG_IS_ENABLED(OF_PRIOR_STAGE)   // 현재 미설정 # CONFIG_OF_PRIOR_STAGE is not set
        gd->fdt_blob = (void *)prior_stage_fdt_address;
#  else
// 상위에서 설정된 gd->fdt_blob 변수 fdtcontroladdr의 기본값으로 읽어옴 
//bdinfo 와 printenv 확인가능 
        gd->fdt_blob = map_sysmem
                (env_get_ulong("fdtcontroladdr", 16,
                               (unsigned long)map_to_sysmem(gd->fdt_blob)), 0); 
#  endif
# endif

# if CONFIG_IS_ENABLED(MULTI_DTB_FIT)   // 현재미설정 # CONFIG_MULTI_DTB_FIT is not set
        /*
         * Try and uncompress the blob.
         * Unfortunately there is no way to know how big the input blob really
         * is. So let us set the maximum input size arbitrarily high. 16MB
         * ought to be more than enough for packed DTBs.
         */
        if (uncompress_blob(gd->fdt_blob, 0x1000000, &fdt_blob) == 0)
                gd->fdt_blob = fdt_blob;

        /*
         * Check if blob is a FIT images containings DTBs.
         * If so, pick the most relevant
         */
        fdt_blob = locate_dtb_in_fit(gd->fdt_blob);
        if (fdt_blob) {
                gd->multi_dtb_fit = gd->fdt_blob;
                gd->fdt_blob = fdt_blob;
        }

# endif
#endif

        return fdtdec_prepare_fdt();
}

이전의 Uboot 관련소스
  https://lists.denx.de/pipermail/u-boot/2012-July/127516.html
  https://gitlab.labs.nic.cz/turris/u-boot-turris/commit/eea63e05d0b7f54e7aa39725015483972c71cb3c

  • Uboot의 DTB  설정확인
$ vi arch/arm/dts/Makefile
....
dtb-$(CONFIG_MX6SX) += \
        imx6sx-14x14-arm2.dtb \
        imx6sx-17x17-arm2.dtb \
        imx6sx-17x17-arm2-ecspi.dtb \
        imx6sx-17x17-arm2-gpmi-weim.dtb \
        imx6sx-19x19-arm2.dtb \
        imx6sx-19x19-arm2-ecspi.dtb \
        imx6sx-19x19-arm2-gpmi-weim.dtb \
        imx6sx-sabreauto.dtb \
        imx6sx-sdb.dtb \
        imx6sx-sdb-emmc.dtb
.....


1.3 Uboot 의 Flattened Device Tree (FDT)

Uboot는 DTB File을 Memory 에 Load하여 기본 확인가능하며, 이를 수정도 가능한 명령이 fdt 명령어이다.
uImage 에서 사용하게 될 dtb, 즉 kernel 용 dtb를 fdt 명령어를 이용하여 이를 확인해보자.

fdt 명령어 설명 (세부명령어 참조)
  https://www.denx.de/wiki/view/DULG/UBootCmdFDT#Section_5.9.7.2.
  https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18841676/U-Boot+Flattened+Device+Tree

  • Uboot 에서 Kernel의 DTB 정보확인 
Kernel에서 사용하게될 DTB 정보확인

=>pri
...
mmcdev=3
mmcpart=1
fdt_addr=0x83000000
fdt_file=undefined.dtb
loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}   
.....
=> setenv fdt_file imx6sx-sdb-emmc.dtb  //DTB File 이름변경 

=> run loadfdt        //상위 명령어 실행 (eMMC or SDcard의 Device의 Partition에서 File 읽기 
49954 bytes read in 15 ms (3.2 MiB/s)

=> fdt addr ${fdt_addr}  // FDT address 설정 

=> fdt list  // DTB 파일을 볼수 있음 
....
=> fdt print // DTB 파일을 세부적으로 확인 
....

1.4 Uboot Env 분석 및 Hush Shell Script 확장 

i.MX6의 경우 이전에 TI의 Uboot Env보다 좀 더 잘 구성이 되어있어 이부분을 간단정리

=> pri
baudrate=115200
boot_fdt=try
bootargs=console=ttymxc0,115200 rdinit=/linuxrc clk_ignore_unused
bootcmd=run findfdt; mmc dev ${mmcdev}; if mmc rescan; then if run loadbootscript; then run bootscript; else if run loadimage; then run mmcboot; else run netboot; fi; fi; else run netboot; fi
bootcmd_mfg=run mfgtool_args;if iminfo ${initrd_addr}; then if test ${tee} = yes; then bootm ${tee_addr} ${initrd_addr} ${fdt_addr}; else bootz ${loadaddr} ${initrd_addr} ${fdt_addr}; fi; else echo "Run fastboot ..."; fastboot 0; fi;
bootdelay=3
bootscript=echo Running bootscript from mmc ...; source   // source command를 이용하여 boot.scr 실행 (default loadaddr) 
console=ttymxc0
emmc_ack=0
emmc_dev=3
eth1addr=c2:42:5a:9f:cd:09
ethact=ethernet@02188000
ethaddr=26:E1:2C:C4:C7:C6
ethprime=eth0
fastboot_bytes=adc00
fastboot_dev=mmc
fdt_addr=0x83000000       // Kernel용 DTB 주소 (DRAM) 
fdt_file=undefined        // Kernel용 DTB File 이름
fdt_high=0xffffffff       // DTB MAX DRAM MAX 
fdtcontroladdr=bdf35a08  // Uboot 용 DTB 주소 (DRAM)  
filesize=adc00
findfdt=if test $fdt_file = undefined; then setenv fdt_file imx6sx-sdb-emmc.dtb; fi;
image=zImage
initrd_addr=0x86800000
initrd_high=0xffffffff
ip_dyn=yes
kboot=bootz
loadaddr=0x80800000
loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};  // eMMC에서 bootscript 읽어서 쉽게확장
loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file} // Kernel DTB File 읽기
loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}  // Kernel Image
loadm4image=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${m4image} // qspi용 Kernel Image로 추정
loadtee=fatload mmc ${mmcdev}:${mmcpart} ${tee_addr} ${tee_file}  // 보안 boot 
m4_qspi_cs=2
m4boot=sf probe 1:${m4_qspi_cs}; bootaux 0x78000000
m4image=m4_qspi.bin
mfgtool_args=setenv bootargs console=${console},${baudrate} rdinit=/linuxrc clk_ignore_unused
mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot}
mmcautodetect=yes
mmcboot=echo Booting from mmc ...; run mmcargs; if test ${tee} = yes; then run loadfdt; run loadtee; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi; fi;
mmcdev=3
mmcpart=1
mmcroot=/dev/mmcblk3p2 rootwait rw
netargs=setenv bootargs console=${console},${baudrate} root=/dev/nfs ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp
netboot=echo Booting from net ...; run netargs; if test ${ip_dyn} = yes; then setenv get_cmd dhcp; else setenv get_cmd tftp; fi; ${get_cmd} ${image}; if test ${tee} = yes; then ${get_cmd} ${tee_addr} ${tee_file}; ${get_cmd} ${fdt_addr} ${fdt_file}; bootm ${tee_addr} - ${fdt_addr}; else if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if ${get_cmd} ${fdt_addr} ${fdt_file}; then bootz ${loadaddr} - ${fdt_addr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;fi;
panel=Hannstar-XGA
script=boot.scr  // FAT에서 boot.scr를 만들어 설정확장
sd_dev=3
serial#=121a59d4f21fe636
soc_type=imx6sx
tee=no
tee_addr=0x84000000
tee_file=uTee-6sxsdb
update_m4_from_sd=if sf probe 1:${m4_qspi_cs}; then if run loadm4image; then setexpr fw_sz ${filesize} + 0xffff; setexpr fw_sz ${fw_sz} / 0x10000; setexpr fw_sz ${fw_sz} * 0x10000; sf erase 0x0 ${fw_sz}; sf write ${loadaddr} 0x0 ${filesize}; fi; fi


  • i.MX6의 경우 HW bootmode에 따라 bootcmd의 실행변경
  1. bootcmd: 일반 boot  Mode
  2. bootcmd_mfg: Download Mode (uuu라는 Program을 이용하여 fastboot이용)

  • Download Mode (fastboot이용)
i.MX6는 Download Mode 일 경우 USB를 통해서 Window/Linux의 uuu(mfgtools) Program을 이용하여 boot가 가능하다.
PC (USB Host) / i.MX6 (USB Device) 로 동작이되며, Uboot에서 fastboot를 이용하여 usb로 각 Data를 Download를 하고, eMMC or SDCard를 Write를 진행한다.
PC용 fastboot로는 연결해보지 못하고 오직 uuu라는 Program만 사용해봄

  • bootcmd 일 경우 
상위를 간단히 분석을 해보면 확장을 위해서 별도의 Uboot Script 파일을 읽어 User에서 Uboot의 설정을 변경가능하도록 만들었다.

  • loadbootscript (확장의 용이성)
Linux의 User에서 수정가능한 Uboot Script(boot.scr)가 존재하며, Linux User는 Uboot Env를 쉽게 이를 이용하여 변경이 가능하다.

TI-Sitara Uboot Script 및 Device Tree 설정
  https://ahyuo79.blogspot.com/2015/08/uboot-script-device-tree.html


1.5 Uboot Env 값 고정값으로 설정 

Env값들 중 변경 불가능 값들이 존재하여 관련된 소스분석 아래와 같이 board init 할때 마다 env_set 관련 function을 이용하여 직접 설정

$ cd uboot
$ vi include/configs/mx6sxsabresd.h   // 기본적인 uboot의 default env 값으로 saveenv 로 user가 각각 변경가능

#define CONFIG_EXTRA_ENV_SETTINGS \       //default env 값들 (saveenv 변경가능하지만, 변경불가능한 값 원인분석)
...............

#define CONFIG_BOOTCOMMAND \             // bootcmd 값  (saveenv 변경가능) 
           "run findfdt; " \
           "mmc dev ${mmcdev}; if mmc rescan; then " \
                   "if run loadbootscript; then " \
                           "run bootscript; " \
                   "else " \
                           "if run loadimage; then " \
                                   "run mmcboot; " \
                           "else run netboot; " \
                           "fi; " \
                   "fi; " \
           "else run netboot; fi"

//mmcdev 와 mmcroot의 경우 saveenv로 변경을해도 board_init 할때마다 새로설정됨  
$ vi board/freescale/common/mmc.c  
....
void board_late_mmc_env_init(void)
{
        char cmd[32];
        char mmcblk[32];
        u32 dev_no = mmc_get_env_dev();

        if (!check_mmc_autodetect())
                return;

//mmcdev 값 고정  , saveenv로 변경해도 기본값으로 설정 
        env_set_ulong("mmcdev", dev_no);

//mmcroot 값 고정 , saveenv로 변경해도 기본값으로 설정 
        /* Set mmcblk env */
        sprintf(mmcblk, "/dev/mmcblk%dp2 rootwait rw",
                mmc_map_to_kernel_blk(dev_no));
        env_set("mmcroot", mmcblk);

        sprintf(cmd, "mmc dev %d", dev_no);
        run_command(cmd, 0);
}


2. Uboot 의 Command Script 관리 

예전의 Uboot 보다 점점 많은 명령어를 지원해주고 있으며, fastboot를 비롯하여, 각종 filesystem도 마음대로 접근이 가능하며,
다양한 Hardware Interface도 지원을 해주고 있어 Hush shell 를 잘 이용하면 일반 Shell Script 못지않게 잘 사용할 수 있을 것 같다.

각종 사용되어지는 Image 관리부터 각각의 Interface check 기능 및다양한 Program을 쉽게 작성이 가능할 것 같다.

Hush Shell Script
  https://sites.google.com/site/manisbutareed/bringing-my-beagles-to-heel/5-to-be-continued

// Android의 fastboot 기능 
fastboot  - run as a fastboot usb or udp device
// Partition 
gpt       - GUID Partition Table
part      - disk partition related commands

// File system 관리 명령어 
fstype    - Look up a filesystem type
fatsize   - determine a file's size

ext2load  - load binary file from a Ext2 filesystem
ext2ls    - list files in a directory (default /)
ext4load  - load binary file from a Ext4 filesystem
ext4ls    - list files in a directory (default /)
ext4size  - determine a file's size
ext4write - create a file in the root directory

fatinfo   - print information about filesystem
fatload   - load binary file from a dos filesystem
fatls     - list files in a directory (default /)
fatmkdir  - create a directory
fatrm     - delete a file
fatsize   - determine a file's size
fatwrite  - write file into a dos filesystem

// DTB 관리 
fdt       - flattened device tree utility commands


2.1  Uboot의 mmc command 사용


=> mmc
mmc - MMC sub system

Usage:
mmc info - display info of the current MMC device
mmc read addr blk# cnt
mmc write addr blk# cnt
mmc erase blk# cnt
mmc rescan
mmc part - lists available partition on current mmc device
mmc dev [dev] [part] - show or set current mmc device [partition]
mmc list - lists available devices
mmc hwpartition [args...] - does hardware partitioning
  arguments (sizes in 512-byte blocks):
    [user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes
    [gp1|gp2|gp3|gp4 cnt [enh] [wrrel {on|off}]] - general purpose partition
    [check|set|complete] - mode, complete set partitioning completed
  WARNING: Partitioning is a write-once setting once it is set to complete.
  Power cycling is required to initialize partitions after set to complete.
mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode
 - Set the BOOT_BUS_WIDTH field of the specified device
mmc bootpart-resize   
 - Change sizes of boot and RPMB partitions of specified device
mmc partconf dev [boot_ack boot_partition partition_access]
 - Show or change the bits of the PARTITION_CONFIG field of the specified device
mmc rst-function dev value
 - Change the RST_n_FUNCTION field of the specified device
   WARNING: This is a write-once field and 0 / 1 / 2 are the only valid values.
mmc setdsr  - set DSR register value

MMC 사용예제
  https://forums.xilinx.com/t5/ACAP-and-SoC-Boot-and/U-boot-Mmc-read-write/td-p/891742

  • mmc 기본확인
=> mmc list
FSL_SDHC: 1
FSL_SDHC: 2 (SD)
FSL_SDHC: 3 (eMMC)

=> mmc dev 3   //mmc device 선택 
switch to partitions #0, OK
mmc3(part 0) is current device

=> mmc part

Partition Map for MMC device 3  --   Partition Type: DOS

Part    Start Sector    Num Sectors     UUID            Type
  1     8192            45668           304dec68-01     0c Boot
  2     57344          445688          304dec68-02     83
  3     507904          524288          304dec68-03     83

=> mmc dev 2  //mmc device 선택 
switch to partitions #0, OK
mmc2 is current device

=> mmc part

Partition Map for MMC device 2  --   Partition Type: DOS

Part    Start Sector    Num Sectors     UUID            Type
  1     129             3911551         02751898-01     0c


  • mmc erase/write/read 방법
//SD Card의 Partition1 에서 File read 
=> fatload mmc 2:1 ${loadaddr} core-lora-image-imx6sxsabresd.wic 
528482304 bytes read in 35944 ms (14 MiB/s)

=> mmc dev 3   //mmc device 선택 
switch to partitions #0, OK
mmc3(part 0) is current device

=> pri loadaddr
loadaddr=0x80800000

//0x82400000  = 0x80800000 + 0x1C00000 ( 57344*512)
// Start Sector 0xE000(57344) 
// Num Sectors 0x6CCF8‬(445688)
// mmc read/write/erase HEX로 밖에 동작이 안됨 

=> mmc erase 0xE000 0x6CCF8‬ //eMMC erase
MMC erase: dev # 3, block # 57344, count 445688 ...

=> mmc write 0x82400000 0xE000 0x6CCF8‬ //eMMC Write 
MMC write: dev # 3, block # 57344, count 445688 ... 445688 blocks written: OK

=> mmc read 0x82400000 0xE000 0x6CCF8‬ //eMMC Write 
MMC read: dev # 3, block # 57344, count 445688 ... 445688 blocks read: OK

상위 정보는 linux application에서 fdisk -l 의 정보와 동일하며, image는 dd를 이용하여 편집가능

2.2 Uboot Script 생성

상위에서 사용했던 방법들을 간단히 정리하여 Script로 만들어서 이를 확장하는 방법을 알아보자.


  • 환경변수로 분할한 후 마지막에 연결
SDcard에서 image를 읽고 write한 후 bootscript 삭제
$ vi myboot0.cmd
setenv upgrade_read fatload mmc 2:1 ${loadaddr} core-lora-image-imx6sxsabresd.wic 
setenv upgrade_write mmc write 0x82400000 0xE000 0x6CCF8‬ 
setenv upgrade_remove fatrm mmc 2:1 ${script}
setenv upgradelog_start         echo ======== Simple Upgrade Script
setenv upgradelog_success       echo ======== Succeed to upgrade the firmware
setenv upgradelog_success_read  echo ======== Succeed to read the firmware
setenv upgradelog_success_write echo ======== Succeed to wirte the firmware
setenv upgradelog_fail_read     echo ======== Failed to read a firmware file 
setenv upgradelog_fail_write    echo ======== Failed to write a firmware file 
setenv upgrade_targets read write remove 
setenv upgrade_loop "for target in ${upgrade_targets}; do run upgrade_${target}; done" 
setenv upgrade_select "run upgradelog_start; if run upgrade_read; then if run upgrade_write; then run upgrade_remove; else run upgradelog_fail_write; fi; else run upgradelog_fail_read; fi"
run upgrade_select


  • 전체순차적으로 실행 
SDcard 삽입시 계속 Loop에 지속적으로 실행되며, SD Card 제거시 동작 중지
$ vi myboot1.cmd
echo ======== Simple Version Upgrade Script;
setenv targetaddr ${loadaddr};
if test $version = 1; then
   echo "======== checked your firmware version";
   setenv upgrade_read fatload mmc 2:1 ${loadaddr} core-lora-image-imx6sxsabresd.wic
   setenv upgrade_write mmc write 0x82400000 0xE000 0x6CCF8
   if run upgrade_read; then
      echo "======== Ok found a SD card upgrade file";
      echo "======== Start to upgrade a firmware";

      if run upgrade_write; then
         echo "======== Ok write the firmware into eMMC";
         setenv version 2; 
         mw  ${targetaddr} 0 100;
         mw  ${targetaddr} 0x43435553 1;
         setexpr targetaddr $targetaddr + 4;
         mw  ${targetaddr} 0x20535345 1;
         fatwrite mmc 2:1 ${loadaddr} result.txt 8         
      else
         echo "======== failed to write the image to eMMC";
         mw  ${targetaddr} 0 100;
         mw  ${targetaddr} 0x4c494146 1;
         setexpr targetaddr $targetaddr + 4;
         mw  ${targetaddr} 0x20 1;
         fatwrite mmc 2:1 ${loadaddr} result.txt
         setenv version 0
      fi
   else
      echo "======== failed to read the image from SD card";
      mw  ${targetaddr} 0 100;
      mw  ${targetaddr} 0x4c494146 1;
      setexpr targetaddr $targetaddr + 4;
      mw  ${targetaddr} 0x20 1;
      setenv version 0;
   fi
else
   echo "======== its same version";
   mw  ${targetaddr} 0 100;
   mw  ${targetaddr} 0x454d4153 1;
   setexpr targetaddr $targetaddr + 4;
   mw  ${targetaddr} 0x52455620 1;
   setexpr targetaddr $targetaddr + 4;
   mw  ${targetaddr} 0x4e4f4953 1;
   fatwrite mmc 2:1 ${loadaddr} result.txt
fi
saveenv;
reset;
boot script example
  https://boundarydevices.com/boot-scripts-for-main-line-u-boot-on-i-mx6/


  • boot scirpt 생성

아래와 같이 기본이 PowerPC로 되어있으므로, 가능하다면, ARM으로 변경해서 사용하자. (아래와 같이 사용해도 동작가능)

$ mkimage -T script -C none -n 'Uboot Script File' -d myboot0.cmd boot.scr
Image Name:   Uboot Script File
Created:      Fri May 15 17:00:50 2020
Image Type:   PowerPC Linux Script (uncompressed)
Data Size:    271 Bytes = 0.26 kB = 0.00 MB
Load Address: 00000000
Entry Point:  00000000
Contents:
   Image 0: 263 Bytes = 0.26 kB = 0.00 MB


$ mkimage -T script -C none -n 'Uboot Script File' -d myboot1.cmd boot.scr
Image Name:   Uboot Script File
Created:      Mon May 18 10:56:40 2020
Image Type:   PowerPC Linux Script (uncompressed)
Data Size:    979 Bytes = 0.96 kB = 0.00 MB
Load Address: 00000000
Entry Point:  00000000
Contents:
   Image 0: 971 Bytes = 0.95 kB = 0.00 MB


  • boot script 적용

=> setenv version 1 // version 입력
=> setenv loadbootscript fatload mmc 2:1 ${loadaddr} ${script}; // SD Card Read로 변경 
=> saveenv
=> reset

setenv loadbootscript fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};

  https://www.denx.de/wiki/view/DULG/UBootScripts

이를 이용하여 간단히 Upgrade script 도 간단히 만들수 있다.

12/07/2016

Uboot Nand Command 와 설정확인

1. Uboot env 설정 확인 및 설정 

TI-Davinci Series를 다시 사용할줄을 몰랐으며, 이 오래된 모델을 대학원 교육용으로 팔기위해서 간단히 설정정리하고자 한다.

  • Board Information (RAM Info)
U-Boot# bdinfo
arch_number = 0x00000BBC
env_t       = 0x00000000
boot_params = 0x80000100
DRAM bank   = 0x00000000
-> start    = 0x80000000
-> size     = 0x40000000
DRAM bank   = 0x00000001
-> start    = 0xC0000000
-> size     = 0x40000000
ethaddr     = d0:ff:50:af:35:52
ip_addr     = 192.168.1.78
baudrate    = 115200 bps

  • NAND info 
U-Boot# nand info
Device 0: nand0, sector size 128 KiB

  • Uboot default env info
U-Boot# pri
bootdelay=3
baudrate=115200
autoload=yes
verify=yes
bootfile=uImage
ramdisk_file=ramdisk.gz
loadaddr=0x81000000
script_addr=0x80900000
loadbootscript=fatload mmc 0 ${script_addr} boot.scr
bootscript= echo Running bootscript from MMC/SD to set the ENV...; source ${script_addr}
ethaddr=d0:ff:50:af:35:52
ethact=cpsw
ipaddr=192.168.219.201
serverip=192.168.219.112
bootcmd=nand read 0x81000000 0x00280000 0x300000;bootm 0x81000000
bootargs=console=ttyO0,115200n8 earlyprintk noinitrd rootwait=1 rw ubi.mtd=4,2048 rootfstype=ubifs root=ubi0:rootfs notifyk.vpssm3_sva=0xBF900000 mem=364M@0x80000000 mem=320M@0x9FC00000 mem=1023M@0xC0000000 vmalloc=500M ip=none vram=50M ti814xfb.vram=0:24M,1:16M,2:6M

DM368 IPNC :>pri
bootdelay=4
baudrate=115200
bootfile="uImage"
setboot=setenv bootargs $(bootargs)
broadcast=192.168.0.255
gateway=192.168.0.1
ethaddr=00:0C:0C:A0:04:22
verify=no
filesize=2100000
fileaddr=82000000
netmask=255.255.255.0
ipaddr=192.168.0.207
serverip=192.168.0.210
bootcmd=nboot 0x80700000 0 0x500000;bootm 0x80700000
bootargs=mem=48M console=ttyS1,115200n8 noinitrd ip=192.168.1.168:192.168.1.210:192.168.1.1:255.255.255.0:::off rw ubi.mtd=3,2048 rootfstype=ubifs root=ubi0:rootfs cmemk.phys_start=0x83000000 cmemk.phys_end=0x88000000 cmemk.phys_start_1=0x00001000 cmemk.phys_end_1=0x00008000 cmemk.pools_1=1x28672 cmemk.allowOverlap=1 cmemk.useHeapIfPoolUnavailable=1 nohz=off highres=off clocksource=acpi_pm lpj=1077248 eth=00:0C:0C:A0:04:22
stdin=serial
stdout=serial
stderr=serial
ver=U-Boot 1.3.4 (Jun  5 2013 - 12:45:48) DM368-IPNC-5.1.0

Environment size: 843/131068 bytes


CPSW관련
  http://processors.wiki.ti.com/index.php/AM335x_CPSW_(Ethernet)_Driver's_Guide

  • Uboot Config 
U-BOOT는 환경설정은 Device의 의존적인 환경변수존재하며, Uboot도 Kernel Config처럼 Config를 설정하여 추가하고 싶을 설정,
즉 Command를 추가가능하다. 또한 Config 설정에서 각각의 프롬프트 이름을 비롯하여 default env 설정부분을 Uboot Source에서 직접 변경가능하다.

아래는 기본적인 테스트이며, 최종으로 본인의 default env 설정확정되면, Uboot Source에서 default env 관련 부분을 수정하도록 하자.

1.1. Uboot 에서 Kernel 부팅시 문제사항 정리 

  • U-BOOT에서 uncompressing 한 후 바로 멈춤경우
Bytes transferred = 2720236 (2981ec hex)
## Booting kernel from Legacy Image at 81000000 ...
   Image Name:   Linux-2.6.37
   Image Type:   ARM Linux Kernel Image (uncompressed)
   Data Size:    2720172 Bytes = 2.6 MiB
   Load Address: 80008000
   Entry Point:  80008000
   Verifying Checksum ... OK
   Loading Kernel Image ... OK
OK

Starting kernel ...

Uncompressing Linux... done, booting the kernel.  


  • 기본Boot 문제해결방법 (이외방법은 아래 사이트 참조)
Serial 설정 문제확인
bootargs 설정문제 해결하기위해서 uboot에 rootwait를 추가.

printenv bootargs
bootargs=console=ttyS2,115200n8 root=/dev/mmcblk0p2 rw rootwait

세부사항은 kernel argument 참조
  https://linux-sunxi.org/Kernel_arguments

  • 일반적인 Boot 문제사항들 (아래사이트 확인) 
일반적으로 boot 시 발생하는 문제사항 정리
  http://processors.wiki.ti.com/index.php/Kernel_-_Common_Problems_Booting_Linux
bootmem 에러나서 관련내용
  http://jake.dothome.co.kr/bootmem/

  • U-BOOT NAND 문제사항
   jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at
   https://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/716/t/244611
   http://naito.tistory.com/entry/jffs2scaneraseblock-Magic-bitmask-0x1985-not-found-at-0x0000fcac-0x0b45-instead

  • NXP에서 제공하고 U-Boot Quick Reference
IMX6을 하면서 읽게되었지만, 역시 문서가 쉽고 이해하기가 쉬운거 같다
  http://www.nxp.com/files/32bit/doc/quick_ref_guide/MEDIA5200UBPG/MEDIA5200UBPG.pdf


1.2. Uboot 기본환경변수로 테스트  

Uboot가 booting 한 후 Uboot의 bootdelay 설정시간이후에 Uboot의 bootcmd는 자동실행되어 Uboot의 bootargs를 kernel에 전달하여 Kernel Boot를 진행한다.


  • DM368 설정 (bootcmd)
DM368 IPNC :> setenv verify no                                  // CRC에러 
DM368 IPNC :> setenv bootcmd 'nboot 0x80700000 0 0x500000;bootm 0x80700000'

  • DM8147 설정(bootargs)
아래와 같이 ${} 본인이 원하는 환경변수 별도로 이용하여 각 설정을 변경

U-Boot# setenv bootargs_ubifsrw "console=ttyO0,115200n8 earlyprintk noinitrd rootwait=1 rw ubi.mtd=4,2048 rootfstype=ubifs root=ubi0:rootfs notifyk.vpssm3_sva=0xBF900000 mem=364M@0x80000000 mem=320M@0x9FC00000 mem=1023M@0xC0000000 vmalloc=500M ip=none vram=50M ti814xfb.vram=0:24M,1:16M,2:6M"
U-Boot# setenv bootargs_ubifsro "console=ttyO0,115200n8 earlyprintk noinitrd rootwait=1 ro ubi.mtd=4,2048 rootfstype=ubifs root=ubi0:rootfs notifyk.vpssm3_sva=0xBF900000 mem=364M@0x80000000 mem=320M@0x9FC00000 mem=1023M@0xC0000000 vmalloc=500M ip=none vram=50M ti814xfb.vram=0:24M,1:16M,2:6M"
U-Boot# setenv bootargs "${bootargs_ubifsro}" 
U-Boot# setenv bootargs "${bootargs_ubifsro} ${serverip}"  

bootcmd 인 경우 좀 특별한데 명령어들을 자동으로 실행해주는 환경변수이므로 보다 주의해서 작성하자.
Uboot는 기본적인 Shell 처럼 간단한 Uboot Script도 작성가능하므로 이를 최대이용
  1. 기본적으로 다른 환경변수는 표시는다음과 같이 한다.    ${ name }
  2. Command 구분자 ';' 세미콜론을 사용한다. 
  3. bootcmd에는 run 명령어로 다른 환경변수를 실행가능하다. 
  4. bootcmd에는 기본명령어인 setenv 비롯하여 uboot command가 실행가능
  5. 이외 외부 script 및 if 문도 사용가능        

* 주의사항  setenv or set 할 경우 "" or '' 권하며, 하지 않아도 설정은 되지만 간혹 제대로 설정이 되지 스페이스문제로 설정이 안되는 경우가 발생한다. 

1.3. Uboot Network/Video 기본설정 

bootargs 설정을 NFS로 변경하기 위해서 아래와 같이 각각 변경을 해주고 최후에 bootargs의 root를 network로 설정

NFS설정을 위해 아래와 같이 Uboot에 Network 기본설정 아래와 같이 해준다.
  • Network 환경설정 및 확인 
U-Boot# set serverip 192.168.1.100
U-Boot# set ipaddr 192.168.1.39
U-Boot# set gatewayip 192.168.1.1
U-Boot# set netmask 255.255.255.0
U-Boot# set hostname "jhlee-VirtualBox"
U-Boot# set nfspath "/home/jhlee/dm8148/targetfs"

DM368 IPNC :> setenv ethaddr 00:0C:0C:A0:04:22
DM368 IPNC :> setenv ipaddr 192.168.1.20
DM368 IPNC :> setenv gateway 192.168.1.1
DM368 IPNC :> setenv serverip 192.168.1.100
DM368 IPNC :> setenv netmask 255.255.255.0


  • Host에서 Hostname 확인 
 jhlee@jhlee-VirtualBox:~/dm8148$ hostname
jhlee-VirtualBox


* 주의사항 
  1. set은 setenv와 동일 (가끔씩 set이 동작이 안될때는 setenv로 변경)
  2. hostname 가급적 server이름을 설정해야겠지만, 아무거나 설정해도 무방하다.
  3. nfs mount test는 server에서 반드시 TEST 해보자. 

  • DM814x Video 설정 (2G M설정)
  1. mem =xxx : linux memory 설정
  2. vpssm3

set videoset "notifyk.vpssm3_sva=0xBF900000 mem=364M@0x80000000 mem=320M@0x9FC00000 mem=1023M@0xC0000000 vmalloc=500M vram=50M ti814xfb.vram=0:24M,1:16M,2:6M"

  1. 기본설정확인 (Start 0x80000000  : Size : 512M or 1024M or 2048M) 
  2. 현재 2GM사용하지만, 512M와 1024M 만 지원 (1024 Memory Map 선택)
  3. 0xC0000000 이후 부터 Linux로 모두 할당 
  4. Memory를 연속적으로 설정하지 않았기때문에, 이부분 설정을 따로 해야할 것 같다.
설정시 아래의 Memory Map을 반드시 참조.
  http://processors.wiki.ti.com/index.php/EZSDK_Memory_Map
  http://lxr.linux.no/linux/mm/Kconfig


1.4 Uboot의 bootargs 와 bootcmd 

  • UBIFS 와 NFS Boot Mode (bootargs의 분할)
현재 UBIFS를 RW모드와 RO모드 두개 설정하며, NFS도 일반모드 설정과 뒤에 다시 MEM 설정하기에 이를 지운다.


  • bootargs를 여러개 옵션으로 분할
U-Boot# set bootarg_consol "console=ttyO0,115200n8"
U-Boot# set bootarg_debug  "earlyprintk rootwait=1"
U-Boot# set bootarg_etc    "noinitrd"  
U-Boot# set bootarg_ubifsro  "ro ubi.mtd=4,2048 rootfstype=ubifs root=ubi0:rootfs"
U-Boot# set bootarg_ubifsrw "rw ubi.mtd=4,2048 rootfstype=ubifs root=ubi0:rootfs"
U-Boot# set bootarg_nfs "rw root=/dev/nfs nfsroot=${serverip}:${nfspath},nolock"
U-Boot# set bootarg_net "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:eth0:off"
U-Boot# set bootarg_netnone "ip=none" 

  • bootargs를 조합하여 설정진행 
setnenv bootargs를 상위 변수들을 조합하여 재설정

U-Boot# setenv args_nfs 'setenv bootargs ${bootarg_consol} ${bootarg_debug} ${bootarg_etc}  ${bootarg_nfs} ${bootarg_net} ${videoset}'
U-Boot# setenv args_ubiro 'setenv bootargs ${bootarg_consol} ${bootarg_debug} ${bootarg_etc}  ${bootarg_ubifsro} ${bootarg_netnone} ${videoset}'
U-Boot# setenv args_ubirw 'setenv bootargs ${bootarg_consol} ${bootarg_debug} ${bootarg_etc}  ${bootarg_ubifsrw} ${bootarg_netnone} ${videoset}'

  • bootargs를 UBIFS로 직접설정
DM368 IPNC :> setenv bootargs mem=48M console=ttyS1,115200n8 noinitrd ip=192.168.1.168:192.168.1.210:192.168.1.1:255.255.255.0:::off rw ubi.mtd=3,2048 rootfstype=ubifs root=ubi0:rootfs cmemk.phys_start=0x83000000 cmemk.phys_end=0x88000000 cmemk.phys_start_1=0x00001000 cmemk.phys_end_1=0x00008000 cmemk.pools_1=1x28672 cmemk.allowOverlap=1 cmemk.useHeapIfPoolUnavailable=1 nohz=off highres=off clocksource=acpi_pm lpj=1077248 eth=00:0C:0C:A0:04:22

  • bootargs를 NFS로 직접설정
  1. nfsrootdebug: nfs debug 가능
  2. rootdelay=4: filesystem mount 시점을 조절가능
  3. earlyprintk: KERNEL 의 CONFIG_EARLY_PRINTK=y 설정후 가능
  4. quiet: 에러 이외의 메세지를 보고 싶지 않다면 사용

DM368 IPNC :> setenv bootargs 'console=ttyS1,115200n8 rw mem=48M root=/dev/nfs nfsrootdebug rootdelay=4 nfsroot=192.168.1.100:/home/jhlee/dm368/mt5/Source/ipnc_rdk/target/filesys_dm368,nolock mem=48M cmemk.phys_start="0x83000000" cmemk.phys_end="0x88000000" cmemk.phys_start_1="0x00001000" cmemk.phys_end_1="0x00008000" cmemk.pools_1="1x28672" cmemk.allowOverlap=1 eth=00:0C:0C:A0:04:22 ip=192.168.1.168 nohz=off highres=off clocksource=acpi_pm lpj=1077248 earlyprintk'

NFS Boot Mode
  https://www.kernel.org/doc/Documentation/filesystems/nfs/nfsroot.txt
Kernel Argument (bootargs)
  https://www.kernel.org/doc/Documentation/kernel-parameters.txt

  • bootcmd의 분할과 bootargs 설정 
  1. dhcp : dhcp client로 동작 tftp로 uImage가져온다.
  2. autoload: dhcp에서 자동으로 tftp로 uImage 가져오는 작업을 막는다.
  3. loadaddr: tftp 할 경우 loadaddr주소
  4. tftp or tftpboot: tftp로 data를 가져온다.

아래와 같이 다양한 bootcmd를 지원가능하도록  분할하여 쉽게 구성하도록하자

U-Boot# set autoload no
U-Boot# set loadaddr 0x81000000

U-Boot# set bootcmd_nfs1 'dhcp;run args_nfs; tftp uImage-dm814x-evm.bin;bootm'
U-Boot# set bootcmd_nfs2 'dhcp;run args_nfs; tftp 0x81000000 uImage;bootm'
U-Boot# set bootcmd_nfs3 "dhcp;run args_nfs; tftpboot uImage-dm814x-evm.bin;bootm"

U-Boot# set bootcmd_nfs  'run args_nfs; tftp uImage;bootm'
U-Boot# set bootcmd_ubi  "run args_ubirw;nand read 0x81000000 0x00280000 0x300000;bootm 0x81000000"
U-Boot# set bootcmd_ubi_me  'run args_ubirw; tftp uImage;bootm'

  •  bootcmd의 NFS/UBI_ME/UBI 설정
U-Boot# set bootcmd "run bootcmd_nfs"
U-Boot# set bootcmd "run bootcmd_ubi_me"
U-Boot# set bootcmd "run bootcmd_ubi"

  • U-BOOT의 환경변수 설명 (반드시 확인)
  http://www.denx.de/wiki/DULG/UBootEnvVariables
  http://www.denx.de/wiki/view/DULG/UBootEnvVariables

  • U-BOOT NFS 환경설정 
  http://processors.wiki.ti.com/index.php/DM814x_AM387x_PSP_U-Boot#Environment_Settings_for_NFS_Filesystem
  http://www.denx.de/wiki/publish/DULG/to-delete/LinuxNfsRoot.html


2. Board 의 정보파악 후 검증

  • Memory info 
Memory Start Address 와 Memory Size를 bdinfo로 파악하자.
이 정보가 잘못되었다면, datasheet를 이용하여 파악하자. (Memory Map)

  • NAND info 
Nand의 Memory Map 주소와 각 영역의 Size를 파악하자.
제대로 동작한다면, Kernel에서 mtd에서 알려준다.

 
NAND device: Manufacturer ID: 0x2c, Chip ID: 0xcc (Micron )
Creating 5 MTD partitions on "omap2-nand.0":
0x000000000000-0x000000020000 : "U-Boot-min"
0x000000020000-0x000000260000 : "U-Boot"
0x000000260000-0x000000280000 : "U-Boot Env"
0x000000280000-0x0000006c0000 : "Kernel"
0x0000006c0000-0x000020000000 : "File System"

Kernel command line: console=ttyO0,115200n8 earlyprintk noinitrd rootwait=1 rw ubi.mtd=4,2048 rootfstype=ubifs root=ubi0:rootfs notifyk.vpssm3_sva=0xBF900000 mem=364M@0x80000000 mem=320M@0x9FC00000 mem=1023M@0xC0000000 vmalloc=500M ip=none vram=50M ti814xfb.vram=0:24M,1:16M,2:6M

nand page size : 2048


  • 기본검증방법 
Memory Size를 정확히 파악한 후 Image의 size를 생각하여, 두 Memory 주소를 얻는다.
본인은 1G Memory이며, 0x8000 0000 : DDR START ADDR
                                0x4000 0000 : 1 G

0x81000000  부터 U-BOOT Application을 사용가능하다고, U-BOOT msg에서 파악.
0xA0000000  Size : 0x20000000 : 256M

위의 nand address를 파악해서 이제 검증시작하자.

  https://processors.wiki.ti.com/index.php/Booting_Linux_kernel_using_U-Boot

2.1 Uboot의 Memory TEST

Uboot에서 사용해보니, 너무느리며, 비효율적이다. 만약 시간이 많다면, 사용하고, 시간이 없다면, tftpboot kernel을 이용하여 DRAM을 검증하자.
그리고, NFS System도 같이 이용한다면 더욱 좋을 것 같다.

  • Uboot의 memory test 
U-Boot#  mtest 0x81000000 
U-Boot#  mtest 0x81000000  0x82000000


2.2 Uboot의 NAND TEST

NAND의 Test의 목적은 bad block문제로 인하여 nand boot가 제대로 안되는 것인지 파악하고, NAND의 read/write가 제대로 동작이 되는지를 확인하는 것이다.
일단 nand info를 통해 nand 기본정보를 파악하고, bad block이 scrub 이 되었는지  확인해보자.

nand bad를 해보면 bad block 정보를 읽어 표시해준다.
nand createbbt 명령어가 없을 경우 최근 version uboot는 이 명령어가 사라져 버리고 자동으로 scan해서 만들어 버리는 것 같다.
Uboot version마다 다를수 있으므로, 주의하자

2.3 NAND Image 기본검증

일단 tftpboot를 통해서 kernel의 Image 검증한 후 각각의 NAND Read/Write를 하여 문제없는지 확인하자.

  • TFTPBOOT TEST
DM368 IPNC :> tftpboot 0x80007FC0 dm368ipnc/uImage_ipnc_dm368
DM368 IPNC :> bootm 0x80007FC0;

  • How To update KERNEL & Filesystem
DM368 IPNC :> tftpboot 0x80700000 dm368ipnc/uImage_ipnc_dm368
DM368 IPNC :> tftpboot 0x82000000 dm368ipnc/ipnc_dm368_ubifs

DM368 IPNC :> nand erase 0x500000 0x400000               // NAND ERASE 4MB  
DM368 IPNC :> nand write 0x80700000 0x500000 0x400000    // KERNEL WRITE 4MB

DM368 IPNC :> nand erase 0x900000 0x2800000              //NAND ERASE 4MB
DM368 IPNC :> nand write 0x82000000 0x900000 0x2800000   //FS  WRITE 40MB


  • NAND Image 검증
DM368 IPNC :> tftpboot 0x80700000 dm368ipnc/uImage_ipnc_dm368
DM368 IPNC :> nand read 0x82000000 0x500000 0x400000   // KERNEL READ 4MB
DM368 IPNC :> cmp 0x80700000 0x82000000  0x38a420      // check tftpboot 

상위와 동일함
U-Boot#  tftp 0x81000000 uImage
Bytes transferred = 2215324 (21cd9c hex) 

U-Boot#  nand read 0xA0000000 0x280000 0x21cd9c 

// 553831 = 2215324/4 bytes 

U-Boot#  cmp   0x81000000 0xA0000000 553831
U-Boot#  cmp.l 0x81000000 0xA0000000 553831
 
word at 0x8121cd9c (0x605f9029) != word at 0x8221cd9c (0xffffffff)
Total of 553831 words were the same 

8/17/2015

Uboot DRAM 설정 (DM812x)

1. DM8128 의 EVM의 구성 

  • EVM Board 구성
  1. BOARD-NAME: DM8128-IPNC
  2. BOARD-VER   :
  3. RAM Type     : K4B1G1646E
  4. RAM Size      :  2 x (16x 64M, 1Gb) = 2Gb = 256MB 

이 오래된 모델을 대학원 교육용으로 팔기위해서 간단히 설정정리한다.

2. RAM의 기본이해 및 다른 SOC Setting 

TI의 Sitara 기준으로 간단히 설명
  https://ahyuo79.blogspot.com/search/label/RAM-DRAM

2.1 Uboot 설정 및 CCS TEST

아래사이트의 두 항목을 보고 쉽게 수정이 가능하며, CCS TEST 가능하다

  1. Modifying U-Boot
  2. Register to U-Boot Macro Definition Mapping Table
  http://processors.wiki.ti.com/index.php/TI814x-DDR3-Init-U-Boot

2.2 DRAM의 SW Leveling 

만약, DDR의 선로의 길이 확장으로 인해 SW-Leveling 사용해야한다면, 아래부분 참조
Leveling은 대해 좀더 알고 싶다면 상위 RAM부분을 읽어보고 파악하자

  http://processors.wiki.ti.com/index.php/TI814x-DDR3-Init-U-Boot_Wordwise_SWleveling

2.3 DDR Power Optimization

  Docs/Application_Notes/IPNC_RDK_Power_Optimization.pdf

  • DM8127 전체 Power 조절에 관한 내용이 있음
       1. Interleaving 문제로 16bit로 두개연결이 성능이 가장 뛰어남.
       2. DeepSleep과 IO Power optimization 부분 및 VTP 조절

 
3. DDR 관련 설정 


$ cd ~/dm8127/work/Source/ti_tools/ipnc_psp_04_04_00_01/u-boot 
  • DM8127 CONFIG 

$ vi include/config.h
$ vi include/configs/ti8148_ipnc.h

  • DDR관련소스 

$ vi ./board/ti/ti8148_ipnc/evm.c


3.1 Uboot의 DRAM SOURCE


  • DDR 설정 관련소스
$ vi board/ti/ti8148_ipnc/evm.c
                dram_init                  // 확장시 확인 필요
                is_ddr3()                  // ddr3 동작 , return 1
                config_ti814x_ddr()        // 이 부분 설정
                ddr_pll_config()           // CLOCK 변경 ,DDR_PLL_533

  • 설정부분 
arch/arm/include/asm/arch-ti81xx/ddr_defs_ti814x.h      // 설정값 변경
arch/arm/include/asm/arch-ti81xx/clocks_ti814x.h        // DDR_M


3.2 Uboot DDR Timing 설정 및 Clock 설정

  • DDR TIMING 및 CONFIG 부분

$ vi arch/arm/include/asm/arch-ti81xx/ddr_defs_ti814x.h 
....
#else //CONFIG_DM385_DDR3_533

/* TI814X DDR3 EMIF CFG Registers values 400MHz */
#define DDR3_EMIF_READ_LATENCY          0x00170208   //RD_ODT=0x2, IDLE_ODT=0x0, Dynamic power_down enabled
#define DDR3_EMIF_TIM1                  0x0AAAD4DB
#define DDR3_EMIF_TIM2                  0x682F7FDA
#define DDR3_EMIF_TIM3                  0x501F82BF
#define DDR3_EMIF_REF_CTRL              0x00000C30
#define DDR3_EMIF_SDRAM_CONFIG          0x61C011B2
#define DDR3_EMIF_SDRAM_ZQCR            0x50074BE1

#endif

        아래는 U-BOOT Name과 Reg-Name 및 OFFSet을 간단히 Mapping 하였습니다.

#define EMIF4_0_CFG_BASE                0x4C000000
#define EMIF4_1_CFG_BASE                0x4D000000
          U-BOOT Name                   Reg-Name     OFFSET
#define DDR3_EMIF_READ_LATENCY          DDRPHYCR      (E4h)
#define DDR3_EMIF_TIM1                  SDRTIM1       (18h)
#define DDR3_EMIF_TIM2                  SDRTIM2       (20h)
#define DDR3_EMIF_TIM3                  SDRTIM3       (28h) 
#define DDR3_EMIF_REF_CTRL              SDRRCR        (10h)
#define DDR3_EMIF_SDRAM_CONFIG          SDRCR         (08h) 
#define DDR3_EMIF_SDRAM_ZQCR            ZQCR          (C8h)

  • DDR CLOCK 설정 
현재 DDR_PLL_533 정의되어있으나, 400MHz 동작됨 


$ vi arch/arm/include/asm/arch-ti81xx/clocks_ti814x.h

#define DDR_PLL_533     /* Values supported 400,533 */
.....
#define DDR_N           19
#ifdef CONFIG_DM385
/* DDR PLL */
/* For 400 MHz */
#if defined(DDR_PLL_400)
#define DDR_M           (opp_val_dm385(800, 800))
#endif

/* For 533 MHz */
#if defined(DDR_PLL_533)
#define DDR_M       (opp_val_dm385(1066, 1066))
#endif
#else
#define DDR_M           (pg_val_ti814x(666, 800))
#endif
#define DDR_M2          2
#define DDR_CLKCTRL     0x801
$ vi ./board/ti/ti8148_ipnc/evm.c

static void ddr_pll_config()
{
        pll_config(DDR_PLL_BASE,
                        DDR_N, DDR_M,
                        DDR_M2, DDR_CLKCTRL);
}


 AM437x 와 유사하며, maxium frequecies를 확인을 반드시 확인하자.
 일반적은 Maximum Clock 400MHz이며, overclock해서 533MHz를 사용가능

  • 확인사항들 
         위 부분은 TI DM814x의 SPRUGZ8F와 회로도를 참고하여, 위 설정값을 변경하자.
         DDR_M: CPU의 Version에 따라 666 or 800 되지만, PG2_1 이기에,  800 사용
         1. DEVOSC_MX0 : APPRO 회로도에서 20MHz 확인 (DEVOSC_MX0=CLKINP)
         2. CLKOUT    : [M /(N+1)] * CLKINP * [1/M2]
                            **    800/20 * 20*1/2 = 400 MHz   최종 CLOCK
         3. CLKOUT: DDR0_PHY Clock, DDR1_PHYClock, DMM clock and EMIFmclk.

  • 관련내용 (SPRUGZ8F.pdf)

             2.3.5 DDR PLL Clock
             2.5.3 DPLLS Clock Function 참조
             8.4.10 Module Clock (Maximum Clock 확인)
             8.2.2.1 DVFS ( Maximum Clock 확인)
           

3.3 DDR3 Datasheet Timing 


  • K4B1G1646E 의 TIMING 

  • DDR3로 16bit로 연결시 




TI에서는 손쉽게 Timing 설정이 가능하도록 Tool을 제공을 한다.

  • DM8127 관련 설정 
AM43xx 용을 고쳐서 DM8127용으로 내가 새로 만들었다.
  https://docs.google.com/spreadsheets/d/1ZXFmWqTe1SLkZ-KmxYmUkfUR1GQwOV-Pms0-Fj7J1xA/edit?usp=sharing


  • AM43xx용 
  https://drive.google.com/open?id=0B_ehveuLi8MVV1lXaW0zLTZ1ZVE


4. DDR설정 및 확인

DM8127는 EMIF에 현재 16bit 모드로 연결되어 있기때문에 아래와 같이 EMIF를 개별로 각각 설정을 해줘야 한다. (EMIF0, EMIF1)

$ vi arch/arm/include/asm/arch-ti81xx/cpu.h

#define EMIF4_0_CFG_BASE                0x4C000000
#define EMIF4_1_CFG_BASE                0x4D000000

.....

#define EMIF4_0_SDRAM_ZQCR              (EMIF4_0_CFG_BASE + 0xC8)
#define EMIF4_0_SDRAM_CONFIG            (EMIF4_0_CFG_BASE + 0x08)
#define EMIF4_0_SDRAM_CONFIG2           (EMIF4_0_CFG_BASE + 0x0C)
#define EMIF4_0_SDRAM_REF_CTRL          (EMIF4_0_CFG_BASE + 0x10)
#define EMIF4_0_SDRAM_REF_CTRL_SHADOW   (EMIF4_0_CFG_BASE + 0x14)
#define EMIF4_0_SDRAM_TIM_1             (EMIF4_0_CFG_BASE + 0x18)
#define EMIF4_0_SDRAM_TIM_1_SHADOW      (EMIF4_0_CFG_BASE + 0x1C)
#define EMIF4_0_SDRAM_TIM_2             (EMIF4_0_CFG_BASE + 0x20)
#define EMIF4_0_SDRAM_TIM_2_SHADOW      (EMIF4_0_CFG_BASE + 0x24)
#define EMIF4_0_SDRAM_TIM_3             (EMIF4_0_CFG_BASE + 0x28)
#define EMIF4_0_SDRAM_TIM_3_SHADOW      (EMIF4_0_CFG_BASE + 0x2C)
#define EMIF4_0_DDR_PHY_CTRL_1          (EMIF4_0_CFG_BASE + 0xE4)
#define EMIF4_0_DDR_PHY_CTRL_1_SHADOW   (EMIF4_0_CFG_BASE + 0xE8)
#define EMIF4_0_IODFT_TLGC              (EMIF4_0_CFG_BASE + 0x60)

#ifndef CONFIG_DM385
#define EMIF4_1_SDRAM_ZQCR              (EMIF4_1_CFG_BASE + 0xC8)
#define EMIF4_1_SDRAM_CONFIG            (EMIF4_1_CFG_BASE + 0x08)
#define EMIF4_1_SDRAM_CONFIG2           (EMIF4_1_CFG_BASE + 0x0C)
#define EMIF4_1_SDRAM_REF_CTRL          (EMIF4_1_CFG_BASE + 0x10)
#define EMIF4_1_SDRAM_REF_CTRL_SHADOW   (EMIF4_1_CFG_BASE + 0x14)
#define EMIF4_1_SDRAM_TIM_1             (EMIF4_1_CFG_BASE + 0x18)
#define EMIF4_1_SDRAM_TIM_1_SHADOW      (EMIF4_1_CFG_BASE + 0x1C)
#define EMIF4_1_SDRAM_TIM_2             (EMIF4_1_CFG_BASE + 0x20)
#define EMIF4_1_SDRAM_TIM_2_SHADOW      (EMIF4_1_CFG_BASE + 0x24)
#define EMIF4_1_SDRAM_TIM_3             (EMIF4_1_CFG_BASE + 0x28)
#define EMIF4_1_SDRAM_TIM_3_SHADOW      (EMIF4_1_CFG_BASE + 0x2C)
#define EMIF4_1_DDR_PHY_CTRL_1          (EMIF4_1_CFG_BASE + 0xE4)
#define EMIF4_1_DDR_PHY_CTRL_1_SHADOW   (EMIF4_1_CFG_BASE + 0xE8)
#define EMIF4_1_IODFT_TLGC              (EMIF4_1_CFG_BASE + 0x60)
#endif
$ vi board/ti/ti8148_ipnc/evm.c

static void config_ti814x_ddr(void)
{
....

 /*Program EMIF0 CFG Registers*/
                __raw_writel(DDR3_EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_1);
                __raw_writel(DDR3_EMIF_READ_LATENCY, EMIF4_0_DDR_PHY_CTRL_1_SHADOW);
                __raw_writel(DDR3_EMIF_TIM1, EMIF4_0_SDRAM_TIM_1);
                __raw_writel(DDR3_EMIF_TIM1, EMIF4_0_SDRAM_TIM_1_SHADOW);
                __raw_writel(DDR3_EMIF_TIM2, EMIF4_0_SDRAM_TIM_2);
                __raw_writel(DDR3_EMIF_TIM2, EMIF4_0_SDRAM_TIM_2_SHADOW);
                __raw_writel(DDR3_EMIF_TIM3, EMIF4_0_SDRAM_TIM_3);
                __raw_writel(DDR3_EMIF_TIM3, EMIF4_0_SDRAM_TIM_3_SHADOW);
                __raw_writel(DDR3_EMIF_SDRAM_CONFIG, EMIF4_0_SDRAM_CONFIG);

....

/*Program EMIF1 CFG Registers*/
                __raw_writel(DDR3_EMIF_READ_LATENCY, EMIF4_1_DDR_PHY_CTRL_1);
                __raw_writel(DDR3_EMIF_READ_LATENCY, EMIF4_1_DDR_PHY_CTRL_1_SHADOW);
                __raw_writel(DDR3_EMIF_TIM1, EMIF4_1_SDRAM_TIM_1);
                __raw_writel(DDR3_EMIF_TIM1, EMIF4_1_SDRAM_TIM_1_SHADOW);
                __raw_writel(DDR3_EMIF_TIM2, EMIF4_1_SDRAM_TIM_2);
                __raw_writel(DDR3_EMIF_TIM2, EMIF4_1_SDRAM_TIM_2_SHADOW);
                __raw_writel(DDR3_EMIF_TIM3, EMIF4_1_SDRAM_TIM_3);
                __raw_writel(DDR3_EMIF_TIM3, EMIF4_1_SDRAM_TIM_3_SHADOW);
                __raw_writel(DDR3_EMIF_SDRAM_CONFIG, EMIF4_1_SDRAM_CONFIG);

....

}

위와 같이 변경후, DDR 설정은 SPL에서 진행이 되므로, SPL 변경 후, TEST를 진행하자.

SPL 파일:  u-boot.min.sd을 MLO 변경후 SDIMAGE 생성후 TEST   각 REGISTER 확인은 아래와 같이, md 명령으로 확인 (boot가 될 경우)

* SPL도 기본 U-BOOT 명령은 동작한다.
TI-MIN# md 0x4C000018
TI8148_IPNC# md 0x4C000018 


AM437x DDR 의 AC Timing 설정 TOOL을 DM8127에 맞게 수정하고 SDBOOT로 변경하고 이값으로 기본적으로 TEST를 함.

8/14/2015

Uboot Script 이해 및 Device Tree Boot 설정 (Sitara)

1. Uboot Env 환경변수 

setenv or set : 명령이용하여 환경변수 설정가능 uboot에서 많은 환경변수를 제공하며, script기능도 제공

1.1 Uboot Hush Script 이해

환경변수 설정과 기본 script 실행하는 방법은 아래와 같으며, Uboot에서 사용하는 Command는 Uboot 빌드시 CONFIG 옵션에 따라
변경되기 때문에 차이는 있지만, 기본 Command들은 대체적으로 알아두자.

  • UBoot의 기본 env 와 command 이해 
  1. bootcmd:  uboot가 기본적으로 실행되는 변수 (가장중요)
  2. 이외에 암묵적으로 많이 사용하는 환경변수가 존재 (stdin,stdout, 등 ) 
  3. script의 기본은 uboot cmd의 나열로 구성하고 환경변수 및 구분자를 세미콜론사용
  4. run을 이용하여 만들어진 script을 실행가능 
  5. setenv 이용하여 환경변수 및 script 생성  

  • UBoot Script 의 확장이해 
  1. if <list>; then <command list>; [elif <list>; then <list>; ] [else <list>; then <list>;]
  2. while <list>; do <list>; done
  3. until <list>; do <list>; done
  4. for <name> in <word list>; do <list> ; done

1,2,3 앞에 test command를 이용하여 비교가 가능하며,  뒤에 는 script or 환경변수를 넣으면 된다.   

  http://www.compulab.co.il/utilite-computer/wiki/index.php/U-Boot_Scripts

1.2 Uboot Hush Script 의 예제 

위에서 확장으로 사용되는 예제들을 한번 살펴보자.

  • Uboot Script  if 문 test 예제 
test command를 이용하여 비교하고, 그 결과을 적용

findfdt=if test $board_name = AM43EPOS; then setenv fdtfile am43x-epos-evm.dtb; fi; if test $board_name = AM43__GP; then setenv fdtfile am437x-gp-evm.dtb; fi; if test $board_name = AM43__SK; then setenv fdtfile am437x-sk-evm.dtb; fi; if test $fdtfile = undefined; then echo WARNING: Could not determine device tree; fi; // if문 예제 

  • Uboot Script for 문 예제 
boot_target 이라는 word_list에서 target이라는 변수를 만들어 반복문을 만들어 여러 bootcmd_target을 실행한다.

boot_targets=mmc0 legacy_mmc0 mmc1 legacy_mmc1 nand0 pxe dhcp    // target list 
distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done  //for boot_targets에서 환경변수에서 target을 추출하여 bootcmd_x 실행
bootcmd_dhcp=run boot_net_usb_start; if dhcp ${scriptaddr} ${boot_script_dhcp}; then source ${scriptaddr}; fi
bootcmd_legacy_mmc0=setenv mmcdev 0; setenv bootpart 0:2 ; run mmcboot
bootcmd_legacy_mmc1=setenv mmcdev 1; setenv bootpart 1:2 ; run mmcboot
bootcmd_mmc0=setenv devnum 0; run mmc_boot
bootcmd_mmc1=setenv devnum 1; run mmc_boot
bootcmd_nand=run nandboot
bootcmd_pxe=run boot_net_usb_start; dhcp; if pxe get; then pxe boot; fi

uboot script은 쉽게 이해가능하며, 누구나 쉽게 사용가능.


1.3 외부 Uboot Script 사용방법

  • Uboot에서 Uboot Script 실행
Uboot에서 FAT에서 boot.scr를 읽어서 이를 source를 이용하여 실행하며, 보통 SDCard Boot를 했을 때 사용한다.

U-Boot# pri
...
script_addr=0x80900000
loadbootscript=fatload mmc 0 ${script_addr} boot.scr
bootscript= echo Running bootscript from MMC/SD to set the ENV...; source ${script_addr}
bootcmd=if mmc init; then if run loadbootscript; then run bootscript; else if run loaduimage; then run mmcboot; else run nandboot; f
i; fi; else run nandboot; fi
...

  • 외부 Uboot Script 생성방법
$ vi boot-nfs.txt 
setenv bootargs 'console=ttyO0,115200n8 root=/dev/nfs nfsrootdebug rw rootdelay=10 mem=80M vram=4M notifyk.vpssm3_sva=0xBFD00000 nfsroot=192.168.1.100:/home/jhlee/dm8127/work/Source/ipnc_rdk/target/filesys,nolock eth=32:30:3a:63:64:3a ip=192.168.1.168 cmemk.phys_start=0x85000000 cmemk.phys_end=0x89000000 cmemk.allowOverlap=1 earlyprintk'

$ mkimage -A arm -T script -C none -d boot-nfs.txt  boot.scr // Uboot Script 생성

생성된 boot.scr를 FAT에 복사하여 실행가능하여 이외에도 상위의 if문을 비롯하여 다양한 연속적인 Uboot Script을 생성가능하다


  • mkimage 설치
Uboot안에 mkimage가 존재하지만, PATH설정를 비롯하여 귀찮아서 직접 설치
$ sudo apt-get install uboot-mkimage //mkimage가 없을 경우 설치 

  https://wiki.ubuntu.com/ARM/EditBootscr
  http://www.denx.de/wiki/DULG/UBootScripts

2. Uboot 와 Device Tree Boot 설정 

AM437x와 AM335x는 Uboot에서 손쉽게 Device Tree Boot를 설정변경이 가능하며,
이전에 Device Tree File에 대해서 설명했듯이 zImage와 dtb 파일은 filesystem의 /boot라는 곳에 저장이 되어있다.

Device Tree 관련내용
  https://ahyuo79.blogspot.com/2015/08/kernel-boot-kernel-device-tree.html

  • Uboot 와 Device Tree Boot 역할
각각의 File (zImage와 *.dtb) 들을  Load를 하면 Uboot Device Tree 기본역할은 한것이며, 이 관련 script을 수정을하면된다.


  • Device Tree Boot 설정 변경 (다양한 Kernel 및 Device Tree 선택)
Uboot Script or 환경변수 설정을 변경하여 이를 변경하자
특히 findfdt는 device tree의 file을 설정을 하는 것이며, findfdt 대신 직접 설정을 하여도 좋다.


2.1 Uboot의 boot 분석 (AM437x-EVM-GP)

이제 중요한 uboot에서 dtb을 찾고 zImage를 찾아 booting을 해보자
기본명령어는 다음과 같다

bootz ${loadaddr} - ${fdtaddr} 


FDT (Flattened Device Tree) 는  DTB (Device Tree Blob)를 말하며 관련 구조는 Device Tree Spec를 참조

  • Uboot Env MMC BOOT 분석 
  1. bootcmd : dtb를 찾아 설정 후 mmcboot / usbboot/ nand boot로 순차실행
  2. findfdt : 현재 board_name에 따라 fdtfile 에 dtb 파일설정
  3. mmcboot: mmc device를 설정하고 rescan 
  4. mmcboot: uEnv.txt (uboot Env) File이 존재한다면 찾아 설정 
  5. mmcboot: importenv는 외부에 존재 할 경우,  uenvcmd는 존재할 경우 동작  두부분 생략
  6. mmcboot: loadimage로 kernel을  load_addr로 load 한다 ( File system의 /boot) 
  7. mmcboot: loadfdt로 dtb file을 fdt_addr로 load한다   (File system의 /boot)
  8. mmcboot: mmcargs로 kernel argument 설정
  9. mmcboot: bootz ${loadaddr} - ${fdtaddr} 로 kernel과 dtb booting  


U-Boot# pri
arch=arm
baudrate=115200
board=am43xx
board_name=AM43__GP
board_rev=1.4A
bootcmd=run findfdt; run mmcboot;run usbboot;run nandboot; 
bootdelay=1
bootdir=/boot
bootenv=uEnv.txt
bootfile=zImage
bootm_size=0x10000000
bootpart=0:2
console=ttyO0,115200n8
cpu=armv7
dfu_alt_info_emmc=MLO raw 0x100 0x100 mmcpart 0;u-boot.img raw 0x300 0x1000 mmcpart 0
dfu_alt_info_mmc=boot part 0 1;rootfs part 0 2;MLO fat 0 1;spl-os-args fat 0 1;spl-os-image fat 0 1;u-boot.img fat 0 1;uEnv.txt fat 0 1
dfu_alt_info_ram=kernel ram 0x80200000 0x4000000;fdt ram 0x80f80000 0x80000;ramdisk ram 0x81000000 0x4000000
dfu_bufsiz=0x10000
eth1addr=34:b1:f7:30:fb:00
ethact=cpsw
ethaddr=34:b1:f7:30:f7:fe
fdt_addr_r=0x88000000
fdtaddr=0x88000000
fdtfile=undefined
findfdt=if test $board_name = AM43EPOS; then setenv fdtfile am43x-epos-evm.dtb; fi; if test $board_name = AM43__GP; then setenv fdtfile am437x-gp-evm.dtb; fi; if test $board_name = AM43__SK; then setenv fdtfile am437x-sk-evm.dtb; fi; if test $fdtfile = undefined; then echo WARNING: Could not determine device tree; fi; 
importbootenv=echo Importing environment from mmc ...; env import -t $loadaddr $filesize
kernel_addr_r=0x82000000
loadaddr=0x82000000
loadbootenv=load ${devtype} ${devnum} ${loadaddr} ${bootenv}
loadfdt=load ${devtype} ${bootpart} ${fdtaddr} ${bootdir}/${fdtfile}
loadimage=load ${devtype} ${bootpart} ${loadaddr} ${bootdir}/${bootfile}
loadramdisk=load ${devtype} ${devnum} ${rdaddr} ramdisk.gz
mmcargs=setenv bootargs console=${console} ${optargs} root=${mmcroot} rootfstype=${mmcrootfstype}
mmcboot=mmc dev ${mmcdev}; setenv devnum ${mmcdev}; setenv devtype mmc; if mmc rescan; then echo SD/MMC found on device ${devnum};if run loadbootenv; then echo Loaded environment from ${bootenv};run importbootenv;fi;if test -n $uenvcmd; then echo Running uenvcmd ...;run uenvcmd;fi;if run loadimage; then run loadfdt; echo Booting from mmc${mmcdev} ...; run mmcargs; bootz ${loadaddr} - ${fdtaddr}; fi;fi;
mmcdev=0
mmcroot=/dev/mmcblk0p2 rw
mmcrootfstype=ext4 rootwait
mtdids=nand0=nand.0
mtdparts=mtdparts=nand.0:256k(NAND.SPL),256k(NAND.SPL.backup1),256k(NAND.SPL.backup2),256k(NAND.SPL.backup3),512k(NAND.u-boot-spl-os),1m(NAND.u-boot),256k(NAND.u-boot-env),256k(NAND.u-boot-env.backup1),7m(NAND.kernel),-(NAND.file-system)
nandargs=setenv bootargs console=${console} ${optargs} root=${nandroot} rootfstype=${nandrootfstype}
nandboot=echo Booting from nand ...; run nandargs; nand read ${fdtaddr} NAND.u-boot-spl-os; nand read ${loadaddr} NAND.kernel; bootz ${loadaddr} - ${fdtaddr}
nandroot=ubi0:rootfs rw ubi.mtd=NAND.file-system,4096
nandrootfstype=ubifs rootwait=1
netargs=setenv bootargs console=${console} ${optargs} root=/dev/nfs nfsroot=${serverip}:${rootpath},${nfsopts} rw ip=dhcp
netboot=echo Booting from network ...; setenv autoload no; dhcp; tftp ${loadaddr} ${bootfile}; tftp ${fdtaddr} ${fdtfile}; run netargs; bootz ${loadaddr} - ${fdtaddr}
nfsopts=nolock
partitions=uuid_disk=${uuid_gpt_disk};name=rootfs,start=2MiB,size=-,uuid=${uuid_gpt_rootfs}
ramargs=setenv bootargs console=${console} ${optargs} root=${ramroot} rootfstype=${ramrootfstype}
ramdisk_addr_r=0x88080000
ramroot=/dev/ram0 rw
ramrootfstype=ext2
rdaddr=0x88080000
rootpath=/export/rootfs
soc=am33xx
static_ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off
stderr=serial
stdin=serial
stdout=serial
usbargs=setenv bootargs console=${console} ${optargs} root=${usbroot} rootfstype=${usbrootfstype}
usbboot=setenv devnum ${usbdev}; setenv devtype usb; usb start ${usbdev}; if usb dev ${usbdev}; then if run loadbootenv; then echo Loaded environment from ${bootenv};run importbootenv;fi;if test -n $uenvcmd; then echo Running uenvcmd ...;run uenvcmd;fi;if run loadimage; then run loadfdt; echo Booting from usb ${usbdev}...; run usbargs;bootz ${loadaddr} - ${fdtaddr}; fi;fi;usb stop ${usbdev};
usbdev=0
usbnet_devaddr=34:b1:f7:30:fb:00
usbroot=/dev/sda2 rw
usbrootfstype=ext4 rootwait
vendor=ti
ver=U-Boot 2014.07-gfb6ab76 (Jul 06 2015 - 16:10:49)

Environment size: 4128/65532 bytes 

  • Uboot Env ( NFS - Network 고정 IP Mode)
현재 dhcp를 사용하며 ip가 바뀌어서 고정 ip로 변경하기로 결정.
만약 AP에서 dhcp 세부설정이 가능하다면 위와 같이 사용.

setenv ipaddr '192.168.1.101'
setenv serverip '192.168.1.100'
setenv netmask '255.255.255.0'
setenv rootpath '/home/jhlee/am437x/targetNFS'
setenv netargs 'setenv bootargs console=${console} ${optargs} root=/dev/nfs nfsroot=${serverip}:${rootpath},${nfsopts} rw ip=${ipaddr}' 
setenv netboot1 'echo Booting from network ...; setenv autoload no; tftp ${loadaddr} ${bootfile}; tftp ${fdtaddr} ${fdtfile}; run netargs; bootz ${loadaddr} - ${fdtaddr}'

setenv bootcmd 'run findfdt; run netboot1;'
setenv bootfile 'zImage'
setenv fdtfile 'am437x-gp-evm.dtb'  //직접 설정 후 run findfdt를 삭제가능 


Linux server의 /tftpboot에 bootfile과 fdtfile을 보관해야한다.


2.2 Uboot Env 분석 (AM335x SK, Start Kit )

AM437x와 거의 동일하며 UBOOT에서  zImage와 *.dtb을 변경을 해주면된다.

  • Device Tree Booting Command
bootz ${loadaddr} - ${fdtaddr} 


  • Uboot Env 분석 
=>pri
arch=arm
args_fit=setenv bootargs console=${console} 
args_mmc=run finduuid;setenv bootargs console=${console} ${optargs} root=PARTUUID=${uuid} rw rootfstype=${mmcrootfstype}
baudrate=115200
board=am335x
board_name=A335X_SK
board_rev=1.2B
board_serial=34124P192908
boot_a_script=load ${devtype} ${devnum}:${distro_bootpart} ${scriptaddr} ${prefix}${script}; source ${scriptaddr}
boot_efi_binary=load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} efi/boot/bootarm.efi; if fdt addr ${fdt_addr_r}; then bootefi ${kernel_addr_r} ${fdt_addr_r};elsebootefi ${kernel_addr_r} ${fdtcontroladdr};fi
boot_extlinux=sysboot ${devtype} ${devnum}:${distro_bootpart} any ${scriptaddr} ${prefix}extlinux/extlinux.conf
boot_fdt=try
boot_fit=0
boot_net_usb_start=usb start
boot_prefixes=/ /boot/
boot_script_dhcp=boot.scr.uimg
boot_scripts=boot.scr.uimg boot.scr
boot_targets=mmc0 legacy_mmc0 mmc1 legacy_mmc1 nand0 pxe dhcp 
bootcmd=if test ${boot_fit} -eq 1; then run update_to_fit;fi;run findfdt; run init_console; run envboot; run distro_bootcmd
bootcmd_dhcp=run boot_net_usb_start; if dhcp ${scriptaddr} ${boot_script_dhcp}; then source ${scriptaddr}; fi
bootcmd_legacy_mmc0=setenv mmcdev 0; setenv bootpart 0:2 ; run mmcboot
bootcmd_legacy_mmc1=setenv mmcdev 1; setenv bootpart 1:2 ; run mmcboot
bootcmd_mmc0=setenv devnum 0; run mmc_boot
bootcmd_mmc1=setenv devnum 1; run mmc_boot
bootcmd_nand=run nandboot
bootcmd_pxe=run boot_net_usb_start; dhcp; if pxe get; then pxe boot; fi
bootcount=4
bootdelay=2
bootdir=/boot
bootenvfile=uEnv.txt
bootfile=zImage
bootm_size=0x10000000
bootpart=0:2
bootscript=echo Running bootscript from mmc${mmcdev} ...; source ${loadaddr}
console=ttyO0,115200n8
cpu=armv7
dfu_alt_info_emmc=rawemmc raw 0 3751936
dfu_alt_info_mmc=boot part 0 1;rootfs part 0 2;MLO fat 0 1;MLO.raw raw 0x100 0x100;u-boot.img.raw raw 0x300 0x400;spl-os-args.raw raw 0x80 0x80;spl-os-image.raw raw 0x900 0x2000;spl-os-args fat 0 1;spl-os-image fat 0 1;u-boot.img fat 0 1;uEnv.txt fat 0 1
dfu_alt_info_nand=SPL part 0 1;SPL.backup1 part 0 2;SPL.backup2 part 0 3;SPL.backup3 part 0 4;u-boot part 0 5;u-boot-spl-os part 0 6;kernel part 0 8;rootfs part 0 9
dfu_alt_info_ram=kernel ram 0x80200000 0xD80000;fdt ram 0x80F80000 0x80000;ramdisk ram 0x81000000 0x4000000
distro_bootcmd=for target in ${boot_targets}; do run bootcmd_${target}; done
efi_dtb_prefixes=/ /dtb/ /dtb/current/
envboot=mmc dev ${mmcdev}; if mmc rescan; then echo SD/MMC found on device ${mmcdev};if run loadbootscript; then run bootscript;else if run loadbootenv; then echo Loaded env from ${bootenvfile};run importbootenv;fi;if test -n $uenvcmd; then echo Running uenvcmd ...;run uenvcmd;fi;fi;fi;
eth1addr=d4:94:a1:86:70:e1
ethaddr=d4:94:a1:86:70:e0
fdt_addr_r=0x88000000
fdtaddr=0x88000000
fdtcontroladdr=8ef282f8
fdtfile=undefined
findfdt=if test $board_name = A335BONE; then setenv fdtfile am335x-bone.dtb; fi; if test $board_name = A335BNLT; then setenv fdtfile am335x-boneblack.dtb; fi; if test $board_name = BBG1; then setenv fdtfile am335x-bonegreen.dtb; fi; if test $board_name = A33515BB; then setenv fdtfile am335x-evm.dtb; fi; if test $board_name = A335X_SK; then setenv fdtfile am335x-evmsk.dtb; fi; if test $board_name = A335_ICE; then setenv fdtfile am335x-icev2.dtb; fi; if test $fdtfile = undefined; then echo WARNING: Could not determine device tree to use; fi; 
finduuid=part uuid mmc ${bootpart} uuid
fit_bootfile=fitImage.itb
fit_loadaddr=0x88000000
importbootenv=echo Importing environment from mmc${mmcdev} ...; env import -t ${loadaddr} ${filesize}
init_console=if test $board_name = A335_ICE; then setenv console ttyO3,115200n8;else setenv console ttyO0,115200n8;fi;
kernel_addr_r=0x82000000
load_efi_dtb=load ${devtype} ${devnum}:${distro_bootpart} ${fdt_addr_r} ${prefix}${efi_fdtfile}
loadaddr=0x82000000
loadbootenv=fatload mmc ${mmcdev} ${loadaddr} ${bootenvfile}
loadbootscript=load mmc ${mmcdev} ${loadaddr} boot.scr
loadfdt=load ${devtype} ${bootpart} ${fdtaddr} ${bootdir}/${fdtfile}
loadfit=run args_fit; bootm ${loadaddr}#${fdtfile};
loadimage=load ${devtype} ${bootpart} ${loadaddr} ${bootdir}/${bootfile}
loadramdisk=load mmc ${mmcdev} ${rdaddr} ramdisk.gz
mmc_boot=if mmc dev ${devnum}; then setenv devtype mmc; run scan_dev_for_boot_part; fi
mmcboot=mmc dev ${mmcdev}; setenv devnum ${mmcdev}; setenv devtype mmc; if mmc rescan; then echo SD/MMC found on device ${mmcdev};if run loadimage; then if test ${boot_fit} -eq 1; then run loadfit; else run mmcloados;fi;fi;fi;
mmcdev=0
mmcloados=run args_mmc; if test ${boot_fdt} = yes || test ${boot_fdt} = try; then if run loadfdt; then bootz ${loadaddr} - ${fdtaddr}; else if test ${boot_fdt} = try; then bootz; else echo WARN: Cannot load the DT; fi; fi; else bootz; fi;
mmcrootfstype=ext4 rootwait
mtdids=nand0=nand.0
mtdparts=mtdparts=nand.0:128k(NAND.SPL),128k(NAND.SPL.backup1),128k(NAND.SPL.backup2),128k(NAND.SPL.backup3),256k(NAND.u-boot-spl-os),1m(NAND.u-boot),128k(NAND.u-boot-env),128k(NAND.u-boot-env.backup1),8m(NAND.kernel),-(NAND.file-system)
nandargs=setenv bootargs console=${console} ${optargs} root=${nandroot} rootfstype=${nandrootfstype}
nandboot=echo Booting from nand ...; run nandargs; nand read ${fdtaddr} NAND.u-boot-spl-os; nand read ${loadaddr} NAND.kernel; bootz ${loadaddr} - ${fdtaddr}
nandroot=ubi0:rootfs rw ubi.mtd=NAND.file-system,2048
nandrootfstype=ubifs rootwait=1
netargs=setenv bootargs console=${console} ${optargs} root=/dev/nfs nfsroot=${serverip}:${rootpath},${nfsopts} rw ip=dhcp
netboot=echo Booting from network ...; setenv autoload no; dhcp; run netloadimage; run netloadfdt; run netargs; bootz ${loadaddr} - ${fdtaddr}
netloadfdt=tftp ${fdtaddr} ${fdtfile}
netloadimage=tftp ${loadaddr} ${bootfile}
nfsopts=nolock
partitions=uuid_disk=${uuid_gpt_disk};name=rootfs,start=2MiB,size=-,uuid=${uuid_gpt_rootfs}
pxefile_addr_r=0x80100000
ramargs=setenv bootargs console=${console} ${optargs} root=${ramroot} rootfstype=${ramrootfstype}
ramboot=echo Booting from ramdisk ...; run ramargs; bootz ${loadaddr} ${rdaddr} ${fdtaddr}
ramdisk_addr_r=0x88080000
ramroot=/dev/ram0 rw
ramrootfstype=ext2
rdaddr=0x88080000
rootpath=/export/rootfs
scan_dev_for_boot=echo Scanning ${devtype} ${devnum}:${distro_bootpart}...; for prefix in ${boot_prefixes}; do run scan_dev_for_extlinux; run scan_dev_for_scripts; done;run scan_dev_for_efi;
scan_dev_for_boot_part=part list ${devtype} ${devnum} -bootable devplist; env exists devplist || setenv devplist 1; for distro_bootpart in ${devplist}; do if fstype ${devtype} ${devnum}:${distro_bootpart} bootfstype; then run scan_dev_for_boot; fi; done
scan_dev_for_efi=setenv efi_fdtfile ${fdtfile}; if test -z "${fdtfile}" -a -n "${soc}"; then setenv efi_fdtfile ${soc}-${board}${boardver}.dtb; fi; for prefix in ${efi_dtb_prefixes}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${efi_fdtfile}; then run load_efi_dtb; fi;done;if test -e ${devtype} ${devnum}:${distro_bootpart} efi/boot/bootarm.efi; then echo Found EFI removable media binary efi/boot/bootarm.efi; run boot_efi_binary; echo EFI LOAD FAILED: continuing...; fi; setenv efi_fdtfile
scan_dev_for_extlinux=if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}extlinux/extlinux.conf; then echo Found ${prefix}extlinux/extlinux.conf; run boot_extlinux; echo SCRIPT FAILED: continuing...; fi
scan_dev_for_scripts=for script in ${boot_scripts}; do if test -e ${devtype} ${devnum}:${distro_bootpart} ${prefix}${script}; then echo Found U-Boot script ${prefix}${script}; run boot_a_script; echo SCRIPT FAILED: continuing...; fi; done
scriptaddr=0x80000000
soc=am33xx
spiargs=setenv bootargs console=${console} ${optargs} root=${spiroot} rootfstype=${spirootfstype}
spiboot=echo Booting from spi ...; run spiargs; sf probe ${spibusno}:0; sf read ${loadaddr} ${spisrcaddr} ${spiimgsize}; bootz ${loadaddr}
spibusno=0
spiimgsize=0x362000
spiroot=/dev/mtdblock4 rw
spirootfstype=jffs2
spisrcaddr=0xe0000
static_ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off
stderr=serial@44e09000
stdin=serial@44e09000
stdout=serial@44e09000
update_to_fit=setenv loadaddr ${fit_loadaddr}; setenv bootfile ${fit_bootfile}
usb_boot=usb start; if usb dev ${devnum}; then setenv devtype usb; run scan_dev_for_boot_part; fi
usbnet_devaddr=de:ad:be:ef:00:01
vendor=ti
ver=U-Boot 2016.05-g6c5519b6fc (Dec 14 2016 - 19:14:27 -0500)

Environment size: 8557/131068 bytes

8/05/2015

AM437x Uboot DRAM 설정 및 확인사항

1. AM437x EVM의 구성

  • BOARD-NAME: AM43__GP 
  • BOARD-VER   : 1.4   
  • RAM TYPE : MT41K512M8RH-125 (CS0 PIN ONLY)   
  • RAM SIZE :  4 x (64 Meg x 8 x 8 banks, 4Gb) = 16Gb = 2 GB   
       http://processors.wiki.ti.com/index.php/AM437X_EVM_Boards


2. AM437x DDR3 CONFIG TI-GUIDE 

http://processors.wiki.ti.com/index.php/AM437x_DDR_Configuration_and_Programming_Guide

상위 사이트에서 다 주위깊게 봐야겠지만, U-BOOT에서 기본적으로 자동으로 설정을
하기에, 아래 부분을 주의깊게 봐야겠다.

  • EMIF General Configuration Registers
  • DDR PHY Control Register   ---> 
  • AC Timing Registers (TI에서 Excel을 제공) 
  • Setting Refresh rate 

Power Consumption (옵션)
  • Internal DDR Clocks ( DLL Clock을 사용한다면, 현재 미사용)

3. Uboot DDR CLOCK 설정

DDR 설정은 현재 400MHz 나오며, 이는 외부 오실레이터에 의해 결정된다. (24MHz)
CLOCK부분과 POWER쪽에 전체적인 완벽한 이해는 추후 다시한번해야함.

  • SoC PLL 설정 전체구조

  • PLL의 DDR PLL 구조 


PLL의 INPUT CLOCK은 우선 PRCM.CM_CLKSEL_DPLL_DDR.DPLL_BYP_CLKSEL의 의해  CLKINP or CLKINPULOW 결정되고 (CLKINPULOW는 PM사용시 사용),
            ALT_CLK0,1 TEST 목적으로 사용
            Master OSC : 19.2/24/25/26 MHz  ( 회로도 확인: OSC0 24MHz )

  • EMIF-CLOCK (EMIF Maximum Frequency)

위와 같이 400MHz 동작하지만, Micron DDR3는 이보다 더 지원이 가능함.


3.1 Uboot DDR Clock  


* board/ti/am43xx/board.c
       gp_evm_dpll_ddr
* arch/arm/cpu/armv7/am33xx/clock.c
       setup_dplls->get_dpll_ddr_params()

struct dpll_params {
        u32 m;  //PRCM_CM_CLKSEL_DPLL_DDR->DPLL_MULT 
        u32 n;  //PRCM_CM_CLKSEL_DPLL_DDR->DPLL_DIV  
        s8 m2;  
        s8 m3;  
        s8 m4;    
        s8 m5;  
        s8 m6;
};  

Power Management에 의해 아래와 같이 4가지 모드로 설정이 가능하지만,
GP EVM은 한가지모드로 설정로 설정하여 사용.

const struct dpll_params epos_evm_dpll_ddr[NUM_CRYSTAL_FREQ] = {
                {665, 47, 1, -1, 4, -1, -1}, /*19.2*/
                {133, 11, 1, -1, 4, -1, -1}, /* 24 MHz */
                {266, 24, 1, -1, 4, -1, -1}, /* 25 MHz */
                {133, 12, 1, -1, 4, -1, -1}  /* 26 MHz */
};
// 회로도에서 Input 24MHz 확인 
const struct dpll_params gp_evm_dpll_ddr = {
                50, 2, 1, -1, 2, -1, -1};      // 상위 dpll_params 참조 


3.2 DDR PLL의 계산방법
    TI의 Reference Manual 와 상위 소스 기반으로 설정을 하면된다.

    1. CLKOUT       :  [M / (N+1)] * CLKINP * [1/M2]  = 266MHz
    2. CLKDCOLDO :  2 * [M / (N+1)] * CLKINP         = 532MHz

    GP_BOARD의 경우 다음과 같이 설정
      상위 gp_evm_dpll_ddr기반으로 계산
                  50 / (2+1) * 24 /(1) = 400MHz (OSC: 회로도 확인 24MHz)


    • TI Manual 참고
    1. 6.6.3.1 Clock Functions
    2. 6.6.11 DDR PLL Description ( 666MHz 로 되나, M2 1이면 반으로 됨)
    3. PRCM_CM_CLKSEL_DPLL_DDR

          m2= DFI_CLK (차분CLK),
          m4= DLL CLK 지원


    4. DDR Timing 및 Config 설정

    • DDR3 EMIF PINMAP 
    현재 8bit로 4개로 DDR3 4개가 연결이 되어있으며, 최대 16 bank를 interleaving 가능하므로, 4개는 의미가 없다. (2개가 최적,  2x16bit 가 최적)

    위와 보다시피 , Embeded는 ODT는 사용하지 않는다.

    4.1 Uboot DDR Timing source 
    • Main 관련설정 source 
                   board/ti/am43xx/board.c
                   sdram_init() ->  config_ddr -> set_sdram_timings() // DDR Timing

    • 기타 관련설정 source       
                  arch/arm/include/asm/arch-am33xx/ddr_defs.h
                  arch/arm/cpu/armv7/am33xx/ddr.c
                  arch/arm/cpu/armv7/am33xx/emif4.c


    4.2 Uboot EMIF Config 및 Timing 
    쉽게 설정이 변경이 가능하며, 아래의 Register로 쉽게 Timing 과 Config를 변경하자.

    GP_EVM은 3가지 Version이 존재함 (현재 1.4용)
     
    const struct emif_regs ddr3_emif_regs_400Mhz_production = {
     .sdram_config   = 0x638413B2,
     .ref_ctrl   = 0x00000C30,
     .sdram_tim1   = 0xEAAAD4DB,
     .sdram_tim2   = 0x266B7FDA,
     .sdram_tim3   = 0x107F8678,
     .read_idle_ctrl   = 0x00050000,
     .zq_config   = 0x50074BE4,
     .temp_alert_config  = 0x0,
     .emif_ddr_phy_ctlr_1  = 0x0E004008,
     .emif_ddr_ext_phy_ctrl_1 = 0x08020080,
     .emif_ddr_ext_phy_ctrl_2 = 0x00000066,//
     .emif_ddr_ext_phy_ctrl_3 = 0x00000091,//
     .emif_ddr_ext_phy_ctrl_4 = 0x000000B9,//
     .emif_ddr_ext_phy_ctrl_5 = 0x000000E6,//
     .emif_rd_wr_exec_thresh  = 0x80000405,//
     .emif_prio_class_serv_map = 0x80000001,
     .emif_connect_id_serv_1_map = 0x80000094,
     .emif_connect_id_serv_2_map = 0x00000000,
     .emif_cos_config  = 0x000FFFFF
    };
    


    각 설정을 MT41K512M8RH-125 데이타 시트와 비교하고,DDR3 SDRAM Initialization을 확인하자

    • EMIF의 관련 설정 
    EMIF의 Config 및 Timing, Refresh Register 기반으로 DDR register를 설정을 하기에 설정을 확인을하자.


     
    EMIF4D_SDRAM_CONFIG 0x638413B2  
            SDRAM_TYPE      3 (DDR3)                          SDRAM Type selection.
            IBANK_POS       0 (Decimal)                       Internal bank position. 
            DDR_TERM        3 (RZQ/6)                         DDR3 termination resistor value.  
            LPDDR2_DDQS     1 (differential DQS)              LPDDR2 differential DQS enable.
            DYN_ODT         0 (Turn off DYN_ODT)              DDR3 Dynamic ODT. 
            DDR_DISABLE_DLL 0 (Disable DLL)                   Disable DLL select. 
            SDRAM_DRIVE     1 (Decimal)                       SDRAM drive strength.  0 for RZQ/6 , 1 for RZQ/7   
            CWL             0 (Decimal)                       DDR3 CAS Write latency.  
            NARROW_MODE     0 (32bit)                         SDRAM data bus width. 
            CL              4 (Decimal)                       CAS Latency. 
            ROWSIZE         7 (Decimal)                       Row Size. 
            IBANK           3 (Decimal)                       Internal Bank setup. 
            EBANK           0 (use pad_cs_o_n[0] only)        External chip select setup. 
            PAGESIZE        2 ((9 colum bits))                Page Size. 
    

    관련설정은 AC-TIMING 참고하여 설정하자

    AM437x에는 DDR에 많은기능이 추가되었지만, 사용하지 않으면 필요없다.
    * HW-LEVELING, DLL, 기타 등등

    7/26/2015

    Sitara(AM437x/AM335x) Uboot와 SPL 분석

    1. Open Uboot (Denx)

    TI에서 제공해주는 Uboot말고  opensource site(Denx)에 있는 걸로 직접사용을 해보자.
    open source u-boot는 아래의 사이트에서 기본으로 제공을 해주고 있다.
    아래사이트에서 download를 하여 소스를 받아 간단히 비교 분석해보자.

      http://www.denx.de/wiki/U-Boot/WebHome

    Tool Chain 설치
      https://ahyuo79.blogspot.com/2015/11/arm-tool-chain.html

    1.1 board config 설정 및 Build

    • Board config 확인
    $ ls configs/am43*
    am43xx_evm_defconfig
    am43xx_evm_ethboot_defconfig
    am43xx_evm_qspiboot_defconfig
    am43xx_evm_usbhost_boot_defconfig
    

    • Board config 설정
    Kernel 과 동일하게 Board config를 설정

    $ make am43xx_evm_defconfig
    //.config 가 configs/am43xx_evm_defconfig 기반으로 자동생성 
    // Makefile을 보면 CONFIG_xxx 검색설정은 .config 기반  
    
    $ make menuconfig CROSS_COMPILE=xxx 
    //Kconfig 기반으로 Menu가 구성되고 최종으로 .config 저장 
    

    이제 config가 생성이 되었으니, 아래의 File들을 점검

    include/config.h                //  include/configs/am43xx_evm.h  설정확인
    include/configs/am43xx_evm.h    // 자신의 Board CONFIG 설정확인 
    board/ti/am43xx/board.c         // board_init  분석 및 수정 
    

    • Uboot Build 
    $ make CROSS_COMPILE=xxx          //u-boot Image 생성 

    1.2 General Uboot 기본확인사항 

    다음과 같이 요약할 수 있다.

     1. board config에서 설정확인 (필요하다면 추가 CONFIG , make menuconfig)
     2. board init 에서 DRAM TIMING 수정.  (DRAM이 변경되었다면)    
     3. 함수들을 u-boot.map 이나 다른 map로 확인

    RAM TIMING만 맞추고 CONFIG만 설정하면 된다.

    1.3 일반적인 Uboot 메뉴얼 및 소스 

    • 일반적인 Uboot 메뉴얼 
           http://www.denx.de/wiki/DULG/Manual
           http://www.denx.de/wiki/U-Boot/Documentation

    • Uboot download 및 소스확인
           http://git.denx.de/?p=u-boot.git;a=summary
       
    $ git clone git://git.denx.de/u-boot.git
    


    2. TI Uboot와 일반 Uboot 설정 및 빌드비교 

    TI-Uboot는 기존 Uboot와 거의 기능이 유사하며, mkconfig(shell script)을 사용하여 config 설정하며 이외에도 Uboot에서 제공되지 않는 기능이
    CONFIG가 몇개 추가 되었다. 기존에 Open Source에서 사용하던 config 설정에서 약간 변경이 되었다.

    2.1 TI Uboot

    • Makefile   
    boards.cfg를 참조하며, mkconfig를 실행을 실행하여 설정하고, 빌드시 script와 새로 생성된 만들어진 Makefile Config 파일로 설정하여 빌드한다.
    • mkconfig  
    config를 만드는 shell script (TI에서 추가)
    • boards.cfg 
    board의 설정 및 정보


    • Board 설정 및 빌드
    $ make am43xx_evm_config // mkconfig 수행 ( 설정시 boards.cfg 참조)
    ./arch/arm/include/asm/arch
    ./include/config.h          // GCC CONFIG       , include/configs/am43xx_evm.h 설정 
    ./include/config.mk         // Makefile CONFIG , ( 둘다 기존과 동일하지만 생성시점이 다르다) 
    


    $ make CROSS_COMPILE=xx 
    ./include/spl-autoconf.mk
    ./include/autoconf.mk
    


    *다른설정을 원할 경우,  boards.cfg 에서 참조
      http://processors.wiki.ti.com/index.php/Linux_Core_U-Boot_User's_Guide

    2.2 Open Uboot


    • board 설정 및 빌드 
    $ make am43xx_evm_defconfig
     .config        //Makefile Config     (TI-UBOOT 다른것으로 mkconfig 대체 ) 


    $ make  CROSS_COMPILE=xx
    include/config.h         // GCC       CONFIG    (기존과 동일)
    include/autoconf.mk      // Makefile  CONFIG    (기존과 동일)
    
    ./include/config/auto.conf   // TI-UBOOT 없음 , Makefile CONFIG 설정 
    ./include/autoconf.mk       //  Makefile CONFIG 설정 
    ./include/config.h          //  configs/am43xx_evm.h
    


    이외 부분은 아직 비슷한 FDT 나 SPL기능을 둘다 지원이 가능한 것 같으며,자세한 부분은 소스를 다 분석을 해야 할 것 같다.
      http://www.denx.de/wiki/view/DULG/UBootCmdFDT

    • SPL과 TPL 설정 관련 설명 및 앞으로 변화 
    Chip Vendor와 상관 없이 Uboot의 설정이 점점 변경이 되고 있으며,TI도 이 흐름에 따라가고 있을 뿐인것 같다.
    아래의 문서는 반드시 한번 읽어봐야한다.
      http://www.denx.de/wiki/pub/U-Boot/MiniSummitELCE2014/uboot2014_kconfig.pdf


    3. TI Uboot Guide 

    아래는 TI에서 제공해주는 Guide 이며, 반드시 개발하기 전에 읽어야 한다.

    • TI에서 제공하는 Sitara U-BOOT를 의 종합 기능설명 
      Sitara U-BOOT Build 및 BOOT모드 설정 및 환경구성 설명이며,
      Sitara를 사용한다면, 반드시 한번 읽어봐야한다.
      http://processors.wiki.ti.com/index.php/Linux_Core_U-Boot_User's_Guide

    • AM335x용 UBOOT User Guide
      AM335x용 UserGuide로 각 BOOT 모드를 설명 및  Flashing 방법을 설명. (참고용)
      http://processors.wiki.ti.com/index.php/AM335x_U-Boot_User's_Guide

    • ETHERNET 관련설정 
      http://processors.wiki.ti.com/index.php/Linux_Core_CPSW_User's_Guide

    • NAND Boot 할 경우 및 NAND 사용할 경우 Guide 
      http://processors.wiki.ti.com/index.php/Linux_Core_NAND_User's_Guide
      http://processors.wiki.ti.com/index.php/Linux_Core_NAND_User%27s_Guide#Board_specific_configurations


    4. SPL(Secondary Program Loader)의 개념 및 비교

    Uboot에서 MLO , SPL 모르는 용어가 나와서 간단히 다시 Uboot를 대충 다시 분석하기로 했다.
    Uboot-SPL은 MLO와 동일한 존재이며, Uboot안에 제공해주는 작은부트로더이다.
    기존에 TI에서 제공된  UBL(User Boot Loader) 혹 X-Loader의 기능과 동일하며, 다른점은 Uboot 내에 소스가 포함이 되어 만들어지는 방법이 만들어진다.
    이는 오래전에 제공되어진 솔루션(UBL 과 X-Loader)과는 다른점이며, AM437x는 기본적으로 OMAP 플랫폼을 동작되고 있다.

    결론적으로 1st Boot Loader 이며,기능은 Uboot의 기능을 제한적사용가능

    • Boot 순서
    1. SOC(Rom Boot Loader)  :  SoC에 내장되어있으며, NAND의 1 Block을 읽어온다.
    2. SPL                            : 1 Block Size의 작은 Boot Loader이며, Uboot 호출
    3. Uboot                        : Size 문제로 SPL를 사용하여 Uboot를 3번째로 호출된다.

    • Open Uboot
         * SPL( Secondary Program Loader) : 작은 Uboot
         * TPL( Tertiary Program Loader)  : 보통 Uboot

      http://www.denx.de/wiki/pub/U-Boot/MiniSummitELCE2013/tpl-presentation.pdf

    • For Davinci series (UBL)
         * UBL 제공 및 사용 (RBL->UBL->UBOOT) BOOT
         * 부가기능- UART BOOT로 Window에서 Flashing 과 loading 기능제공

    1. DM644x Dvflasher (RBL -> UBL-> UBOOT) for Davinci series.
      http://processors.wiki.ti.com/index.php/RBL_UBL_and_host_program

    2. 기존 Davinci Series 와 OMAP-Lx Series 지원 (기능 동일)
      http://processors.wiki.ti.com/index.php/Serial_Boot_and_Flash_Loading_Utility

    • For OMAP series (X-Loader ->SPL)
         *초반에 X-Loader를 사용했으나, 이를 SPL 개념으로 변경
         *기본개념은 상동
      http://omappedia.org/wiki/Bootloader_Project
      http://processors.wiki.ti.com/index.php/Boot_Sequence
       
    • 참고사항 
        * 다른 CPU UBOOT SPL
      http://www.wiki.xilinx.com/U-Boot+Secondary+Program+Loader


    4.1 SPL 기본구조 

    기본 Makfile과 Makefile Config를 분석

     $ vi Makefile
    ...
    ALL-$(CONFIG_SPL) += spl/u-boot-spl.bin
    ALL-$(CONFIG_SPL_FRAMEWORK) += u-boot.img
    ......
    spl/u-boot-spl.bin: spl/u-boot-spl
            @:
    spl/u-boot-spl: tools prepare
            $(Q)$(MAKE) obj=spl -f $(srctree)/scripts/Makefile.spl all
    ...
    
    tpl/u-boot-tpl.bin: tools prepare
            $(Q)$(MAKE) obj=tpl -f $(srctree)/scripts/Makefile.spl all CONFIG_TPL_BUILD=y
    
    


    board config에서 SPL 설정하고 빌드를 진행하면, SPL dir이 새로 생성하게 되며,이 안에 작은 boot loader와 각각의 필요한 *.o, *.su, *.cmd 이 생성이 된다.

    .su 파일 과 .cmd 파일기록으로 분석해보면, 기존의 소스로 컴파일 or link해서 사용하는것 같다.

    $ cat spl/arch/arm/cpu/armv7/.cpu.o.cmd 
       source_spl/arch/arm/cpu/armv7/cpu.o := arch/arm/cpu/armv7/cpu.c
       xxxxx
    
    $ cat spl/arch/arm/cpu/armv7/cpu.su 
     cpu.c:25:13:cpu_cache_initialization    0       static
     cpu.c:27:5:cleanup_before_linux 8       static
    

    • SPL 설정  (DM8127-IPNC예제)
    dm8127-ipnc의 config 설정 각각의 설정에 따라, PROMPT를 SPL과 Uboot를 각각 변경하고 MINI Uboot인 SPL이 되어진다.
    SPL은 각각의 내부 COMMAND와 별도의 설정가능하며,SPL의 역할은 DDR 설정 및 초기화 기능

    $ vi ./include/configs/ti8148_ipnc.h 
    #ifdef CONFIG_TI814X_MIN_CONFIG
    ...
    # define CONFIG_CMD_LOADB       /* loadb                        */
    # define CONFIG_CMD_LOADY       /* loady */
    # define CONFIG_TI814X_CONFIG_DDR
    # define CONFIG_TI814X_EVM_DDR3
    # define CONFIG_SYS_PROMPT              "TI-MIN#"
    ....
    #else
    # include 
    # define CONFIG_SKIP_LOWLEVEL_INIT      /* 1st stage would have done the basic init */
    # define CONFIG_ENV_SIZE                        0x2000
    # define CONFIG_SYS_MALLOC_LEN          (CONFIG_ENV_SIZE + (32 * 1024))
    # define CONFIG_ENV_OVERWRITE
    # define CONFIG_SYS_PROMPT              "TI8148_IPNC#"
    
    # define CONFIG_MMC                     1
    # define CONFIG_NAND                    1
    
    #endif
    
    

    • U-BOOT 내의 Image 구성
    $ cd board-support/u-boot-2014.07-g7e537bf
    $ ls 
       MLO          : u-boot-spl.bin 의 최종 이미지      확인방법 cat .MLO.cmd  (동일한 존재)
       
       spl          : SPL 관련링크 및 Image 파일 
       
       u-boot.img   : U-BOOT bin 최종 파일               확인방법: cat .u-boot.img.cmd 
    
       xxx  (중략) 
    


    • su file 관련내용
    su file은 static stack의 사용량 분석하는 파일이니, 참고만 하면 되겠으며, 이 file로 최대 stack 사이즈를 알려고 하는 것 같다.

    su file 관련내용
      https://gcc.gnu.org/onlinedocs/gnat_ugn/Static-Stack-Usage-Analysis.html

    su file 생성 관련수정 (Makefile 연계)
      http://lists.denx.de/pipermail/u-boot/2014-February/172622.html

    • SPL 관련 문서 
    Uboot안에 SPL 관련문서를 제공
     ./doc/README.SPL


    4.2 SPL 사용방법 

    TI-UBOOT는 Makefile CONFIG를 두개로 따로 관리(자동생성)를 하여, 관리하지만, 만약, SPL 관련 수정을 한다면, boards.cfg를 봐야할 것 같다.

    Makefile은 (mkconfig 실행 와 boards.cfg 참조) Board Config들을 보려면 아래사항을 확인 해야할 것 같다.

    • Board Configuration 
    ./include/configs/am43xx_evm.h
    ./include/configs/ti_armv7_common.h //SPL 관련 설정
    // 위 Config 파일을 보면 각각 설정이 가능함.
    
    
    //USB BOOT Mode일 경우 변경
              #define CONFIG_SPL_TEXT_BASE   0x402F4000     // SRAM 위치 , Link Sript 참조.
              #define CONFIG_SPL_MAX_SIZE             (220 << 10)     /* 220KB */
              #define CONFIG_SYS_SPL_ARGS_ADDR        (CONFIG_SYS_SDRAM_BASE + \
                                             (128 << 20))
    
              #define CONFIG_SPL_BOARD_INIT
              #define CONFIG_SPL_POWER_SUPPORT
              #define CONFIG_SPL_YMODEM_SUPPORT
    


    • Makefile의 CONFIG 파일 구성
    ./include/autoconf.mk       // CONFIG_SPL=y 선언
    ./include/spl-autoconf.mk  // CONFIG_SPL_BUILD=y 선언
    

    • SPL 빌드과정
    1. U-BOOT의 CONFIG .config에 CONFIG_SPL=y 설정 할 경우  
    2. Makefile 안의  spl/u-boot-spl 에서 Makefile.spl이 spl-autoconf.mk 생성
    3. SPL은 이 부분을 참조하여 빌드를 한다. 

     *CONFIG_SPL_BUILD=y //SPL 관련 Makefile CONFIG 이부분은 SPL문서 참조.

    4.3 SPL 관련파일 

    SPL 관련자료는 board config에서  *CONFIG_SPL_BUILD=y 사용하겠다고 명시를 하면, 아래와 같이 기본기능과 각 BOOT MODE 맞게 생성이 되는 것 같다.
    BSP 혹은 uboot version에 따라  조금씩 다른것 같다.

    • SPL의 기본소스 
    SPL의 기본소스는 존재하지만, U-BOOT와 공통되느는 부분은 동일하게 외부에서 가져다 쓰기에 이곳에 존재하지 않는다.

    common/spl/

     $ vi common/spl/Makefile 
      11 ifdef CONFIG_SPL_BUILD
      12 obj-$(CONFIG_SPL_FRAMEWORK) += spl.o
      13 obj-$(CONFIG_SPL_NOR_SUPPORT) += spl_nor.o
      14 obj-$(CONFIG_SPL_YMODEM_SUPPORT) += spl_ymodem.o
      15 obj-$(CONFIG_SPL_NAND_SUPPORT) += spl_nand.o
      16 obj-$(CONFIG_SPL_ONENAND_SUPPORT) += spl_onenand.o
      17 obj-$(CONFIG_SPL_NET_SUPPORT) += spl_net.o
      18 obj-$(CONFIG_SPL_MMC_SUPPORT) += spl_mmc.o
      19 obj-$(CONFIG_SPL_USB_SUPPORT) += spl_usb.o
      20 obj-$(CONFIG_SPL_FAT_SUPPORT) += spl_fat.o
      21 obj-$(CONFIG_SPL_EXT_SUPPORT) += spl_ext.o
      22 obj-$(CONFIG_SPL_SATA_SUPPORT) += spl_sata.o
      23 endif
    


    빌드 후에는 uboot/spl 에 모든 파일이 생성.

    • U-BOOT 설정
    기본적으로, make board_config를 한 후에 가능

    $ vi .config        // U-BOOT EVM CONFIG 설정  
    $ vi ./u-boot.cfg   // U-BOOT Build 된 후 아래 CONFIG와 관련 CONFIG 전부  
    
    $ vi ./spl/include/autoconf.mk  // U-BOOT-SPL, MLO의 설정 확인 
    $ vi ./spl/u-boot-spl.cfg       // Build 된 후 CONFIG 포함 
    

    • U-BOOT SPL 설정 
    $ vi ./spl/include/autoconf.mk  // U-BOOT-SPL, MLO의 설정 확인 
    $ vi ./spl/u-boot-spl.cfg       // Build 된 후 CONFIG 포함 
    


    4.4 TI-SPL을 적용한 BOOT MODE 
    AM437X는 다양한 BOOT MODE를 제공하지만, 일단 기본적인 BOOT인 MMC와 NAND 보겠다.

    • 자주사용할 Boot Mode 
    1. MMC BOOT   (SD Card)
    2. NAND BOOT

    • 기본 부팅순서 
    1. ROM Bootloader, (IPL, Initial Program Loader or (PPL, the Primary Program Loader) 
    2. The binary for the (SPL, Secondary Program Loader) or the MLO.
    3. The binary for U-Boot (TBL, Tertiary Program Loader)

    NAND일 경우, PPL이 NAND 1st ~ 4th block 몇개를 SPL 찾기위해 검색을 Bad Block 생각해서, 그리고, SPL 진행하고 초기화

    MMC와 USB일 경우, PPL이 FAT를 Mount하는 기능이 추가되어, SPL 파일을 찾아,SPL(MLO)를 진행하고 초기화

    부팅관련용어 및 내용
      http://elinux.org/Boot_U-Boot_from_UBI_volume


    5. Boot Mode 기본분석 및 Memory Map 

    • NAND BOOT 구조 
    NAND BOOT일 경우, 아래와 같은 구조로 구성이 될 것 같다.
    아래는 AM33xx 인 경우 NAND 구조이며, SPL과 U-Boot.img Kernel 위치를 알수 있다.


    +------------+-->0x00000000-> SPL start         (SPL copy on 1st block)
    |            |
    |            |-->0x0001FFFF-> SPL end 
    |            |-->0x00020000-> SPL.backup1 start (SPL copy on 2nd block)
    |            |
    |            |-->0x0003FFFF-> SPL.backup1 end 
    |            |-->0x00040000-> SPL.backup2 start (SPL copy on 3rd block)
    |            |
    |            |-->0x0005FFFF-> SPL.backup2 end 
    |            |-->0x00060000-> SPL.backup3 start (SPL copy on 4th block)
    |            |
    |            |-->0x0007FFFF-> SPL.backup3 end
    |            |-->0x00080000-> U-Boot start
    |            |                                    
    |            |-->0x002BFFFF-> U-Boot end 
    |            |-->0x00260000-> ENV start
    |            |
    |            |
    |            |-->0x0027FFFF-> ENV end
    |            |-->0x00280000-> Linux Kernel start
    |            |
    |            |
    |            |
    |            |
    |            |-->0x0077FFFF-> Linux Kernel end
    |            |-->0x00780000-> File system start
    |            |
    |            |
    |            |
    |            |
    |            |
    |            |
    |            |
    |            |
    |            |
    |            |
    |            |
    |            |
    +------------+-->0x10000000-> NAND end (Free end)
    

      http://processors.wiki.ti.com/index.php/AM335x_U-Boot_User's_Guide

    • MMC와 eMMC 와 USB BOOT MODE일 경우 구조 
        Partition-1:  FAT32:   MLO(SPL) 와 u-boot.img
        Partition-2:  EXT3:  Linux File system
        (* fdisk로 각 파티션을 만들고, 분할)

    • Linker Script 확인
    SPL때문에 Link Script을 다시 확인하게 되었지만, 기본 Link Script가 에서 다시 설정이 되어, spl directory에 최종결과물이 생성이 된다.

    • 기본 확인방법 (Board Config)
    $ vi include/configs/am43xx_evm.h 
    ...
    #define CONFIG_SPL_LDSCRIPT  "$(CPUDIR)/omap-common/u-boot-spl.lds"
    ...
    $ cat arch/arm/cpu/armv7/omap-common/u-boot-spl.lds //linker script 확인
    
       
      https://sourceware.org/binutils/docs-2.25/ld/index.html
      http://www.math.utah.edu/docs/info/ld_3.html

    5.1 AM335x 관련정보

    • AM335x AM335x EVM-SK Info 
      http://processors.wiki.ti.com/index.php/AM335x_Starter_Kit
      http://processors.wiki.ti.com/index.php/AM335x_Starter_Kit#Hardware_Documentation

    • AM335x EVM-SK 진단용
      추후 QC Program응용가능
      http://processors.wiki.ti.com/index.php/AM335x_Starter_Kit_Diagnostics

    • AM335x Battery Pack
      http://processors.wiki.ti.com/index.php/AM335x_Starter_Kit_Battery_Pack

    • AM335x EVM-SK JTAG (XDS-100 V2) 설정 
    현재 이 EVM JTAG Header가 없다고해서 사용못한다고 한다. 설정방법
      http://processors.wiki.ti.com/index.php/Starter_kit_jtag

    • AM335x SD Boot 일 경우 참고사항
      http://processors.wiki.ti.com/index.php/Linux_Core_U-Boot_User's_Guide#Partitioning_eMMC_from_U-Boot

    현재 SD Boot할 경우, Sandisk 16GB Class10 인 경우 제대로 동작이 안되지만, 기본적으로 ICS 4.0.3 포함한 SD Disk는 잘동작한다.
    원인은 MLO에서 MMC를 정확히 인식을 못하는 것 같다.
      http://processors.wiki.ti.com/index.php/TI-Android-ICS-4.0.3-DevKit-3.0.1_UserGuide#SD_Card_Recommendations


    U-Boot SPL 2016.05 (Feb 20 2017 - 16:27:15)
    Trying to boot from MMC1
    ** First descriptor is NOT a primary desc on 0:1 **
    ** Partition 1 not valid on device 0 **
    spl_register_fat_device: fat register err - -1
    ** Partition 1 not valid on device 0 **
    spl_register_fat_device: fat register err - -1
    spl_load_image_fat: error reading image u-boot.img, err - -1
    spl: no partition table found
    spl: no partition table found
    SPL: failed to boot from all boot devices
    ### ERROR ### Please RESET the board ###
    

      https://en.wikipedia.org/wiki/Secure_Digital#Micro