SD 카드 직접 이식 과정 정리



앞서 우분투에서 SD 카드에 직접 안드로이드 심는 과정을 살펴봤는데, 직전 포스트에서 에러가 있다고 이야기했다.


에러 메세지를 검색하기 전에, 포맷 되지 않은 파티션이 있음을 알아채고 모든 파티션을 제대로 포맷한 후, 진행했더니, 덜컥! SD 부팅이 성공했다.

안드로이드 부팅 성공!



그 과정을 정리한다.

필요한 파일 : u-boot.bin, zImage, ramdisk, system.img

sd_fdisk2, mkbl1, sd_fusing.sh


sd 카드는 /dev/sdb 가정

~/out 안에 모든 파일이 있다고 가정.


ryu@ryu-Ubuntu:~/work $ sudo ./sd_fusing.sh /dev/sdb


ryu@ryu-Ubuntu:~/work $ sudo dd if=~/work/zImage of=/dev/sdb seek=1073


ryu@ryu-Ubuntu:~/work $ sudo dd if=~/work/ramdisk.img of=/dev/sdb seek=9265


ryu@ryu-Ubuntu:~/work $ sudo dd if=~/work/system.img of=/dev/sdb seek=23136


ryu@ryu-Ubuntu:~/work $ sync


sd_fusing.sh 는 sd_fdisk2 와 mkbl1 을 이용해서 SD 카드를 파티션하고, 포맷하고, BL1 과 u-boot 를 기록한다.


이후, zImage, ramdisk, system.img 를 기록하면 완료!



sd_fusing.sh 내에 u-boot.bin 위치는 수정해줘야되고.

sd_fdisk2 와 mkbl1 


mkbl1 소스 C110-EVT1-mkbl1.c


/*

 * Copyright (c) 2010 Samsung Electronics Co., Ltd.

 *              http://www.samsung.com/

 *

 * This program is free software; you can redistribute it and/or modify

 * it under the terms of the GNU General Public License version 2 as

 * published by the Free Software Foundation.

 */


#include <stdio.h>

#include <string.h>

#include <stdlib.h>


int main (int argc, char *argv[])

{

FILE *fp;

char *Buf, *a;

int BufLen;

int nbytes, fileLen;

unsigned int checksum;

int i;


//////////////////////////////////////////////////////////////

if (argc != 4)

{

printf("Usage: mkbl1 <source file> <destination file> <size> \n");

return -1;

}


//////////////////////////////////////////////////////////////

BufLen = atoi(argv[3]);

Buf = (char *)malloc(BufLen);

memset(Buf, 0x00, BufLen);

//////////////////////////////////////////////////////////////

fp = fopen(argv[1], "rb");

if( fp == NULL)

{

printf("source file open error\n");

free(Buf);

return -1;

}


fseek(fp, 0L, SEEK_END);

fileLen = ftell(fp);

fseek(fp, 0L, SEEK_SET);


if ( BufLen > fileLen )

{

printf("Usage: unsupported size\n");

free(Buf);

fclose(fp);

return -1;

}


nbytes = fread(Buf, 1, BufLen, fp);


if ( nbytes != BufLen )

{

printf("source file read error\n");

free(Buf);

fclose(fp);

return -1;

}


fclose(fp);


//////////////////////////////////////////////////////////////

a = Buf + 16;

for(i = 0, checksum = 0; i < BufLen - 16; i++)

checksum += (0x000000FF) & *a++;


a = Buf + 8;

*( (unsigned int *)a ) = checksum;


//////////////////////////////////////////////////////////////

fp = fopen(argv[2], "wb");

if (fp == NULL)

{

printf("destination file open error\n");

free(Buf);

return -1;

}


a = Buf;

nbytes = fwrite( a, 1, BufLen, fp);


if ( nbytes != BufLen )

{

printf("destination file write error\n");

free(Buf);

fclose(fp);

return -1;

}


free(Buf);

fclose(fp);


return 0;

}


sd_fdisk2.c 소스 (sd_fdisk.c 와 u-boot 의 fdisk 참고해서 작성한 버전)

mbr을 직접 기록하므로, sd_fusing.sh 에 mbr 을 dd 하는 필요없다. 주석처리.


/*

 * Copyright (c) 2010 Samsung Electronics Co., Ltd.

 *              http://www.samsung.com/

 *

 * fdisk command for U-boot

 *

 * This program is free software; you can redistribute it and/or modify

 * it under the terms of the GNU General Public License version 2 as

 * published by the Free Software Foundation.

 */


#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <fcntl.h>

#include <sys/ioctl.h>

#include <mtd/mtd-user.h>



#define BLOCK_SIZE 512

#define BLOCK_END 0xFFFFFFFF

#define _10MB (10*1024*1024)

#define _100MB (100*1024*1024)

#define _8_4GB (1023*254*63)


#define SYSTEM_PART_SIZE (256*1024*1024)

#define USER_DATA_PART_SIZE (350*1024*1024)

#define CACHE_PART_SIZE _100MB


#define CHS_MODE 0

#define LBA_MODE !(CHS_MODE)


typedef struct

{

int C_start;

int H_start;

int S_start;


int C_end;

int H_end;

int S_end;


int available_block;

int unit;

int total_block_count;

int addr_mode; // LBA_MODE or CHS_MODE

} SDInfo;


typedef struct

{

unsigned char bootable;

unsigned char partitionId;


int C_start;

int H_start;

int S_start;


int C_end;

int H_end;

int S_end;


int block_start;

int block_count;

int block_end;

} PartitionInfo;


/////////////////////////////////////////////////////////////////

int calc_unit(int length, SDInfo sdInfo)

{

if (sdInfo.addr_mode == CHS_MODE)

return ( (length / BLOCK_SIZE / sdInfo.unit + 1 ) * sdInfo.unit);

else

return ( (length / BLOCK_SIZE) );

}


/////////////////////////////////////////////////////////////////

void encode_chs(int C, int H, int S, unsigned char *result)

{

*result++ = (unsigned char) H;

*result++ = (unsigned char) ( S + ((C & 0x00000300) >> 2) );

*result   = (unsigned char) (C & 0x000000FF); 

}


/////////////////////////////////////////////////////////////////

void get_SDInfo(int block_count, SDInfo *sdInfo)

{

       int C, H, S;


        int C_max = 1023, H_max = 255, S_max = 63;

        int H_start = 1, S_start = 1;

        int diff_min = 0, diff = 0;


        if(block_count >= _8_4GB)

                sdInfo->addr_mode = LBA_MODE;

        else

                sdInfo->addr_mode = CHS_MODE;


//-----------------------------------------------------

        if (sdInfo->addr_mode == CHS_MODE)

        {

                diff_min = C_max;


                for (H = H_start; H <= H_max; H++)

                        for (S  = S_start; S <= S_max; S++)

                        {

                                C = block_count / (H * S);


                                if ( (C <= C_max) )

                                {

                                        diff = C_max - C;

                                        if (diff <= diff_min)

                                        {

                                                diff_min = diff;

                                                sdInfo->C_end = C;

                                                sdInfo->H_end = H;

                                                sdInfo->S_end = S;

                                        }

                                }

                        }

        }

//-----------------------------------------------------

        else

        {

                sdInfo->C_end = 1023;

                sdInfo->H_end = 254;

                sdInfo->S_end = 63;

        }


//-----------------------------------------------------

        sdInfo->C_start                 = 0;

        sdInfo->H_start                 = 1;

        sdInfo->S_start                 = 1;


        sdInfo->total_block_count       = block_count;

        sdInfo->available_block         = sdInfo->C_end * sdInfo->H_end * sdInfo->S_end;

        sdInfo->unit                    = sdInfo->H_end * sdInfo->S_end;

}


/////////////////////////////////////////////////////////////////

void encode_partitionInfo(PartitionInfo partInfo, unsigned char *result)

{

*result++ = partInfo.bootable;


encode_chs(partInfo.C_start, partInfo.H_start, partInfo.S_start, result);

result +=3;

*result++ = partInfo.partitionId;


encode_chs(partInfo.C_end, partInfo.H_end, partInfo.S_end, result);

result += 3;


memcpy(result, (unsigned char *)&(partInfo.block_start), 4);

result += 4;

memcpy(result, (unsigned char *)&(partInfo.block_count), 4);

}


/////////////////////////////////////////////////////////////////

int get_sd_block_count(char *device_name)

{

FILE *fp;

char buf[128];


int block_count = 0;

int nbytes = 0;


char *t = "/sys/block/";

char sd_size_file[64];


strcpy(sd_size_file, t);

strcat(sd_size_file, &device_name[5]);

strcat(sd_size_file, "/size");


fp = fopen(sd_size_file, "rb");

nbytes = fread(buf, 1, 128, fp);

fclose(fp);


block_count = atoi(buf);

return block_count;

}


/////////////////////////////////////////////////////////////////

int put_sd_mbr(unsigned char *mbr, char *device_name)

{

int rv;

FILE *fp;

int fd, i=0;


fp = fopen(device_name, "r+b");

fseek(fp, 0, SEEK_SET);

fwrite(mbr, 1, 512, fp);

fclose(fp);


return 0;

}


/////////////////////////////////////////////////////////////////

void make_partitionInfo(int LBA_start, int count, SDInfo sdInfo, PartitionInfo *partInfo)

{

        int             temp = 0;

        int             _10MB_unit;


        partInfo->block_start   = LBA_start;


//-----------------------------------------------------

        if (sdInfo.addr_mode == CHS_MODE)

        {

                partInfo->C_start       = partInfo->block_start / (sdInfo.H_end * sdInfo.S_end);

                temp                    = partInfo->block_start % (sdInfo.H_end * sdInfo.S_end);

                partInfo->H_start       = temp / sdInfo.S_end;

                partInfo->S_start       = temp % sdInfo.S_end + 1;


                if (count == BLOCK_END)

                {

                        _10MB_unit = calc_unit(_10MB, sdInfo);

                        partInfo->block_end     = sdInfo.C_end * sdInfo.H_end * sdInfo.S_end - _10MB_unit - 1;

                        partInfo->block_count   = partInfo->block_end - partInfo->block_start + 1;


                        partInfo->C_end = partInfo->block_end / sdInfo.unit;

                        partInfo->H_end = sdInfo.H_end - 1;

                        partInfo->S_end = sdInfo.S_end;

                }

                else

                {

                        partInfo->block_count   = count;


                        partInfo->block_end     = partInfo->block_start + count - 1;

                        partInfo->C_end         = partInfo->block_end / sdInfo.unit;


                        temp                    = partInfo->block_end % sdInfo.unit;

                        partInfo->H_end         = temp / sdInfo.S_end;

                        partInfo->S_end         = temp % sdInfo.S_end + 1;

                }

        }

//-----------------------------------------------------

        else

        {

                partInfo->C_start       = 0;

                partInfo->H_start       = 1;

                partInfo->S_start       = 1;


                partInfo->C_end         = 1023;

                partInfo->H_end         = 254;

                partInfo->S_end         = 63;


                if (count == BLOCK_END)

                {

                        _10MB_unit = calc_unit(_10MB, sdInfo);

                        partInfo->block_end     = sdInfo.total_block_count - _10MB_unit - 1;

                        partInfo->block_count   = partInfo->block_end - partInfo->block_start + 1;


                }

                else

                {

                        partInfo->block_count   = count;

                        partInfo->block_end     = partInfo->block_start + count - 1;

                }

        }

}


/////////////////////////////////////////////////////////////////

int make_sd_partition(int total_block_count, unsigned char *mbr)

{

int block_start = 0, block_offset;


SDInfo sdInfo;

PartitionInfo partInfo[4];


///////////////////////////////////////////////////////////

memset((unsigned char *)&sdInfo, 0x00, sizeof(SDInfo));


///////////////////////////////////////////////////////////

get_SDInfo(total_block_count, &sdInfo);


///////////////////////////////////////////////////////////

block_start = calc_unit(_10MB, sdInfo);

block_offset = calc_unit(SYSTEM_PART_SIZE, sdInfo);


partInfo[0].bootable = 0x00;

partInfo[0].partitionId = 0x83;


make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[0]);


///////////////////////////////////////////////////////////

block_start += block_offset;

block_offset = calc_unit(USER_DATA_PART_SIZE, sdInfo);

partInfo[1].bootable = 0x00;

partInfo[1].partitionId = 0x83;


make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[1]);


///////////////////////////////////////////////////////////

block_start += block_offset;

block_offset = calc_unit(CACHE_PART_SIZE, sdInfo);


partInfo[2].bootable = 0x00;

partInfo[2].partitionId = 0x83;


make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[2]);


///////////////////////////////////////////////////////////

block_start += block_offset;

block_offset = BLOCK_END;


partInfo[3].bootable = 0x00;

partInfo[3].partitionId = 0x0C;


make_partitionInfo(block_start, block_offset, sdInfo, &partInfo[3]);


///////////////////////////////////////////////////////////

memset(mbr, 0x00, sizeof(mbr));

mbr[510] = 0x55; mbr[511] = 0xAA;


encode_partitionInfo(partInfo[0], &mbr[0x1CE]);

encode_partitionInfo(partInfo[1], &mbr[0x1DE]);

encode_partitionInfo(partInfo[2], &mbr[0x1EE]);

encode_partitionInfo(partInfo[3], &mbr[0x1BE]);

return 0;

}


/////////////////////////////////////////////////////////////////

int create_sd_fdisk(int argc, char *argv[])

{

int rv;

int total_block_count;

unsigned char mbr[512];


memset(mbr, 0x00, 512);

total_block_count = get_sd_block_count(argv[1]);

if (total_block_count < 0)

return -1;

printf("total_block_count : %d",total_block_count);


make_sd_partition(total_block_count, mbr);


rv = put_sd_mbr(mbr, argv[1]);

if (rv != 0)

return -1;

printf("fdisk is completed\n");


return 0;

}


/////////////////////////////////////////////////////////////////

int main(int argc, char *argv[])

{

if ( argc != 2 )

{

printf("Usage: sd_fdisk2 <device_name>\n");

return 0;

}


return create_sd_fdisk(argc, argv);

}




파티션 할 때, SYSTEM_PART_SIZE, USER_DATA_PART_SIZE 를 설정해 줄 수 있게 수정해야겠다.


sd_fusing.sh 소스


#

# Copyright (C) 2010 Samsung Electronics Co., Ltd.

#              http://www.samsung.com/

#

# This program is free software; you can redistribute it and/or modify

# it under the terms of the GNU General Public License version 2 as

# published by the Free Software Foundation.

#

####################################

#!/bin/bash

reader_type1="/dev/sdb"

reader_type2="/dev/mmcblk0"


if [ -z $1 ]

then

    echo "usage: ./sd_fusing.sh <SD Reader's device file>"

    exit 0

fi


if [ -b $1 ]

then

    echo "$1 reader is identified."

else

    echo "$1 is NOT identified."

    exit 0

fi


if [ $1 = $reader_type1 ]

then 

    partition1="${1}1"

    partition2="${1}2"

    partition3="${1}3"

    partition4="${1}4"

elif [ $1 = $reader_type2 ]

then 

    partition1="$1p1"

    partition2="$1p2"

    partition3="$1p3"

    partition4="$1p4"

else

    echo "Unsupported SD reader"

    exit 0

fi


####################################

# make partition

echo "make sd card partition"

echo "./sd_fdisk2 $1" 

./sd_fdisk2 $1 

#dd iflag=dsync oflag=dsync if=sd_mbr.dat of=$1 

#rm sd_mbr.dat

 

####################################

# format

umount $partition1 2> /dev/null

umount $partition2 2> /dev/null

umount $partition3 2> /dev/null

umount $partition4 2> /dev/null


echo "mkfs.vfat -F 32 $partition1"

mkfs.vfat -F 32 "$partition1"


echo "mkfs.ext2 $partition2"

mkfs.ext2 "$partition2"


echo "mkfs.ext2 $partition3"

mkfs.ext2 "$partition3"  


echo "mkfs.ext2 $partition4"

mkfs.ext2 "$partition4"  


####################################

# mount 

#umount /media/sd 2> /dev/null

#mkdir -p /media/sd

#echo "mount -t vfat $partition1 /media/sd"

#mount -t vfat $partition1 /media/sd


####################################

#<BL1 fusing>

bl1_position=1

uboot_position=49


echo "BL1 fusing"

./mkbl1 u-boot.bin SD-bl1-8k.bin 8192

dd iflag=dsync oflag=dsync if=SD-bl1-8k.bin of=$1 seek=$bl1_position

rm SD-bl1-8k.bin


####################################

#<u-boot fusing>

echo "u-boot fusing"

dd iflag=dsync oflag=dsync if=../u-boot.bin of=$1 seek=$uboot_position


####################################

#<Message Display>

echo "U-boot image is fused successfully."

echo "Eject SD card and insert it again."




여기까지 정리하고, 이제 kitkat 이식 살펴봐야겠다.









Posted by 똑똑한 영장류

MV V210 SD 카드에 바로 퓨징


sd_fusing 스크립트를 통해서 부트로더를 올리는 것은 구현이 되서 그 다음으로 커널을 올려보았다.



MV 제공 zImage 파일을 이용했다.


리눅스의 dd 명령을 이용해서 SD 카드의 특정 위치에다가 기록을 했다.

특정 위치는 fastboot 를 이용해서 기록할 때 화면에서 확인한 1073이다.( 1073 의 의미는??)






보드에 SD 카드 끼우고 SD 모드로 부팅시켰더니...





오호~~ 커널이 올라왔다.. root fs 를 발견 못해서 패니꾸!!


이제 RFS 를 올려봐야겠다. 그리고, 1073 이 숫자의 의미를 알고 싶다.



MV 제공 램디스크도 기록!




보드에 장착 테스트!





다음 단계로 왔다! 이제 system 파일들을 찾는다.


system 파티션이 준비되어있어야하는데, 나는 sd_fdisk 소스를 수정해서 파티션 4개로 나누도록 했다.





system.img 도 같은 방식으로 기록하면 될까???





system.img 는 /system 에 올라가야하는데, 파티션 잡은걸로는 시작 위치가 23136이다. 그래서 seek 위치를 조정해줬다. 이건 파티션정보를 보고 결정하면 될 거 같다.


보드 LCD에 안드로이드 로고는 나타났으나, 테라텀 창에서는 init: untracked pid... 에러가 뜨면서 안드로이드 부팅이 완료되지 않았다.



많이 가까이 갔다. 좀 더 공부해야겠다.




















Posted by 똑똑한 영장류

MV V210 SD 카드에 바로 퓨징


매번 dragin, fastboot 를 통해서 안드로이드를 이식하는 작업이 꽤나 성가셔서 우분투에서 바로 SD 카드에 모두 기록할 수 있는 방법이 없을까 찾아봤다.



우선 MV 제공 이미지 파일들을 이용해서 ICS가 제대로 올라가도록 해 보고, 이후 kitkat 작업해야겠다.



이전 방법을 이용했을 때, 절차는 결국, 파티션, BL1 기록, u-boot 기록, zImage 기록, ramdisk 기록, system.img 기록, userdata.img 기록이다.

이걸 우분투에서 모두 할 수 있으면 문제는 해결!



제공된 u-boot 소스 아래에 sd_fusing 이라는 디렉토리가 있다.


sd_fusing.sh, sd_fusing2.sh 가 있다.

머가 다른가...



sd_fusing.sh 

 sd_fusing2.sh

 reader_type1="/dev/sdd"


#<BL1 fusing>

bl1_position=1

uboot_position=49





echo "BL1 fusing"

./mkbl1 ../u-boot.bin SD-bl1-8k.bin 8192

dd iflag=dsync oflag=dsync if=SD-bl1-8k.bin of=$1 seek=$bl1_position

rm SD-bl1-8k.bin


#<u-boot fusing>

echo "u-boot fusing"

dd iflag=dsync oflag=dsync if=../u-boot.bin of=$1 seek=$uboot_position







 reader_type1="/dev/sdb"


#<BL1 fusing>

signed_bl1_position=1

bl2_position=9

uboot_position=57




echo "BL1 fusing"

dd iflag=dsync oflag=dsync if=c110.signedBL1_bin of=$1 seek=$signed_bl1_position




#<u-boot fusing>

echo "u-boot fusing"

dd iflag=dsync oflag=dsync if=../u-boot.bin of=$1 seek=$bl2_position count=16

dd iflag=dsync oflag=dsync if=../u-boot.bin of=$1 seek=$uboot_position








여기 mkbl1 이라는 실행파일이 있는데, Makefile을 보니, C110-EVT1-mkbl1.c 로 만들어진 파일이다. u-boot.bin 에서 BL1을 만드는 기능을 하는거 같다.


두 스크립트 모두,  리눅스에 연결된 SD 카드를 지정해주고, mkbl1 을 이용해서 u-boort.bin 으로부터 BL1을 만들고, BL1을 특정위치에, 이어서 u-boot.bin 도 특정 위치에 기록하는 작업을 수행하는 듯 보인다.


두 스크립트의 차이는 기록할 위치정도인듯하고...sd_fusing2.sh 의 저 c110.signedBL1.bin 은 어떻게 만들어지는도 알 수가 없고 signed 의 의미도 모르겠네.

sd_fusing2.sh 는 무시하고, sd_fusing.sh 만 잘 만지면 될 거 같다.



차례대로 하나씩 해 보자...


sd_fusing.sh 살펴보기


reader_type1="/dev/sdb"

reader_type2="/dev/mmcblk0"


if [ -z $1 ]

then

    echo "usage: ./sd_fusing.sh <SD Reader's device file>"

    exit 0

fi


if [ $1 = $reader_type1 ]

then 

    partition1="$11"

    partition2="$12"

    partition3="$13"

    partition4="$14"


elif [ $1 = $reader_type2 ]

then 

    partition1="$1p1"

    partition2="$1p2"

    partition3="$1p3"

    partition4="$1p4"


else

    echo "Unsupported SD reader"

    exit 0

fi


if [ -b $1 ]

then

    echo "$1 reader is identified."

else

    echo "$1 is NOT identified."

    exit 0

fi


sh_fusing.sh 실행할 때 전달하는 인자를 이용해서 파티션 이름을 설정해준다. 그리고나서 인자로 지정해준 디바이스가 존재하는 체크하네.


연결된 SD 카드가 sda인지, sdb 인지 확인하고 reader_type1 값 수정부터 해 줘야겠다..

내 경우엔, 

reader_type1="/dev/sdb"


####################################

# make partition

echo "make sd card partition"

echo "./sd_fdisk $1" 

./sd_fdisk $1 

dd iflag=dsync oflag=dsync if=sd_mbr.dat of=$1 

#rm sd_mbr.dat

 

####################################

# format

umount $partition1 2> /dev/null

umount $partition2 2> /dev/null

umount $partition3 2> /dev/null

umount $partition4 2> /dev/null


echo "mkfs.vfat -F 32 $partition1"

mkfs.vfat -F 32 $partition1


#echo "mkfs.ext2 $partition2"

#mkfs.ext2 $partition2  


#echo "mkfs.ext2 $partition3"

#mkfs.ext2 $partition3  


#echo "mkfs.ext2 $partition4"

#mkfs.ext2 $partition4  


이상없으면 sd_fdisk 를 이용해서 파티션해주고, 포맷을 진행하는데, $partition1 만 포맷하고 있네..주석처리되어있는 것들은 이유가 머냐? (sd_fdisk 소스보니까 파티션을 하나밖에 안 하더라. 아마 그래서 주석처리.)


####################################

# mount 

#umount /media/sd 2> /dev/null

#mkdir -p /media/sd

#echo "mount -t vfat $partition1 /media/sd"

#mount -t vfat $partition1 /media/sd


####################################

#<BL1 fusing>

bl1_position=1

uboot_position=49


echo "BL1 fusing"

./mkbl1 ../u-boot.bin SD-bl1-8k.bin 8192

dd iflag=dsync oflag=dsync if=SD-bl1-8k.bin of=$1 seek=$bl1_position

#rm SD-bl1-8k.bin


####################################

#<u-boot fusing>

echo "u-boot fusing"

dd iflag=dsync oflag=dsync if=../u-boot.bin of=$1 seek=$uboot_position


####################################

#<Message Display>

echo "U-boot image is fused successfully."

echo "Eject SD card and insert it again."



mkbl1 을 이용해서 SD-bl1-8k.bin 을 만들어  $bl1_position 에 기록하고, u-boot.bin 도 $uboot_position 에서부터 기록을 한다.




일단 실행 한번 시켜보까나..

reader_type? 수정해주고...

터미널로 sd_fusing 디렉토리에 가서, sh_fusing.sh 실행시켜보자. 상위 디렉토리에 u-boot.bin 파일이 있어야하고, /dev 접근 때문에 스크립트를 sudo 로 실행시켜야한다.





mkfs 실행 중에 에러발생!!! 에러 발생해서 보니, mkfs 로 partition1이 제대로 넘어가지 않았다.


$11 이 예전에는 $1에 1이 붙었었는데, 이제 11번째 인자를 표시하는가싶다. 아래처럼 수정해주면 partition1, 2, 3, 4가 제대로 설정된다.


if [ $1 = $reader_type1 ]

then 

    partition1="${1}1"

    partition2="${1}2"

    partition3="${1}3"

    partition4="${1}4"


스크립트 실행전과 실행후의 SD 카드 파티션 정보를 한 번 찍어봤다.







sd_fdisk 소스도 살펴보니, 파티션 테이블 포함한 MBR 생성해서 파일로 저장하고 있는데, 원 소스는 파티션을 하나만 하도록 되어있었다. 

MBR 파일은 sd_mbr.dat.. 기록하고는 지우도록 되어있네.


수정해야되는거 수정하고 다시 실행시키고, BL1이 기록된 상태에서 보드로 테스트를 해 봤다.




u-boot 가 적절한 위치에 잘 올라간거 같네...


이제 sd_fdisk 수정하고, zImage, ramdisk 등등 올려봐야겠다. 잘 될까?






Posted by 똑똑한 영장류

S5PV210 CPU 는 클럭 속도가 1GHz 이고, MVV210 보드에 달려있는 램은 512MB이다.


마시멜로가 최신 버전이라, 한참 철 지난 스펙의 보드에서 버벅거릴까 걱정된다.


물론, 저 스펙의 Nexus S 에 마시멜로를 올렸다는 희망적인 글이 눈에 띄긴 하지만, 난 그정도 고수가 아닌지라 살짝 걱정된다.

그래서....4.4 이상을 요구하는 그 앱만 제대로 동작시킬 수 있으면 되니까 Kitkat 마지막 버전을 이식하기로 결정했다.



요녀석 되시겠다.


Nexus 5 스펙은 어느정도인지 살펴보는게 좋을 듯 싶네..


Nexus 5 는 LG가 만들었고 코드네임은 Hammerhead 란다.

프로세서 : 퀄컴 스냅드래곤 800 MSM8974 SoC. Qualcomm Krait 400 MP4 2.3 GHz CPU, 퀄컴 Adreno 330 GPU

메모리 : 2 GB LPDDR3 SDRAM, 16 / 32 GB 내장 메모리


하~~. MVV210보다 훨~ 좋은 스펙이다.


어쨋든 Kitkat으로 어떻게 해 봐야겠다.







Posted by 똑똑한 영장류

안드로이드 포팅 - 5

(SD 카드에 이미지 기록)

 

안드로이드 소스를 건드리는 작업이 아니고, 빌드된 결과 파일, 즉, img 파일들을 SD 카드에 기록하는 방법에 대해 정리해 놓고자 한다.

 

마이크로비젼에서 제공해 준 매뉴얼에 있는 내용과 그다지 다르지 않다.

Dragin.exe 가 xp에서 정상동작을 한다는 이야기가 있어서 xp 컴퓨터에서 작업한다.

 

1. 준비~~~

http://developer.android.com/sdk/index.html

위 사이트로 가서 SDK Only 를 찾아 android-sdk_r24.4.1-windows.zip 을 다운받는다.

 

 

 

적당한 곳에 압축을 풀고 ... 난 C 드라이브에 아래처럼 압축을 풀었다. 그 안에 있는 SDK Manager.exe 를 실행시키자.

 

 

자바가 설치되어 있지 않으면 껌뻑거리고는 실행되지 않는다.

실행되면 다운받을 거 선택하고 Install 고고 하면 되는데, 중요한건 Android SDK Platform-tools 와 Google USB Driver 다.

 

 

 

 

 

 

6.0 관련한 것들도 깔아보자.. TV, Wear 저런거는 없어도 되지 싶은데...

 

 

 

 

Install Go!!go!!

 

설치 끝나고 나면 C:/android-sdk-windows 디렉토리가 풍성해져 있다.

 

SD 카드에 기록할 때 사용할 fastboot.exe 파일이 C:\android-sdk-windows\platform-tools 안에 들어있는데, 경로를 환경변수에 등록해준다.

 

 

 

 

 

 

 

 

그리고 중요한거, USB Driver 다.

MV V210에 안드로이드가 올라가면 USB 장치로 검색이 되는데, 이때 드라이버를 지정해줘야한다. 그 때 사용할 드라이버다.

 

C:\android-sdk-windows\extra\google\usb_driver 에 있다.

그 안에 있는 android_winusb.inf 파일을 수정하라고 해서 아래 내용을 추가했다.

 

[Google.NTx86]

 

; Samsung SMDK

%SingleBootLoaderInterface% = USB_Install, USB\VID_18D1&PID_0002

%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_0005&MI_01

 

 

여기까지하면 준비가 된거고..MV V210에 맞는 빌드는 아니지만, SD 카드에 한번 기록해 보겠다.

필요한 파일은 Dragin.exe, 시리얼 통신 프로그램(테라텀 정도?) 필요하다.

 

 

 

2. 기록

작업할 디렉토리를 하나 만들겠다. C:\work

여기에 빌드해서 만들어진 img 파일들을 복사한다. 마시멜로 빌드한 거 이용해 볼까...싶지만 설정값들이 달라서 실패할 것이 분명함으로 마이크로비젼 제공 파일로 테스트 하겠다. fast.bat, zImage_wifi, ramdisk_uboot.img, system.img, u-boot.img 파일은 복사해 놓자.

BL1_UART_30000000.nb0, eboot.nb0 도 복사한다.

Dragin.exe 도 복사한다.

테라텀 설치해 놓는다.

 

V210 보드에 전원은 넣지 말고, 부트모드를 iROM 모드로 설정한다. 설정 스위치가 000011 이다.

시리얼 케이블, USB 케이블 연결한다.

 

Dragin.exe 를 실행시킨다.

 

Basic Option 을 아래처럼 설정한다.

 

 

Basic 으로 와서 아래처럼 설정한다.

 

 

 

 아래의 [DETECT] 를 클릭한 후에 전원을 넣는다.

 

 

 

보드를 인식하고 아래처럼 [DOWNLOAD] 버튼이 활성화된다.

 

 

이 때, 보드에 전원이 인가되면서 USB가 띠동! 하고 연결되는데, 제공되는 WinXP USB Driver로 잡아준다.

 

 

 

 

USB 연결 때문에 작업이 끊기는데, 몇번을 반복하면서 제대로 드라이버를 잡아두는 것이 좋다.

 

USB 가 잘 정리됐으면 계속...

 

[DOWNLOAD] 버튼이 활성화 된 상황까지 다시 간 후,

 

이쯤에서 테라텀을 실행시키면 Dragin.exe 가 COM4 를 사용중이라 연결되지 않은 상태로 대기하게 된다.

 

 Baud rate 맞춰 주는거 잊지 말고 설정해주자.

 

 

 

 

요 상태로 대기...

 

Dragin 에서 이제 [DOWNLOAD]를 클릭한다.

 

 

 

BL1 이 쫘~악 올라가고,

 

 

 

이어서 TSR 이 쫘악 올라갈 때, 얼른 테라텀으로 가서 Connect 를 한 다음, 스페이스바를 눌러준다.

 

 

 

uboot 프롬프트를 볼 수 있다.

 

이제 fastboot 를 이용해서 기록을 해 주면 되겠다.

테라텀, uboot 프롬프트에서 아래 명령들을 입력한다.

 

MVV210 # fdisk -c 0

MVV210 # fatformat mmc 0:1 

MVV210 # ext3format mmc 0:2

MVV210 # ext3format mmc 0:3

MVV210 # ext2format mmc 0:4

MVV210 # fastboot

 

아래는 fastboot 까지 입력한 상태다..

 

fastboot 를 입력하고 나면, 곧바로 USB가 인식되면서 드라이버를 요청하는데, C:\android-sdk-windows\extras\google\usb_driver 를 지정해서 설치한다.

 

 

 

 

오케이..

이제 명령 프롬프트, 즉 도스창에서 작업을 해야한다.

 

c:\work 에 모아놓은 파일들 이름이랑 fast.bat 파일 안에 이름들이 같도록 확인한다.

 

fastboot flash bootloader u-boot.bin
fastboot flash kernel zImage_wifi
fastboot flash ramdisk ramdisk-uboot.img
fastboot flash system system.img
fastboot -w
fastboot reboot

 

이때, C:\android-sdk-windows\platform-tools 패스가 잡혀있어야한다.

 

 

 

fast.bat 를 실행한 결과다.

 

 

 

테라텀에서도 진행상황이 보인다.

 

이제 보드의 전원을 차단하고 부팅모드를 SD 모드, 011001 로 변경하고 전원을 넣으면 안드로이드가 잘 실행될 것이다.

 

이때, 또 USB를 인식하고 드라이버 설치를 요구하는데, 그냥 찾기 하니까 아래처럼 찾아지더라..

 

 

 

여기까지 MV V210에 SD 카드를 이용한 안드로이드 심기 절차에 대해서 정리해봤다.

 

마시멜로 심을려면 어떻게 해야하나....

 

 

 

 

 

 

 

 

 



Posted by 똑똑한 영장류

안드로이드 포팅 - 4


다운받은 소스를 빌드해볼 차례다.


나의 최종 목표는 MV V210에 마시멜로를 올려보는 것이다. 전문용어로 target 이 MV V210 이라는 말씀.

그렇게 하려면, MV V210 에 맞게 안드로이드가 빌드되어야하는 건 당연한 일이지만, 

아직 V210에 맞게 소스를 수정하는 작업을 하지는 않고 빌드 절차에 관해서만 살펴보려고 한다.


빌드 해보자

http://source.android.com/source/building.html


위 링크에 가면 빌드 절차가 설명되어 있다.

두번째 문단에 Android 6.0 이상을 빌드할 때 새로운 툴체인, Jack 을 사용할 수 있다는 말이 있다. Jack 에 관해서는 다음에 살펴봐야겠다.


환경설정

우선 터미널 열고, work 디렉토리로 간다.

거기서 아래 명령을 실행해 환경 설정부터 하자.





target 선택

어느 하드웨어에 맞춰서 빌드를 할 것인가를 선택해주어야한다.


명령은 아래의 형태를 가진다.


$ lunch BUILD-BUILDTYPE


예)

$ lunch asop_arm-eng


asop_arm은 타겟, eng 는 아래의 설명에 따른다.


user : 최종 상품? 결과물에 적합

userdebug : user 와 비슷하고 root 권한 접근이 가능하다. 디버깅에 적합

eng : 개발 중일 때 이용할만한 설정


나중에는 asop_arm 자리에 mvv210 을 사용해 빌드할 수 있도록 작업을 해 줘야할 것이다.


그냥 lunch 만 입력하면 아래처럼 가능한 옵션들이 나타난다.



이 21개의 선택지들은 어디서 오는지 나중에 살펴봐야겠다. 어디 mk 파일이 존재할 것이다. 지금은 빌드 절차에 집중하자.

aosp_arm-eng 를 선택했다.




빌드환경 설정값들이 보인다. PLATFORM_VERSION=6.0.1 보니 마시멜로가 맞다.

BUILD_ID=MHC19J 도 맞네..소스는 마시멜로 제대로 받아진 모양이다.




진짜 빌드


$ make -j4


make 명령으로 빌드를 시작하는데, -j4 옵션은 병렬 작업 갯수를 지정해주는 거 같다. 컴퓨터 성능에 따라, CPU 코어 쓰레드 갯수의 2배정도를 설정해주면 되는거 같다.

내 컴퓨터는 intel core i5-3450 인데 찾아보니 쓰레드가 4개라고 나왔다. 그래서 난 -j8 옵션을 주고 실행시키겠다.


오래 걸리겠지..


make 걸고... 끝나면 정리를 계속 해야겠다....라고 생각했으나,




OpenJDK 7 이 필요하다고 한다. 



이렇게 알려줘놓고 OpenJDK 7이 필요하다니..


다시 돌아가서 JDK 설치를 다시 해야겠다.


이전 포스팅 수정하고 돌아왔다.


이제 빌드가 진행이 된다.



빌드 끝나고 다시 돌아오겠다..


약 2시간 후...




1시간 49분 40초만에 make 완료!


~/work/out 에 ramdisk.img, system.img, userdata.img 등 결과파일들이 있다.


후... 아직까지는 순조롭네.








Posted by 똑똑한 영장류

안드로이드 포팅 - 3



이어서 소스 다운로드를 하도록 하겠다.

안드로이드 소스는 구글이 관리하고 있으며, repo 를 이용해서 손쉽게 접근이 가능하단다.


Repo 설치

홈디렉토리 아래에 bin 디렉토리를 만들고 PATH에 추가해준다.

$ mkdir ~/bin

$ PATH=~/bin:$PATH


그리고, 다운로드!

$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo

$ chmod a+x ~/bin/repo





Repo client 초기화

1. 작업디렉토리 만들기

$ mkdir ~/work

$ cd ~/work


2. 이름이랑 이메일 주소로 git 설정하기

$ git config --global user.name "Your Name"

$ git config --global user.email "you@example.com"


3.작업디렉토리 초기화 하기

master 체크아웃 하려면 아래처럼 하면 되는데,

$ repo init -u https://android.googlesource.com/platform/manifest


나는 마시멜로가 필요하니까, 브랜치를 지정해서 아래처럼 해야된단다.

$ repo init -u https://android.googlesource.com/platform/manifest -b android-6.0.1_r22


-b 뒤에 오는 android-6.0.1_r22 는 http://source.android.com/source/build-numbers.html#source-code-tags-and-builds 에서 확인할 수 있는데, 마시멜로 중에 가장 높은 버전을 선택했다.


실행시키니까 빠르게 뭔가 지나가고 아래처럼 끝이 난다.



빠르게 지나가는 중에, 뭔가 에러 메세지를 본 거 같아 다시 실행시켜봤는데, 별말이 없다. 터미널 버퍼를 더 늘여야겠다. 지나간거 보려니 버퍼에 남아있지가 않았다.




~/work 디렉토리에 .repo 디렉토리가 생긴 걸 보니, 잘 된거겠지...



이제 다운로드!

work 디렉토리에서 아래처럼 입력한다.

$ repo sync





복잡하게 많이 지나간다~~~




오래 걸린다~~ 1시간쯤 지나고 나니 완료가 됐다.




work 디렉토리에 많이도 생겼다. 용량은 41기가 정도된다.


소스를 다운받았으니, 빌드를 해 봐야겠네.

빌드는 다음 포스팅에서 정리해야겠다.






Posted by 똑똑한 영장류

안드로이드 포팅 - 2


http://source.android.com/source/initializing.html


우분투 14.04.4 데스크탑 64비트를 설치하고 돌아왔다.

이제 위 링크에서 설명하고 있는대로 하나씩 개발환경을 꾸려보겠다.


1. 브랜치 선택하기

오픈소스로 개발되고 있는 안드로이드 AOSP 는 깃으로 관리되고 있고, 각각의 버전들은 별도의 브랜치라는 깃 개념으로 구분할 수 있다.

AOSP 라는 큰 줄기가 쭈~~욱 진행되어 가고 있고, 의미있는 개별 버전들은 그 큰 줄기에서 가지치고 나온 것들이라 보면 되겠다.


난 이미 6.0 마시멜로를 선택했다.


2. 리눅스 개발 환경 꾸리기

맥이 아닌 리눅스에서 개발하기로 결정했으니, 리눅스 개발 환경 관련 글을 따라간다.

리눅스는 우분투 14.04.4 64비트 데스크탑 으로 설치를 했다.


JDK 설치

깨끗한 우분투에 JDK 를 설치하자.


Oracle Java JDK 7 설치하고 빌드를 시도했더니 OpenJDK 7이 필요하다고 해서 OpenJDK 7을 설치했다.


설치는 아주 쉽다.


$ sudo apt-get install openjdk-7-jdk





OpenJDK 7 설치완료. 내가 설치했던 Oracle Java 를 제치고 0순위가 되어있다.


그 외 필요한 패키지 설치

우분투 14.04 에서는 아래처럼 하라고 한다. 터미널에 입력!


$ sudo apt-get install git-core gnupg flex bison gperf build-essential \

  zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 \

  lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache \

  libgl1-mesa-dev libxml2-utils xsltproc unzip






y 입력해줘야겠지..




설치가 금방 끝이 난다.


USB 접근 설정

우분투에서 기본적으로는 일반 유저가 USB에 직접 접근이 허용되지 않는데, 이걸 가능하게 해 줘야한단다. 디바이스 테스트할 때 필요한 일인듯 하다.


root 권한으로 아래처럼 입력해서 /etc/udev/rules.d/51-android.rules 를 만들어주면 된다고 한다. <username> 부분은 내 리눅스 계정 넣으면 될거 같다.


$ wget -S -O - http://source.android.com/source/51-android.rules | sed "s/<username>/$USER/" | sudo tee >/dev/null /etc/udev/rules.d/51-android.rules; sudo udevadm control --reload-rules






/etc/udev/rules.d/ 안에 보니, 51-android.rules 가 생겼다.





별도의 결과물 디렉토리 사용하기

기본적으로 빌드 결과물은 소스 디렉토리 아래에 /out 이라는 디렉토리에 저장된다는데, 결과물 저장할 디렉토리를 다른 속도 빠른 디스크에 설정해놓으면 빌드 성능 향상이 있다고 한다. 필요하면 OUT_DIR_COMMON_BASE 라는 환경변수에다가 디렉토리 위치 잡아주면 된단다. 난 다른 디스크 없으니, 그냥 간다....


export OUT_DIR_COMMON_BASE=<path-to-your-out-directory>


여기까지 개발 환경 꾸리기가 끝났다. 개발환경이라기 보다 빌드환경이라는 말이 더 맞겠다..싶다..


그 뒤 글에 ccache 를 이용해서 빌드할때 속도 향상을 꽤 할 수 있다는데, 하드 용량 많이 차지하는거 같아..이것도 패스한다.


이제 다음 단계는 소스를 다운로드 받는 부분이다.

다음 단계니까, 다음 포스팅에....






Posted by 똑똑한 영장류

안드로이드 포팅 - 1


안드로이드 플랫폼

오늘부터 기록할 내용은 '안드로이드 포팅'에 관한 내용이다.

안드로이드 스마트폰용 앱을 만드는 것에 관한 내용이 아니라, 운영체제로서의 안드로이드에 관한 것이다.

운영체재로서의 안드로이드를 다른 말로 '안드로이드 플랫폼'이라고도 한다.



Android Framework ( Applications 가 앱이니까, 그 아래 모두 들고 파야... )


(주)마이크로비젼에서 판매하는 MV V210 이라는 개발보드를 가지고 있다.

삼성에서 생산하는 CPU, S5PV210 을 사용하고 있으며 512MB RAM, 256MB NAND Flash 가 Main Board를 구성하고 있다.

MV V210은 처음에 안드로이드 버전 2.2 '프로요'가 이식되어 출시되었고, 이후 버전 4.0 '아이스크림 샌드위치(ICS)' 이식을 지원 해줬다.

현재 최신의 안드로이드 버전이 6.0 '마시멜로'니까 한참 철지난 버전되시겠다.


ICS 이식은 제공해준 매뉴얼대로하면 별 무리 없이 할 수 있다. 그러나...

이 MV V210 을 참고로 개발하고 있는 단말기에 올려야하는 앱 중 하나가, 버전 4.4 킷캣 이상에서 정상 동작한다고 해서, 킷캣 이상의 안드로이드를 포팅해야하는 상황이 발생했다.


해 보는 수 밖에...


MV V210, 마시멜로 포팅 결정!

킷캣을 이식할까? 아니면, 기왕 하는 김에 마시멜로를 이식할까? 고민이 되는데.

주변 장치 이식은 잠시 접어두고, 메인보드 사양에 이식이 가능은 할까?

S5PV210 에는 안되요. 라던가, 메모리 512MB에는 안 돌아갈걸요? 라던가... 잘 모르겠으므로... 

우선 포팅 절차를 익힌다는 생각으로 마시멜로로 시도해보기로 했다.


안드로이드 본부, http://source.android.com 를 들고 파야할 운명을 맞이했다.


개발자의 숙명, 개발 환경 꾸리기

http://source.android.com/source/requirements.html 에 가서 개발환경 꾸리는 방법을 먼저 살펴봤다.


하드웨어 요구사항

- 진져브레드(2.3.x) 이상은 64비트 환경이 필요함

- checkout 에 최소 100기가, 싱글 빌드에 150기가 디스크 공간이 필요함

- 가상머신에 리눅스 돌릴거면 메모리가 최소 16기가는 필요함


소프트웨어 요구사항(이라기보다 환경)

리눅스나 맥에서 빌드가 가능


리눅스의 경우

6.0 마시멜로 ~ AOSP master : Ubuntu 14.04

2.3.x ~ 5.x : Ubuntu 12.04

1.5 ~ 2.2.x : Ubuntu 10.04


JDK

AOSP master : OpenJDK 8

5.x ~ 6.0 : Java JDK 7 ?????

2.3.x ~ 4.4.x : Java JDK 6

1.5 ~ 2.2.x : Java JDK 5


(미래에서 왔습니다. 마시멜로 6.0.1 빌드를 시도했더니 OpenJDK 7이 필요하다고 빌드가 중단됩니다.)


Python 2.6 ~ 2.7

GNU Make 3.81 - 3.82

Git 1.7 이상


이 정도가 필요한 것들이다.

나는 리눅스에서 마시멜로를 빌드할 것이니, Ubuntu 14.04, Java JDK 7 OpenJDK 7이 필요하다. 

가상머신을 이용하기보다 노는 컴퓨터 하나 통채로 사용하기로 한다.


아래 링크에 개발 환경 꾸리는 과정이 자세히 설명되어있다.


Establishing a Build Environment

http://source.android.com/source/initializing.html


우선 노는 컴퓨터에 우분투부터 설치하고 계속해야겠다.

설치할 우분투는 Ubuntu 14.04.4 LTS 64-bit 이다. 다운받은 정확한 이미지 파일명은 ubuntu-14.04.4-desktop-amd64.iso 이다.










Posted by 똑똑한 영장류