DM368 보드에 대한 모든 것을 다룬다.
개발 환경 만들기
개발 환경을 만들기 위해 소스코드 및 툴체인 환경을 만들어야 한다.
#cs #cd svn #tar xf template_for_rdk41.tar #cd /home/wjkim/svn/template_for_rdk41/Source/dvsdk_ipnctools/ipnc_psp_03_21_00_04/ #./svn.sh // 커널과 부트로더 체크아웃 #cd /home/wjkim/svn/template_for_rdk41/Source/ipnc_rdk #./svn.sh // IP 카메라 소스코드 체크아웃 #cd /home/wjkim/svn/template_for_rdk41/Source/ipnc_rdk #vi Rules.make
빌드할 때, 필요한 경로를 맞춰주어야 한다. Rules.make 파일을 아래와 같이 수정한다.
참고로 크로스컴파일러의 경로는 '/home/sungho/opt/montavista/pro/devkit/arm/v5t_le/bin/arm_v5t_le-gcc' 이다.
MVTOOL_DIR := /home/sungho/opt/montavista/pro/devkit/arm/v5t_le // 툴 체인 지정(수정 안해도 됨) CAM_STUFF_DIR := /home/sungho/cam_stuff // 수정 안해도 됨 ... BASE_HOME := /home/$(shell whoami)/svn IPNC_INSTALL_DIR := $(BASE_HOME)/template_for_rdk41/Source // 수정할 것 DVSDK_INSTALL_DIR := $(BASE_HOME)/template_for_rdk41/Source // 수정할 것 HOME := $(BASE_HOME)/template_for_rdk41/Source/ipnc_rdk // 수정할 것 ... TARGET_FS := $(FILESYS_BASE_DIR)/filesys_ipcam // 파일 시스템 경로 지정
이제 빌드를 위한 모든 준비가 끝났다. 최종 펌웨어를 만들기 위해 필요한 바이너리를 하나씩 빌드해보겠다. 참고로 파일 시스템은 위의 설정대로 /home/wjkim/filesys_ipcam 에 디렉토리로 있어야 한다.
빌드하기
Kernel
#cd /home/wjkim/svn/template_for_rdk41/Source/dvsdk_ipnctools/ipnc_psp_03_21_00_04/ti-davinci #sh build.sh Sselect Target Model. 1)nmd2003p 2)ipxp_hub 3)Reserved 4)nmd2003p_drv_copy 5)ipxp_hub_drv_copy 6)menuconfig 7)Not Clean Build 8)Module Build 9)Reserved
각 번호에 대한 설명은 다음과 같다.
- clean & compile
- menuconfig
- compile
에러없이 빌드되었으면, arch/arm/boot 아래에 uImage 파일이 생성된다. 이 파일을 /tftpboot/wjkim 디렉토리로 복사한다.
#cp uImage /tftpboot/wjkim/uImage-wjkim
Bootloader
#cd /home/wjkim/svn/template_for_rdk41/Source/dvsdk_ipnctools/ipnc_psp_03_21_00_04/u-boot #make davinci_dm368_ipnc_config #make
에러없이 빌드되었으면, u-boot-1.3.4-dm368_ipnc.bin 파일이 생성된다.
Application
#cd /home/wjkim/svn/template_for_rdk41/Source/ipnc_rdk #make hostall #make wwwall #make avall #make dvsdk
최종 Firmware
앞서 빌드한 바이너리 파일들을 합쳐 하나의 펌웨어 바이너리 파일을 생성한다.
#/home/wjkim/svn/template_for_rdk41/Source/ipnc_rdk #make image #cd build #cat version MINOR="1081"
version 의 숫자(1081)는 빌드할 때마다 1씩 증가한다.
빌드 후에 5xx 로 시작하는 디렉토리가 보인다.
#cd 51110.2.1080.100 #ls 51110.2.1080.100.bin web-51110.2.1080.100.bin #cp 51110.2.1080.100.bin /tftpboot/wjkim/
두 개의 바이너리 파일이 있는데, 각각 사이즈가 다르다. 큰 것(51110.2.1080.100.bin)은 일반 부트로더를 통해 Write 하는 용도이고, 작은 것(web-51110.2.1080.100.bin)은 웹을 통해 펌웨어 업데이트를 하는 용도이다.
타겟보드 환경 설정
Nand 부팅
Nand 부팅을 위해 펌웨어 파일을 Nand 에 Write 하거나, NFS 부팅을 하기 위해서 부트로더의 환경 변수를 설정해야 한다.
U-Boot 1.3.4-svn (Mar 22 2013 - 14:17:04) DM368-IPNC-4.1.0 I2C: ready DRAM: 128 MB NAND: nand_init(0) ecc.mode(2) NAND device: Manufacturer ID: 0xec, Chip ID: 0xf1 (Samsung NAND 128MiB 3,3V 8-bit) 128 MiB This is not dual bootimg ------- BOOTING is PONG ------- In: serial Out: serial Err: serial ARM Clock :- 432MHz DDR Clock :- 340MHz Ethernet PHY: GENERIC @ 0x09, ID=0x00008201 Hit any key to stop autoboot: 0 ITX_IPNC :> ITX_IPNC :>printenv bootdelay=1 baudrate=115200 bootfile="uImage" sn_code=none kernal_nand=nboot 0x80700000 0 $ker_base; root_nfs=/dev/nfs nfsroot=$serverip:$rootpath,nolock mem=48M SN_VEN=$sn_code; kernal_tftp=tftpboot 0x80700000 $kernalpath; basic_cmd=setenv bootargs console=ttyS0,115200n8 noinitrd rw ip=$ipaddr:$serverip:$gatewayip:$netmask:IPCAM:eth0:off eth=$ethaddr 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 nohz=off highres=off clocksource=8 nfs_ktftp=setenv bootcmd $basic_cmd $root_nfs $kernal_tftp bootm 0x80700000 yaffs_knand=setenv bootcmd $basic_cmd $root_nand $kernal_nand bootm 0x80700000 yaffs_ktftp=setenv bootcmd $basic_cmd $root_nand $kernal_tftp bootm 0x80700000 root_nand=$fsys_mtd rw noinitrd rootfstype=yaffs2 mem=48M SN_VEN=$sn_code; bootargs=console=ttyS0,115200n8 noinitrd rw ip=$ipaddr:$serverip:$gatewayip:$netmask:IPCAM:eth0:off eth=$ethaddr 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 nohz=off highres=off clocksource=acpi_pm lpj=739320 rootpath=/home/wjkim/filesys_ipcam # 수정할 것 kernalpath=wjkim/uImage-wjkim # 수정할 것 ethaddr=00:11:5f:f0:33:10 # 수정할 것 filesize=53DB4D8 fileaddr=82000000 gatewayip=192.168.100.1 # 수정할 것 netmask=255.255.255.0 ipaddr=192.168.100.68 # 수정할 것 serverip=192.168.100.14 # 수정할 것 bootcmd=setenv bootargs console=ttyS0,115200n8 noinitrd rw ip=$ipaddr:$serverip:$gatewayip:$netmask:IPCAM:eth0:off eth=$ethaddr 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 nohz=off highres=off clocksource=ac0 fsys_mtd=root=/dev/mtdblock9 ker_base=0x3BC0000 stdin=serial stdout=serial stderr=serial ver=U-Boot 1.3.4-svn (Mar 22 2013 - 14:17:04) DM368-IPNC-4.1.0 Environment size: 2118/262140 bytes ITX_IPNC :
아래와 같이 명령어를 실행한다.
ITX_IPNC :>itx_fwup wjkim/51110.2.1080.100.bin
NFS 부팅
부팅 모드를 결정짓는 부트로더 명령은 아래와 같다.
ITX_IPNC :>run nfs_ktftp // 커널(NFS), 파일시스템(NFS) ITX_IPNC :>run yaffs_knand // 커널(NAND), 파일시스템(NAND) ITX_IPNC :>run yaffs_ktftp // 커널(NFS), 파일시스템(NAND) ITX_IPNC :>saveenv // 설정을 저장
타겟보드 설정
커널은 TFTP 를 통해 다운로드하고, 파일시스템은 NFS 를 통해 마운트하기 때문에, 사전에 네트워크 설정을 해주어야 한다.
설정값은 다음과 같다.
DM368 IPNC :>printenv bootdelay=4 baudrate=115200 bootfile="uImage" ethaddr=00:0c:0c:a0:02:15 setboot=setenv bootargs $(bootargs) bootcmd=nboot 0x80700000 0 0x500000;bootm 0x80700000 netmask=255.255.255.0 gatewayip=192.168.100.1 ipaddr=192.168.100.68 serverip=192.168.100.14 bootargs=console=ttyS0,115200n8 noinitrd earlyprintk rw ip=192.168.100.68:192.168.100.14:192.168.100.1:255.255.255.0:IPCAM:eth0:on eth=00:0c:0c:a0:02:15 rootdelay=3 root=/dev/nfs nfsroot=192.168.100.14:/home/wjkim/filesys_ipcam, nolock mem=48M cmemk.phys_start="0x83000000" cmemk.phys_end="0x88000000" cmemk.phys_startf stdin=serial # 뒷부분 짤림 stdout=serial stderr=serial ver=U-Boot 1.3.4 (Feb 13 2013 - 20:06:49) DM368-IPNC-4.1.0 Environment size: 794/131068 bytes DM368 IPNC :>
위 환경변수 중, 'bootargs' 의 경우, 뒷부분이 짤렸는데, 원래 값은 다음과 같다. 아래 내용을 복사하여 부트로더 프롬프트에 입력하면 된다.
setenv bootargs 'console=ttyS0,115200n8 noinitrd rw ip=192.168.100.68:192.168.100.14:192.168.100.1:255.255.255.0:IPCAM:eth0:on eth=00:0c:0c:a0:02:10 rootdelay=3 root=/dev/nfs nfsroot=192.168.100.14:/home/wjkim/filesys_ipcam, 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 lpj=739328 nohz=off highres=off'
커널 빌드
이제 보드 부팅을 위해서는 커널 이미지와 파일시스템을 준비해야 한다. 먼저 커널을 빌드해보겠다.
커널의 위치는 /home/wjkim/cam/rdk_41/Source/dvsdk_ipnctools/ipnc_psp_03_21_00_04/ti-davinci 이다.
커널 빌드를 완료했다면,
이제 부트로더 상에 다음을 입력한다.
tftpboot 0x80700000 wjkim/uImage_ipnc_dm368;nand erase 0x500000 0x400000;nand write 0x80700000 0x500000 0x400000;nboot 0x80700000 0 0x500000;bootm 0x80700000
만일 커널이미지 사이즈가 커서 복사가 안된다면, 사이즈를 늘려준다.
tftpboot 0x80700000 wjkim/uImage_ipnc_dm368;nand erase 0x500000 0x480000;nand write 0x80700000 0x500000 0x480000;nboot 0x80700000 0 0x500000;bootm 0x80700000
Nand 부팅
TI UBL Version: 1.50 Booting Catalog Boot Loader BootMode = NAND Starting NAND Copy... Valid magicnum, 0xA1ACED66, found in block 0x00000008. DONE Jumping to entry point at 0x81080000. DM368_IPNC_UBL_V04 U-Boot 1.3.4-svn1426 (Oct 30 2012 - 10:57:37) DM368-IPNC-1.0.0 I2C: ready DRAM: 128 MB NAND: nand_init(0) ecc.mode(2) NAND device: Manufacturer ID: 0xec, Chip ID: 0xf1 (Samsung NAND 128MiB 3,3V 8-bit) nand_scan_tail, 2892 buffers(80fe0008) res (0) 128 MiB delay_cnt = 499 ------- BOOTING is PING ------- In: serial Out: serial Err: serial ARM Clock :- 486MHz DDR Clock :- 360MHz Ethernet PHY: Dual Phy : GENERIC @ 0x09, ID=0x00008201 Hit any key to stop autoboot: 0 ITX_IPNC :> ITX_IPNC :> ITX_IPNC :> ITX_IPNC :> ITX_IPNC :> ITX_IPNC :> ITX_IPNC :> ITX_IPNC :> ITX_IPNC :> ITX_IPNC :> ITX_IPNC :>tftp 84000000 wjkim/uImage_ipnc_dm368 TFTP from server 192.168.10.129; our IP address is 192.168.10.160 Filename 'wjkim/uImage_ipnc_dm368'. Load address: 0x84000000 Loading: * Abort ITX_IPNC :>setenv serverip 192.168.1000.14 ITX_IPNC :>setenv serverip 192.168.100.14 ITX_IPNC :>set gatewayip 192.168.100.10 ITX_IPNC :>set gatewayip 192.168.100.1 ITX_IPNC :>tftp 84000000 wjkim/uImage_ipnc_dm368 TFTP from server 192.168.100.14; our IP address is 192.168.10.160; sending through gateway 192.168.100.1 Filename 'wjkim/uImage_ipnc_dm368'. Load address: 0x84000000 Loading: * Abort ITX_IPNC :>set ipaddr 192.168.100.68 ITX_IPNC :>tftp 84000000 wjkim/uImage_ipnc_dm368 TFTP from server 192.168.100.14; our IP address is 192.168.100.68 Filename 'wjkim/uImage_ipnc_dm368'. Load address: 0x84000000 Loading: ################################################################# ################################################################# ################################################################# ################################################################# ################################################### done Bytes transferred = 4562880 (459fc0 hex) ITX_IPNC :>nand erase 9bc0000 500000 NAND erase: device 0 offset 0x5c0000, size 0x500000 Erasing at 0xaa0000 erase_length[0x500000]-- 100% complete. OK ITX_IPNC :>nand write.i 84000000 5c0000 500000 ITX_IPNC :>nand write.i 84000000 9bc000 500000 NAND write: device 0 offset 0x5c0000, size 0x500000 5242880 bytes written: OK ITX_IPNC :> CTRL-A Z for help |115200 8N1 | NOR | Minicom 2.6.1 |
.ko 모듈 올리기
#cd /opt/ipnc/modules #insmod mmc_core.ko #insmod mmc_block.ko #insmod davinci_mmc.ko [ 96.585556] davinci_mmc davinci_mmc.0: Using DMA, 4-bit mode [ 96.595085] davinci_mmc davinci_mmc.1: Using DMA, 4-bit mode [ 96.785798] mmc1: new high speed SDIO card at address 0001 #insmod cfg80211.ko [ 151.626072] cfg80211: Calling CRDA to update world regulatory domain #insmod hostap.ko #insmod lib80211_crypt_ccmp.ko #insmod lib80211_crypt_tkip.ko #insmod lib80211_crypt_wep.ko #insmod mac80211.ko root@IPCAM:/opt/ipnc/modules# lsmod Module Size Used by mac80211 130885 0 lib80211_crypt_wep 1836 0 lib80211_crypt_tkip 6748 0 lib80211_crypt_ccmp 3712 0 hostap 83592 0 cfg80211 105508 1 mac80211 davinci_mmc 4124 0 mmc_block 6776 0 mmc_core 44624 2 davinci_mmc,mmc_block root@IPCAM:/opt/ipnc/modules#
반영해야 할 사항들
여기에 나온 수정 사항들은 향후 커널에 포함되어 커밋되어야 한다.
board-dm368-ipnc.c
static __init void dm368_evm_init(void) { evm_init_i2c(); setup_sensor(); davinci_serial_init(&uart_config); dm365evm_emac_configure(); davinci_setup_mmc(0, &dm365evm_mmc_config); davinci_setup_mmc(1, &dm365evm_mmc_config); // 추가 - SDIO Wi-Fi 사용 포트(mmcsd1 포트 초기화) /* maybe setup mmc1/etc ... _after_ mmc0 */ evm_init_emif(); ...
devices.c
void __init davinci_setup_mmc(int module, struct davinci_mmc_config *config) { struct platform_device *pdev = NULL; if (WARN_ON(cpu_is_davinci_dm646x())) return; /* REVISIT: update PINMUX, ARM_IRQMUX, and EDMA_EVTMUX here too; * for example if MMCSD1 is used for SDIO, maybe DAT2 is unused. * * FIXME dm6441 (no MMC/SD), dm357 (one), and dm335 (two) are * not handled right here ... */ switch (module) { case 1: if (cpu_is_davinci_dm355()) { /* REVISIT we may not need all these pins if e.g. this * is a hard-wired SDIO device... */ davinci_cfg_reg(DM355_SD1_CMD); davinci_cfg_reg(DM355_SD1_CLK); davinci_cfg_reg(DM355_SD1_DATA0); davinci_cfg_reg(DM355_SD1_DATA1); davinci_cfg_reg(DM355_SD1_DATA2); davinci_cfg_reg(DM355_SD1_DATA3); } else if (cpu_is_davinci_dm365()) { /* Configure pull down control */ void __iomem *pupdctl1 = DAVINCI_SYSMODULE_VIRT(0x7c); unsigned v; v = readl(pupdctl1); writel(v & ~0xfc0, pupdctl1); davinci_cfg_reg(DM355_SD1_CMD); // 추가 davinci_cfg_reg(DM355_SD1_CLK); // 추가 davinci_cfg_reg(DM355_SD1_DATA0); // 추가 davinci_cfg_reg(DM355_SD1_DATA1); // 추가 davinci_cfg_reg(DM355_SD1_DATA2); // 추가 davinci_cfg_reg(DM355_SD1_DATA3); // 추가 mmcsd1_resources[0].start = DM365_MMCSD1_BASE; mmcsd1_resources[0].end = DM365_MMCSD1_BASE + SZ_4K - 1; mmcsd1_resources[2].start = IRQ_DM365_SDIOINT1; } else ...
WiFI API 호출하기
웹이 완성되지 않은 상태에서 API 를 간이로 테스트 할 수 있는 방법이 있다.
http://<device ip>/cgi-bin/action.fcgi?api=get_setup.network.wifi_scan http://<device ip>/cgi-bin/action.fcgi?api=get_setup.network.wifi_status http://<device ip>/cgi-bin/action.fcgi?api=set_setup.network.wifi_conn&<parameter>=<value>[&<parameter>=<value>...] http://<device ip>/cgi-bin/action.fcgi?api=set_setup.network.wifi_conn&wifion=no&ssid=itx&auth=none&key=aaa&wep_encrypt=bbb&wep_input=ccc&wep_keynum=0&wep_key0=a&wep_key1=b&wep_key2=c&wep_key3=d http://10.10..10.1/cgi-bin/action.fcgi?api=set_setup.network.wifi_conn&wifion=yes&auth=wpa&ssid=IP-CAM&key=topsync123&wep_encrypt=wep64&wep_input=string&wep_keynum=1&wep_key0=ddd&wep_key1=fff&wep_key2=ggg&wep_key3=hhh
무선 카메라 및 지능형 카메라 빌드 옵션 설정
지능형 카메라(VA) 모델을 빌드할 때는 Rules.make 파일을 아래와 같이 수정한다.
#SYSTEM := EVM SYSTEM := IPNC # NOVA, ITXVA, SONEVA KIND_OF_VA := SONEVA #KIND_OF_VA := ITXVA #KIND_OF_VA := NOVA
무선 카메라 모델을 빌드할 때는 Rules.make 파일을 아래와 같이 수정한다.
#SYSTEM := EVM SYSTEM := IPNC # NOVA, ITXVA, SONEVA #KIND_OF_VA := SONEVA #KIND_OF_VA := ITXVA KIND_OF_VA := NOVA
feature_def.h 파일을 다음과 같이 수정한다.
#define WIFI_FEATURE // define 되어 있으면, WiFi 관련 루틴이 실행된다.