-boot Guide|작성자 bocholt
asm-avr32, asm-blackfin, asm-i386, asm-m68k, asm-microblaze,
asm-mips, asm-nios, asm-nios2, asm-ppc, asm-sh, asm-sparc 파일 삭제
lib_avr32, lib_blackfin, lib_i386, lib_m68k, lib_microblaze,
lib_mips, lib_nios, lib_nios2, lib_ppc, lib_sh, lib_sparc 파일 삭제
yhoh@CRZ-PC1:~/u-boot/uboot-1.3.4-feelpass/board$ cp -a samsung/smdk6410/ mango64 yhoh@CRZ-PC1:~/u-boot/uboot-1.3.4-feelpass/board$ ls mango64 samsung |
yhoh@CRZ-PC1:~/u-boot/uboot-1.3.4-feelpass/board/mango64$ mv smdk6410.c mango64.c yhoh@CRZ-PC1:~/u-boot/uboot-1.3.4-feelpass/board/mango64$ mv smdk6410_val.h mango64_val.h |
#ifndef _VAL_MANGO64_H #define _VAL_MANGO64_H |
Makefile (Z:\u-boot\uboot-1.3.4-pooh04\board\mango64)
OBJS := mango64.o flash.o SOBJS := lowlevel_init.o |
.text : { cpu/s3c64xx/start.o (.text) cpu/s3c64xx/start_irom.o (.text) cpu/s3c64xx/s3c6410/cpu_init.o (.text) board/mango64/lowlevel_init.o (.text) cpu/s3c64xx/onenand_cp.o (.text) cpu/s3c64xx/nand_cp.o (.text) cpu/s3c64xx/movi.o (.text) *(.text) lib_arm/div0.o } |
#include "mango64_val.h" |
yhoh@CRZ-PC1:~/u-boot/uboot-1.3.4-feelpass/include/configs$ cp smdk6410.h mango64.h yhoh@CRZ-PC1:~/u-boot/uboot-1.3.4-feelpass/include/configs$ ls mango64.h smdk6410.h |
/* samsung socs: auto-detect devices */ #if defined(CONFIG_SMDK6410) || defined(CONFIG_SMDK6430) || defined(CONFIG_SMDKC100) || defined(CONFIG_MANGO64) |
mango64.h (Z:\u-boot\uboot-1.3.4-feelpass\include\configs)
#define CONFIG_MANGO64 1 /* on a MANGO64 Board */ |
위와 같이 mango64.h에 변경해 놓습니다..
hs_mmc.c (Z:\u-boot\uboot-1.3.4-feelpass\cpu\s3c64xx)
#if defined(CONFIG_SMDK6400) || defined(CONFIG_SMDK6410) || defined(CONFIG_SMDK6430) || defined(CONFIG_MANGO64) |
hs_mmc.c 라인 번호 3 부분에도 CONFIG_MANGO64 정의를 포함해 놓습니다.
Makefile (Z:\u-boot\uboot-1.3.4-feelpass)
mango64_config : unconfig @$(MKCONFIG) $(@:_config=) arm s3c64xx mango64 NULL s3c6410 |
가장 상위 폴더에 존재하는 Makefile에 위의 내용을 포함시킵니다. 이것은 smdk6410_config를 복사해서 적절히 수정한 것에 지나지 않음.
smdk6410_config : unconfig @$(MKCONFIG) $(@:_config=) arm s3c64xx smdk6410 samsung s3c6410 |
위 내용이 원래 들어있는 smdk6410_config 내용이다. 이 내용은 삭제된 것이 아니라 그대로 내용에 포함되어 있습니다. 다만 한가지 다른 부분이 있는데 MKCONFIG에 전달되는 파라미터 중에서 smdk6410으로 보드 이름이 적히던 부분이 mango64로 변해 있고, 바로 다음의 samsung이라고 되어 있는 부분이 NULL로 변화되어 있습니다.
board/samsung/smdk6410을 복사해서 board/mango64로 만들었는데 여기서 samsung이라는 이름이 바로 Vendor 이름입니다. 만약 Vendor 이름이 있을 경우는 위의 경우처럼 board 폴더에 바로 그 Vendor 이름이 폴더로 존재하게 됩니다. mango64는 board 폴더의 바로 밑에 있기 때문에 이 Vendor 이름이 NULL로 존재해야 합니다.
MKCONFIG := $(SRCTREE)/mkconfig |
MKCONFIG는 위와 같이 mkconfig로 정의되어 있고 mkconfig를 찾아보면 아래의 내용을 발견할 수 있습니다.
mkconfig (Z:\u-boot\uboot-1.3.4-feelpass)
echo "ARCH = $2" > config.mk echo "CPU = $3" >> config.mk echo "BOARD = $4" >> config.mk [ "$5" ] && [ "$5" != "NULL" ] && echo "VENDOR = $5" >> config.mk |
config.mk (Z:\u-boot\uboot-1.3.4-feelpass)
ifdef VENDOR BOARDDIR = $(VENDOR)/$(BOARD) else BOARDDIR = $(BOARD) endif |
결국 Vendor에 대한 정의를 하는지 그렇지 않은지에 따라서 Board Directory 이름이 변경되고 있음을 알수 있습니다. 우리는 Vendor를 Null로 해서 이름을 만들지 않으려고 하는 것입니다..
Makefile (Z:\u-boot\uboot-1.3.4-feelpass\drivers\mtd\onenand)
ifeq ($(BOARD),smdk6400) COBJS += s3c_onenand.o else ifeq ($(BOARD),smdk6410) COBJS += s3c_onenand.o else ifeq ($(BOARD),mango64) COBJS += s3c_onenand.o else ifeq ($(BOARD),smdk6430) COBJS += s3c_onenand.o else ifeq ($(BOARD),smdkc100) COBJS += s3c_onenand.o else COBJS += onenand_base.o onenand_bbt.o endif |
위와 같이 mango64와 관련해서도 추가를 해주어야 합니다. 실제로는 One NAND를 사용하지 않기 때문에 필요 없는 부분이기는 하지만 대부분에 대해서 smdk6410 것을 아직은 그저 복사한 수준이기 때문에 이 부분이 포함되지 않으면 컴파일 시에 에러가 발생하게 됩니다.
mango64.c (Z:\u-boot\uboot-1.3.4-feelpass\board\mango64)
int checkboard(void) { printf("Board: MANGO64\n"); return (0); } |
mango64.h (Z:\u-boot\uboot-1.3.4-feelpass\include\configs)
#define CFG_PROMPT "MANGO64 # " /* Monitor Command Prompt */
#define CONFIG_IDENT_STRING " for MANGO64" |
위에서 변한 부분은 단순히 출력에 대한 부분을 Mango64로 변경한 것입니다.
yhoh@CRZ-PC1:~/u-boot/uboot-1.3.4-feelpass$ make mango64_config Configuring for mango64 board... yhoh@CRZ-PC1:~/u-boot/uboot-1.3.4-feelpass$ make Generating include/autoconf.mk.dep ..... ..... ..... ..... ..... ..... /home/yhoh/wk/poohdroid/prebuilt/linux-x86/toolchain/arm-eabi-4.3.1/bin/arm-eabi-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin yhoh@CRZ-PC1:~/u-boot/uboot-1.3.4-feelpass$ |
uboot-1.3.4-pooh05\include\configs\mango64.h
//#define CONFIG_ENABLE_MMU #ifdef CONFIG_ENABLE_MMU #define virt_to_phys(x) virt_to_phy_smdk6410(x) #else #define virt_to_phys(x) (x) #endif |
일단 U-Boot 상에서는 MMU를 사용하지 않도록 설정합니다.
MMU를 사용하지 않기 때문에 Virtual Address를 Physical Address로 변환할 때
특별한 작업을 수행할 필요가 없게 됩니다.
\cpu\s3c64xx\Makefile
ifeq ($(BOARD),smdk6400) START += start_6400.o else ifeq ($(BOARD),mango64) START += start_6400.o else START += start_irom.o endif |
현재는 IROM booting을 사용하고 있지 않기 때문에 start_6400.S를 이용하게 됩니다.
uboot-1.3.4-pooh05/cpu/s3c64xx를 살펴보면 위 내용을 발견할 수 있습니다.
이들 파일들이 보드의 초기 수행 시점에서 매우 중요한 역할을 하는 부분들입니다.
uboot-1.3.4-pooh05\board\mango64\config.mk
ifndef TEXT_BASE TEXT_BASE = 0x57e00000 endif |
기존에 사용하던 u-boot binary에서 Text 주소값으로 매우 익숙한 값이 이곳에 설정되고 있습니다.
이 값이 원래는 TEXT_BASE = 0xc7e00000로 되어 있었습니다.
이 주소는 맞지 않기 때문에 0x57e00000으로 변경합니다.
uboot-1.3.4-pooh05\board\mango64\u-boot.lds
.text : { cpu/s3c64xx/start.o (.text) cpu/s3c64xx/start_6400.o (.text) cpu/s3c64xx/s3c6410/cpu_init.o (.text) board/mango64/lowlevel_init.o (.text) cpu/s3c64xx/onenand_cp.o (.text) cpu/s3c64xx/nand_cp.o (.text) cpu/s3c64xx/movi.o (.text) *(.text) lib_arm/div0.o } |
u-boot.lds Scatter Loader 부분을 또 변경해 주어야 하는 부분이 있습니다.
원래 cpu/s3c64xx/start_irom.o (.text)로 되어 있는 부분을
cpu/s3c64xx/start_6400.o (.text)로 변경해야 합니다.
uboot-1.3.4-pooh05\cpu\s3c64xx\start.S
#if !defined(CONFIG_S3C6400) && !defined(CONFIG_MANGO64) moveq r3, #0xf /* r0 == r1 then skip flash copy */ bl load_bl2_irom #else beq after_copy bl load_bl2_6400 #endif |
load_bl2_irom 대신에 load_bl2_6400가 실행될 수 있도록
!defined(CONFIG_MANGO64)를 start.S에 추가합니다.
일단 현재까지의 상태에서 빌드를 해서 다운로드를 해보았습니다.
다운로드는 문제없이 동작하였고, Checksum까지 통과했는데
아무 것도 출력이 이루어지지 않고 있습니다.
뭔가 Serial 쪽에 변경이 필요한 것이 아닐까 하는 생각을 해봅니다.
디버그 포트로 사용하는 부분의 회로도를 잠시 보도록 하겠습니다.
위와 같이 UART1_TXD를 사용하고 있는 것을 알수 있고,
UART1_xxx가 GPA4, 5, 6, 7에 할당된 것을 알수 있습니다.
UART1_xxx는 XuXXX[1] 부분임을 알수 있습니다.
GPA4, 5, 6, 7이 UART1을 가리키는 부분입니다.
여기서 실제 소스 부분을 살펴보도록 하겠습니다.
s3c6410.h (include)
#ifdef CONFIG_SERIAL1 #define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART0_OFFSET) #elif defined(CONFIG_SERIAL2) #define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART1_OFFSET) #elif defined(CONFIG_SERIAL3) #define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART2_OFFSET) #elif defined(CONFIG_SERIAL4) #define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART3_OFFSET) #else #define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART0_OFFSET) #endif |
위와 같이 s3c6410.h 부분을 보면 UART0는 CONFIG_SERIAL1이고,
UART1은 CONFIG_SERIAL2 임을 알수 있습니다.
mango64.h (include\configs)
#define CONFIG_SERIAL2 1 /* mango64 use UART1 (SERIAL 2) */ |
망고 64는 UART1을 사용하기 때문에 CONFIG_SERIAL2를 define해주어야 합니다.
위와 같이 CONFIG_SERIAL2를 1로 설정해주도록 변경했습니다.
Checksum O.K. H?
U-Boot 1.3.4 (Jan 15 2010 - 12:12:17) for MANGO64 CPU: S3C6410@532MHz Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode) Board: MANGO64 DRAM: 128 MB Flash: 0 kB SD/MMC: 0 MB NAND: 0 MB |
이제 다시 빌드해서 다운로드 후 실행해 보면 위와 같이 출력이 나오고 있습니다.
그렇지만 아직도 정상적으로 작동하고 있지는 않습니다.
릴리즈 된 Mango64-u-boot-1.1.6-V01-000.bin을 사용해서 출력되는 것과 비교해 보도록 합니다.
Checksum O.K. H?
U-Boot 1.1.6 (Nov 11 2009 - 23:12:28) for SMDK6410 CPU: S3C6410@532MHz Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode) Board: SMDK6410 DRAM: 128 MB Flash: 0 kB NAND: 256 MB *** Warning - bad CRC or NAND, using default environment In: serial Out: serial Err: serial Hit any key to stop autoboot: 0 mango6410 # |
이렇게 비교를 하면 힘드니까 강제적으로 비교 툴을 사용해 보겠습니다.
버전이나 출력되는 것이 다른 것을 제외하면 NAND 부분이 좀 다르네요.
클럭은 동일하게 설정되어 있는 것으로 보입니다.
다음 변경된 사항은 아래와 같습니다.
uboot-1.3.4-pooh07\common\Makefile
ifeq ($(CPU),s3c24xx) COBJS += env_nand.o env_movi.o env_onenand.o else ifeq ($(BOARD),mango64) COBJS += env_nand.o else ifeq ($(BOARD),smdk6400) COBJS += env_nand.o env_movi.o env_onenand.o else COBJS += env_auto.o endif endif |
common의 Makefile을 위와 같이 수정했습니다.
일단 One NAND나 Movi NAND의 경우는 제외하고
mango64에서는 env_nand만 포함되도록 추가하였습니다.
lowlevel_init.S (board\mango64)
lowlevel_init: ..... ..... ..... ..... ..... ..... /* for UART */ bl uart_asm_init #if defined(CONFIG_NAND) /* Nand Initialization */ /* simple init for NAND */ bl nand_asm_init #endif |
board\mango64의 lowlevel_init.S에서 lowlevel_init에서 진행하는 과정 중에
uart_asm_init 바로 다음에 NAND를 초기화 해주는 부분을 삽입합니다.
nand_asm_init을 호출하고 있습니다.
uboot-1.3.4-pooh07\include\configs\mango64.h
..... ..... ..... ..... ..... ..... #define CFG_ONENAND_BASE (0x70100000) #define CFG_MAX_ONENAND_DEVICE 1 #define CONFIG_BOOT_NAND #define CONFIG_NAND #define CFG_ENV_IS_IN_NAND //#define CFG_ENV_IS_IN_AUTO #endif /* __CONFIG_H */ |
우리는 향후 U-Boot를 NAND에 저장한 이후에 NAND에서 부팅을 할 수 있도록 만들 것입니다.
위에서 살펴본 config를 이곳에서 정의하고 있는 것입니다.
CONFIG_BOOT_NAND, CONFIG_NAND, CFG_ENV_IS_IN_NAND를 각각 정의합니다.
ENV 관련한 사항은 환경 변수들로서 이것 또한 NAND에 저장할 것입니다.
원래 정의되어 있던 CFG_ENV_IS_IN_AUTO 부분은 삭제합니다.
자동으로 저장될 곳을 찾아서 저장하는 것인데 우리는 NAND에 저장할 것이기 때문에
기본적으로 CFG_ENV_IS_IN_NAND를 정의하고 AUTO는 삭제합니다.
이렇게 변경된 내용을 빌드해서 보드에서 수행시켜 보도록 하겠습니다.
U-Boot 1.3.4 (Jan 18 2010 - 15:22:49) for MANGO64 CPU: S3C6410@532MHz Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode) Board: MANGO64 DRAM: 128 MB Flash: 0 kB SD/MMC: 0 MB NAND: 256 MB
s3c-nand: ECC uncorrectable error detected s3c-nand: 1 bit error detected at byte 194, correcting from 0xcd to 0x8d...OK s3c-nand: 1 bit error detected at byte 507, correcting from 0xe5 to 0xe1...OK ..... ..... ..... ..... ..... ..... s3c-nand: ECC uncorrectable error detected s3c-nand: 1 bit error detected at byte 123, correcting from 0x0a to 0x8a...OK
*** Warning - bad CRC or NAND, using default environment *** Error - default environment is too large In: serial Out: serial Err: serial Net: No ethernet found
MANGO64 # |
드디어 MANGO64 # 프롬프트가 보입니다. ^)^
이제 여러가지 명령들을 수행할 수 있는 단계가 된 것입니다.
초기에 출력하고 있는 메세지들을 살펴보면
NAND: 256 MB
이전까지는 출력하지 못하던 NAND 크기가 출력되고 있습니다.
이후에 ECC 관련해서 매우 긴 내용이 출력되었습니다.
*** Error - default environment is too large Net: No ethernet found |
위 2개의 문장이 처리되어야 할 부분으로 보입니다.
환경 변수들에 대한 저장 부분을 위치나 크기 등의 사항에 대해 변경이 필요해 보이고
Ethernet과 관련해서도 적절한 설정이 필요해 보입니다.
환경 변수의 크기와 관련한 부분만 수정해 보겠습니다.
*** Error - default environment is too large |
uboot-1.3.4-pooh07에서 위의 에러 메세지가 출력되었습니다.
이 부분을 찾아보면 아래 부분입니다.
void set_default_env(void) { if (sizeof(default_environment) > ENV_SIZE) { puts ("*** Error - default environment is too large\n\n"); printf("sizeof(default_environment): %d\n", sizeof(default_environment)); printf("CFG_ENV_SIZE: %d, ENV_SIZE: %d\n", CFG_ENV_SIZE, ENV_SIZE); return; } ..... ..... ..... ..... ..... ..... |
위와 같이 2개의 printf를 추가해서 실제 에러가 발생한 크기를 측정해 보았습니다.
sizeof(default_environment): 16384 CFG_ENV_SIZE: 16384, ENV_SIZE: 16380 |
ENV_SIZE는 environment.h (include)에 아래와 같이 정의되어 있습니다.
#ifdef CFG_REDUNDAND_ENVIRONMENT # define ENV_HEADER_SIZE (sizeof(uint32_t) + 1) #else # define ENV_HEADER_SIZE (sizeof(uint32_t)) #endif #define ENV_SIZE (CFG_ENV_SIZE - ENV_HEADER_SIZE) |
ENV_HEADER_SIZE는 CFG_REDUNDAND_ENVIRONMENT가 정의되어 있지 않기 때문에
sizeof(uint32_t)로 정의될 것이고, 4 값을 가질 것입니다.
CFG_ENV_SIZE에서 4를 뺀 값을 ENV_SIZE로 갖고 있을 것입니다.
env_common.c (common)
#if defined(CONFIG_S3C6410) || defined(CONFIG_S3C6430) || defined(CONFIG_S5PC100) uchar default_environment[CFG_ENV_SIZE] = { #else uchar default_environment[] = { #endif |
default_environment가 CFG_ENV_SIZE 크기의 배열로 잡혀 있기 때문에
이것의 크기를 sizeof 연산을 하게 되면 16384가 됩니다.
결국 늘 크기가 맞지 않을 수 밖에 없는 것입니다.
위 코드를 아래와 같이 수정하도록 하겠습니다.
#if defined(CONFIG_MANGO64) uchar default_environment[] = { #elif defined(CONFIG_S3C6410) || defined(CONFIG_S3C6430) || defined(CONFIG_S5PC100) uchar default_environment[CFG_ENV_SIZE] = { #else uchar default_environment[] = { #endif |
크기를 지정하지 않고 일단 현재 정의된 것의 크기만 가질 수 있도록 변경했습니다.
sizeof(default_environment): 171 |
변경 후에 수행시켜보면
현재의 default_environment에 저장되는 것은 고작 171 바이트 밖에는 안되네요.
uboot-1.3.4-pooh09
board.c (lib_arm)
void start_armboot (void) { ..... ..... ..... ..... ..... ..... /* samsung socs: auto-detect devices */ #if defined(CONFIG_SMDK6410) || defined(CONFIG_SMDK6430) || defined(CONFIG_SMDKC100) ..... ..... ..... ..... ..... ..... /* samsung socs: no auto-detect devices */ #elif defined(CONFIG_SMDK6400) || defined(CONFIG_SMDK2450) || defined(CONFIG_SMDK2416) || defined(CONFIG_MANGO64) ..... ..... ..... ..... ..... ..... |
lib_arm의 board.c를 보면 start_armboot() 함수가 있고
여기에서 두 부분으로 나누어서 초기화를 진행하고 있습니다.
우리는 auto-detect로 동작하도록 하는 것이 아니기 때문에
기존에 CONFIG_SMDK6410 부분에 OR로 포함시켰던 CONFIG_MANGO64를
no auto-detect 부분으로 설정을 변경하였습니다.
이제 Ethernet 부분을 설정하도록 하겠습니다.
망고 64 회로도를 보면 Ethernet이 EBI CSN4로 설정되어 있는 것을 알수 있습니다.
/* mango64 use SROM bank 4 for Ethernet */ #define CS8900_SROM_BANK_4
static void cs8900_pre_init(void) { #if defined(CS8900_SROM_BANK_1) SROM_BW_REG &= ~(0xf << 4); SROM_BW_REG |= (1<<7) | (1<<6) | (1<<4); SROM_BC1_REG = ((CS8900_Tacs<<28)+(CS8900_Tcos<<24)+(CS8900_Tacc<<16)+(CS8900_Tcoh<<12)+(CS8900_Tah<<8)+(CS8900_Tacp<<4)+(CS8900_PMC)); #elif defined(CS8900_SROM_BANK_2) SROM_BW_REG &= ~(0xf << 8); SROM_BW_REG |= (1<<11) | (1<<10) | (1<<8); SROM_BC2_REG = ((CS8900_Tacs<<28)+(CS8900_Tcos<<24)+(CS8900_Tacc<<16)+(CS8900_Tcoh<<12)+(CS8900_Tah<<8)+(CS8900_Tacp<<4)+(CS8900_PMC)); #elif defined(CS8900_SROM_BANK_3) SROM_BW_REG &= ~(0xf << 12); SROM_BW_REG |= (1<<15) | (1<<14) | (1<<12); SROM_BC3_REG = ((CS8900_Tacs<<28)+(CS8900_Tcos<<24)+(CS8900_Tacc<<16)+(CS8900_Tcoh<<12)+(CS8900_Tah<<8)+(CS8900_Tacp<<4)+(CS8900_PMC)); #elif defined(CS8900_SROM_BANK_4) SROM_BW_REG &= ~(0xf << 16); SROM_BW_REG |= (1<<19) | (1<<18) | (1<<16); SROM_BC4_REG = ((CS8900_Tacs<<28)+(CS8900_Tcos<<24)+(CS8900_Tacc<<16)+(CS8900_Tcoh<<12)+(CS8900_Tah<<8)+(CS8900_Tacp<<4)+(CS8900_PMC)); #elif defined(CS8900_SROM_BANK_5) SROM_BW_REG &= ~(0xf << 20); SROM_BW_REG |= (1<<23) | (1<<22) | (1<<20); SROM_BC5_REG = ((CS8900_Tacs<<28)+(CS8900_Tcos<<24)+(CS8900_Tacc<<16)+(CS8900_Tcoh<<12)+(CS8900_Tah<<8)+(CS8900_Tacp<<4)+(CS8900_PMC)); #endif } |
cs8900_pre_init() 부분에서 이것을 설정하는 부분을 찾을 수 있습니다.
두 개의 레지스터를 설정해야 합니다.
SROM_BW_REG는 SROM BUS WIDTH & WAIT CONTRL REGISTER(SROM_BW)이고
SROM_BCx_REG는 SROM bank 0부터 5까지의 6개에 대해서 각각 다른 레지스터 입니다.
현재 망고 64에는 SMSC LAN9220이 탑재되어 있습니다.
SMDK6410에는 CS8900이 탑재되어 있습니다.
함수 이름이 cs8900_으로 시작하는 것은 이것을 기반으로 했기 때문입니다.
mango64.h (include\configs)
//#define CONFIG_NET_MULTI // MANGO64 |
만약 CONFIG_NET_MULTI가 정의되어 있을 경우에는
CS8900과 SMSC LAN9220을 동시에 사용하게 됩니다.
망고 64는 SMSC LAN9220 만을 사용하기 때문에 CONFIG_NET_MULTI는 정의하지 않습니다.
#define CONFIG_DRIVER_SMC911X 1 // MANGO64 |
위와 같이 CONFIG_DRIVER_SMC911X를 1로 정의하고 있습니다.
실제로 망고64에서 사용하는 것은 SMC9220이지만
대부분의 코드가 911X로 정의된 값을 이용하고 있습니다.
#define CONFIG_DRIVER_SMC911X_BASE 0x30000000 // Mango64 |
기존 코드에서는 #define CONFIG_DRIVER_SMC911X_BASE 0x18800300으로 정의되어 있는데
이 부분은 SROM Bank 1을 사용하던 것입니다.
망고64에서는 SROM Bank 4를 사용하기 때문에
base 주소는 0x3000000 번지 입니다.
기존 코드에서 300으로 base 주소가 되어 있는데
이것은 CS8900의 잔재로서 LAN9220에서는 필요가 없습니다.
이제 uboot-1.3.4-pooh09를 빌드해서 수행해 보도록 합니다.
MANGO64 # setenv ipaddr 192.168.11.110 MANGO64 # setenv serverip 192.168.11.120 MANGO64 # setenv gatewayip 192.168.11.1 MANGO64 # ping 192.168.11.120 smc911x: initializing smc911x: detected LAN9220 controller smc911x: phy initialized smc911x: MAC 00:40:5c:26:0a:5b host 192.168.11.120 is alive MANGO64 # |
위와 같이 IP 설정을 수행하고 정상적으로 ping도 수행되는 것을 확인할 수 있었습니다.
MANGO64 # save Saving Environment to NAND... Erasing Nand... Skipping bad block at 0x0007c000 Writing to Nand... amount_saved: 0 FAILED! MANGO64 # |
save를 수행해 보았는데 뭔가 문제가 있습니다.
이 부분은 다음 시간에 하도록 하겠습니다.
달라진 부분은 오직 mango64.h뿐입니다.
#define CONFIG_BOOTARGS "rootfstype=jffs2 root=/dev/mtdblock2 init=/init console=ttySAC1,115200" #define CONFIG_ETHADDR 00:40:5c:26:0a:5b #define CONFIG_NETMASK 255.255.255.0 #define CONFIG_IPADDR 192.168.11.110 #define CONFIG_SERVERIP 192.168.11.120 #define CONFIG_GATEWAYIP 192.168.11.1 |
나중을 대비해서 각종 설정 부분을 제가 사용하는 것으로 변경했습니다.
CONFIG_BOOTARGS, CONFIG_IPADDR, CONFIG_SERVERIP, CONFIG_GATEWAYIP를 변경합니다.
/* 0x40000 - 0x4000 = 0x3C000 */ #define CFG_ENV_OFFSET 0x0003C000 #define CFG_NAND_LARGEPAGE_SAVEENV |
NAND의 영역은 아래의 그림과 같이 나뉠 예정입니다.
환경 데이타의 크기는 CFG_ENV_SIZE에서 0x4000으로 정의되어 있습니다.
이 부분을 U-Boot 영역으로 잡아놓은 공간의 가장 뒷 부분에 저장할 것입니다.
이를 위해서 환경 변수가 저장될 위치를 0x3C000으로 설정해야 합니다.
이 경우 16 kbytes의 공간을 저장하는 것이기 때문에
CFG_NAND_LARGEPAGE_SAVEENV를 설정해서
여러 page에 걸쳐서 저장이 일어날 수 있도록 설정해야 합니다.
우리가 사용하는 NAND의 경우 하나의 페이지 크기는 2kbytes 입니다.
//#define CONFIG_MMC // MANGO64 #define CONFIG_MTDPARTITION "40000 400000 4000000" |
MMC의 경우는 U-boot에서는 현재 사용하지 않기 때문에 막아 두었습니다.
CONFIG_MTDPARTITION은 위 그림에서와 같이 주소를 할당해 두었습니다.
#define CONFIG_BOOTCOMMAND "nand read 50008000 40000 200000;bootm 50008000" |
나중에 U-boot가 Kernel을 로딩할때 위의 방법으로 할수 있도록 미리 설정을 해두었습니다.
이제 빌드를 해서 실행해 보도록 하겠습니다.
MANGO64 # print bootargs=rootfstype=jffs2 root=/dev/mtdblock2 init=/init console=ttySAC1,115200 bootcmd=nand read 50008000 40000 200000;bootm 50008000 mtdpart=40000 400000 4000000 bootdelay=3 baudrate=115200 ethaddr=00:40:5c:26:0a:5b ipaddr=192.168.11.110 serverip=192.168.11.120 gatewayip=192.168.11.1 netmask=255.255.255.0 stdin=serial stdout=serial stderr=serial Environment size: 350/16380 bytes MANGO64 # |
print를 해보면 우리가 설정한 모든 것들이 정상적으로 출력되는 것을 확인할 수 있습니다.
MANGO64 # tftp 51000000 u-boot.bin smc911x: initializing smc911x: detected LAN9220 controller smc911x: phy initialized smc911x: MAC 00:40:5c:26:0a:5b TFTP from server 192.168.11.120; our IP address is 192.168.11.110 Filename 'u-boot.bin'. Load address: 0x51000000 Loading: ############### done Bytes transferred = 219624 (0x359e8) |
이제 NAND에 실제로 U-boot 바이너리를 저장하기 위해서 메모리에 다운로드를 받았습니다.
tftp를 통해서 PC로부터 u-boot.bin을 정확하게 다운받고 있습니다.
MANGO64 # nand erase 0 40000 NAND erase: device 0 offset 0x0, size 0x40000 Erasing at 0x20000 -- 100% complete. OK |
메모리에 다운 받은 u-boot.bin을 NAND에 저장하기 위해서
0 ~ 40000 부분의 NAND를 먼저 erase 하고 있습니다.
MANGO64 # nand write 51000000 0 40000 NAND write: device 0 offset 0x0, size 0x40000 262144 bytes written: OK |
erase한 영역에 메모리의 데이타를 Write하고 있습니다.
MANGO64 # save Saving Environment to NAND... Erasing Nand... Erasing at 0x20000 -- 100% complete. Writing to Nand... done |
환경 변수를 저장하고 있습니다.
이제 NAND로 부팅 모드를 변경해서 부팅을 해보도록 하겠습니다.
U-Boot 1.3.4 (Jan 18 2010 - 21:52:25) for MANGO64 CPU: S3C6410@532MHz Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode) Board: MANGO64 DRAM: 128 MB Flash: 0 kB NAND: 256 MB In: serial Out: serial Err: serial Hit any key to stop autoboot: 0 MANGO64 # |
NAND로도 정확하게 부팅이 되는 것을 확인할 수 있었습니다.
이제 기존에 우리가 가지고 있던 망고 64용 커널과 파일 시스템을 올려보도록 하겠습니다.
MANGO64 # setenv ipaddr 192.168.11.110; setenv serverip 192.168.11.120; sete nv gatewayip 192.168.11.1; setenv bootcmd "nand read 50008000 40000 200000;b ootm 50008000"; setenv bootargs rootfstype=jffs2 root=/dev/mtdblock2 init=/i nit console=ttySAC1,115200 MANGO64 # tftp 51000000 Mango64-kernel-2.6.29-V01-000.zImage; nand erase 400 00 200000; nand write 51000000 40000 200000; smc911x: initializing smc911x: detected LAN9220 controller smc911x: phy initialized smc911x: MAC 00:40:5c:26:0a:5b TFTP from server 192.168.11.120; our IP address is 192.168.11.110 Filename 'Mango64-kernel-2.6.29-V01-000.zImage'. Load address: 0x51000000 Loading: ################################################################# ################################################################ done Bytes transferred = 1880204 (0x1cb08c) NAND erase: device 0 offset 0x40000, size 0x200000 Skipping bad block at 0x00040000 Skipping bad block at 0x00060000 Skipping bad block at 0x00080000 Skipping bad block at 0x000a0000 Erasing at 0x220000 -- 100% complete. OK NAND write: device 0 offset 0x40000, size 0x200000 2097152 bytes written: OK |
커널을 다운로드 하는 것은 문제없이 동작한 것으로 보입니다.
MANGO64 # tftp 0x51000000 Mango64-AndroidCupcake-V01-000.jffs2; nand erase 0 x400000 0x4000000; nand write.jffs2 0x51000000 0x400000 0x1da0000; save; sav e; re smc911x: initializing smc911x: detected LAN9220 controller smc911x: phy initialized smc911x: MAC 00:40:5c:26:0a:5b TFTP from server 192.168.11.120; our IP address is 192.168.11.110 Filename 'Mango64-AndroidCupcake-V01-000.jffs2'. Load address: 0x51000000 Loading: ################################################################# ..... ..... ..... ..... ..... ..... ##################################### done Bytes transferred = 31064064 (0x1da0000) NAND erase: device 0 offset 0x400000, size 0x4000000 Skipping bad block at 0x02600000 Erasing at 0x43e0000 -- 100% complete. OK NAND write: device 0 offset 0x400000, size 0x1da0000 Writing data at 0x219f800 -- 100% complete. 31064064 bytes written: OK Saving Environment to NAND... Erasing Nand... Erasing at 0x20000 -- 100% complete. Writing to Nand... done Saving Environment to NAND... Erasing Nand... Erasing at 0x20000 -- 100% complete. Writing to Nand... done reset... |
파일 시스템 역시 정상적으로 저장이 된 것으로 보입니다.
U-Boot 1.3.4 (Jan 18 2010 - 21:52:25) for MANGO64 CPU: S3C6410@532MHz Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode) Board: MANGO64 DRAM: 128 MB Flash: 0 kB NAND: 256 MB In: serial Out: serial Err: serial Hit any key to stop autoboot: 0 NAND read: device 0 offset 0x40000, size 0x200000 s3c-nand: ECC uncorrectable error detected s3c-nand: 1 bit error detected at byte 205, correcting from 0x00 to 0x80...OK s3c-nand: 1 bit error detected at byte 219, correcting from 0x00 to 0x20...OK s3c-nand: ECC uncorrectable error detected s3c-nand: ECC uncorrectable error detected ..... ..... ..... ..... ..... ..... s3c-nand: 1 bit error detected at byte 499, correcting from 0x00 to 0x08...OK s3c-nand: 1 bit error detected at byte 23, correcting from 0x00 to 0x01...OK s3c-nand: 1 bit error detected at byte 298, correcting from 0x00 to 0x02...OK s3c-nand: ECC uncorrectable error detected 2097152 bytes read: ERROR get_format -------- 0 -------- Wrong Image Format for bootm command ERROR: can't get kernel image! MANGO64 # |
뭔가 ECC 관련해서 좀더 확인이 필요해 보입니다.
uboot-1.3.4-pooh10에서 문제가 되었던 부분이 ECC 관련한 것이었습니다.
불현듯 떠오르는 생각이 왠지 nand scrub을 수행하지 않았기 때문이 아닐까 합니다.
MANGO64 # nand scrub NAND scrub: device 0 whole chip Warning: scrub option will erase all factory set bad blocks! There is no reliable way to recover them. Use this command only for testing purposes if you are sure of what you are doing! Really scrub this NAND flash? <y/N> Erasing at 0x23c0000 -- 14% complete. NAND 256MiB 3,3V 8-bit: MTD Erase failure: -5 Erasing at 0xeb80000 -- 92% complete. NAND 256MiB 3,3V 8-bit: MTD Erase failure: -5 Erasing at 0xffe0000 -- 100% complete. Scanning device for bad blocks s3c-nand: ECC uncorrectable error detected s3c-nand: ECC uncorrectable error detected s3c-nand: ECC uncorrectable error detected s3c-nand: ECC uncorrectable error detected OK |
위와 같이 nand scrub을 수행한 이후에 커널과 파일 시스템을 다운로드 했을 때
정상적으로 안드로이드 화면까지 부팅하는 것을 확인했습니다.
uboot-1.3.4-pooh11
mango64.h (include\configs)
#define CFG_NAND_HWECC #define CONFIG_NAND_BL1_8BIT_ECC |
mango64.h에 보면 위와 같이 정의되어 있는 것을 발견할수 있습니다.
Hardware ECC를 사용하고 있는 것이고, 8 비트 ECC를 사용하도록 설정되어 있습니다.
6410 매뉴얼을 살펴보면 아래와 같이 기술되어 있습니다.
Support both SLC and MLC NAND flash memory : 1-bit ECC, 4-bit and 8-bit ECC for NAND flash. (Recommend: 1bit ECC for SLC, 4bit and 8bit ECC for MLC NAND Flash) |
망고 64에서 사용하는 NAND인 K9F2G08U0M는 SLC NAND 입니다.
그러므로 1-bit ECC를 사용해야 하고
위에서 CONFIG_NAND_BL1_8BIT_ECC는 삭제하는 것이 맞을 것으로 판단됩니다.
//#define CONFIG_NAND_BL1_8BIT_ECC |
위와 같이 코드 상에서 주석으로 처리하였습니다.
uboot-1.3.4-pooh11에서 주요하게 달라진 것은 위의 코드입니다.
#define CONFIG_BOOTCOMMAND "nand read 50008000 40000 400000;bootm 50008000" |
추가적으로 향후 커널이 증가할 것을 대비해서 위와 같이
NAND에서 읽어오는 부분을 200000에서 400000으로 변경하였습니다.
#define CONFIG_IDENT_STRING " for MANGO64 uboot-1.3.4-pooh11" |
부팅 시 표시하는 문구에 uboot-1.3.4-pooh11를 넣어주었습니다.
이제 실제로 실행해서 모든 작업을 수행해 보도록 하겠습니다.
U-Boot 1.3.4 (Jan 19 2010 - 11:24:18) for MANGO64 uboot-1.3.4-pooh11 CPU: S3C6410@532MHz Fclk = 532MHz, Hclk = 133MHz, Pclk = 66MHz, Serial = CLKUART (SYNC Mode) Board: MANGO64 DRAM: 128 MB Flash: 0 kB NAND: 256 MB s3c-nand: ECC uncorrectable error detected *** Warning - bad CRC or NAND, using default environment sizeof(default_environment): 311 CFG_ENV_SIZE: 16384, ENV_SIZE: 16380 In: serial Out: serial Err: serial Hit any key to stop autoboot: 0 |
uboot-1.3.4-pooh11가 정확하게 출력되고 있습니다.
MANGO64 # print bootargs=rootfstype=jffs2 root=/dev/mtdblock2 init=/init console=ttySAC1,115200 bootcmd=nand read 50008000 40000 400000;bootm 50008000 mtdpart=40000 400000 4000000 bootdelay=3 baudrate=115200 ethaddr=00:40:5c:26:0a:5b ipaddr=192.168.11.110 serverip=192.168.11.120 gatewayip=192.168.11.1 netmask=255.255.255.0 stdin=serial stdout=serial stderr=serial Environment size: 350/16380 bytes |
print를 해보면 수정된 사항이 정확하게 반영되어 있습니다.
tftp 51000000 uboot-1.3.4-pooh11.bin nand erase 0 40000; nand write 51000000 0 40000; |
위와 같이 NAND에 기록을 하고 NAND mode로 변경 후 부팅을 하였습니다.
tftp 51000000 zImage-wifi nand erase 40000 400000; nand write 51000000 40000 400000; |
NAND에 커널을 기록하는 부분도 위와 같이 400000까지 기록할 수 있도록 설정하였습니다.
tftp 0x51000000 CB64-wifi.jffs2 nand erase 0x400000 0x4000000 nand write.jffs2 0x51000000 0x400000 0x21e0000; save; save; re |
파일 시스템까지 기록한 이후에 정상적으로 부팅이 되는 것을 확인했습니다.
오늘까지 6번에 걸쳐서 U-Boot에 대한 부분을 살펴보았습니다.
SMDK6410 보드에서 동작하는 U-Boot 소스를 가져다가 하나씩 바꾸어 가면서
망고 64 보드에 적용해가는 과정을 통해서
조금이나마 U-Boot에 대한 이해를 넓힌 듯 생각됩니다.
하지만 소스 코드를 보면서 느낀 것이 알아야 할 내용이 너무 많다는 생각입니다.
나중에 U-Boot에 대해서 보다 심도 있게 분석하는 기회가 있었으면 합니다.
감사합니다.