9/29/2014

USB Cable로만 Linux 개발환경구축 (Exynos)

1. USB Cable로만 개발환경구축

Virtual Box를 개발 도중 , NFS 및 TFTBOOT BOOT 로 편하게 개발하고 싶은마음에,
아래 검색도중 아래의 문서들을 발견하여 다음과 같이 정리

ODROID(Embedded Linux 기반의 개발환경)

현재 ODROID의 경우 USB기반의 Network를 이용하여 개발환경을 구축이 가능하다.
이를 이용하기 위해서 Host Linux와 Device Linux의 설정을 알아보자.

  • 참고사항 (USB_NFS_HOWTO)
  http://www.aesop.or.kr/Board_Resources_General/36144
  http://www.aesop.or.kr/Board_Resources_General/36136
  http://www.aesop.or.kr/Board_Documents_Linux_Kernel/35302
  http://elinux.org/Mount_BeagleBoard_Root_Filesystem_over_NFS_via_USB
  http://com.odroid.com/sigong/nf_board/nboard_view.php?brd_id=odroidpc&bid=1032
  http://callgm.tistory.com/36
  http://vaultmicro.blogspot.kr/2013/04/usb-network-protocol.html
  http://recursive-labs.com/blog/2012/06/15/beaglebone-archlinux-gettingstarted/
  https://sites.google.com/site/computewiththinking/odroid-u2/bootloader-u-boot-fusing


2. Uboot의 dnw명령 과 DNW Tool 

uboot에 dnw라는 명령어가 존재하며 보통 TFTP 대신 목적으로 사용한다
이는 현재 Exynos에서만 지원해주고 있는 것 같다.
원리는 Taget Device의 uboot에서 OTG의 Device Mode 동작이 되고 Host Linux와 통신한다.
이 때 uboot에서는 dnw 명령과 Host에서는 DNW Tool이 필요하다
현재 Odroid인 경우 smdk-usbdl를 이용하여 Exynos를 지원해주고 있다.

관련 Tool: Window 및 Linux 용이 존재.

2.1 Host Linux용 DNW Tool 설치

Host Linux에서 아래의 파일을 Download하고 아래와 같이 설치를 해주면

  • Linux-dltool.tar.gz Download 
  http://bumnux.tistory.com/m/4?category=306215


 $ sudo apt-get install libusb-dev
 $ sudo cp smdk-usbdl /usr/local/bin
 $ apt-get install libusb-0.1-4:i386   (for 64bit)

이제 HOST Linux에서 smdk-usbdl를 이용하여 이제 uboot로 전송가능하다

2.2  UBOOT의 DNW 개발환경설정 

  • Target Device에서 UBOOT dnw명령 확인 
Serial 연결 후,  Reset 한 후, Uboot로 진입 한 후 dnw 명령 실행.
Host에서  System MCU SEC S3C6400X Test B/D USB를 인식 가능하며 아래의 Virtual Box에도 설정을 해주자.

 Exynos4412 # dnw 0xC0008000 


  • Host에서 Virtual Box  관리자 설정      
Main Virtual Box  관리자의  머신->설정->USB  추가

   System MCU SEC S3C6400X Test B/D [0100] 추가  (VID:04e8, PID: 1234)


  • Host에서 실행중 Virtual Box 확인
UBOOT에서 dnw 실행 후,
실행 중인  Virtual Box의 장치-> USB 장치 확인 및 앞에 체크 표시 확인
 
   System MCU SEC S3C6400X Test B/D [0100]


2.3 Uboot의 dnw TEST 진행


  • Target Device에서 UBOOT 명령 실행

아래와 같이 uboot에서 dnw 명령이 지원이 되어야 한다.

 Exynos4412 # dnw 0xC0008000 


  • Host Linux에서 Kernel Image Load 

아래와 같이 smdk-usbdl을 이용하여 Kernel Image를 Load 해보자

$ sudo smdk-usbdl -f arch/arm/boot/zImage -a 0xC0008000 
SMDK42XX,S3C64XX USB Download Tool
Version 0.20 (c) 2004,2005,2006 Ben Dooks 

S3C64XX Detected!
=> found device: bus 001, dev 005
=> loaded 2311724 bytes from arch/arm/boot/zImage
=> Downloading 2311734 bytes to 0x40008000
=> Data checksum 26c6
=> usb_bulk_write() returned 2311734

만약 Window에서 사용하고 싶다면, Window DNW Tool을 사용, 아래 참조 방법은 동일

  •  For Linux SMDK-USBDL
  http://www.fluff.org/ben/smdk/tools/
  http://dreamlog.tistory.com/165
  • for Window 7
  https://code.google.com/p/s3c6410kits/downloads/detail?name=dnw-for-
win7.rar&can=2&q=
  • Window
  http://en.pudn.com/downloads74/sourcecode/others/detail269293_en.html
  • How to install on Linux
  https://code.google.com/p/dnw-linux/ 


3. USB-CDC를 이용한 NFS 설정

이제 UBOOT에서 Kernel을 USB를 통해가져오면,  USB-CDC Gadget을 이용하여 Host Linux에서 USB Network를 이용한다


3.1 Target Device에서 Kernel설정

우선 아래와 같이 USB-CDC Gadget Driver를 추가하여, USB로 Network가 가능하도록 하자.

* KERNEL에서 RNDIS 및 USB Gadet Driver CDC추가와 NFS 지원 확인
  • 아래와 같이 Kernel 설정을 추가
$ make menuconfig
[ * ] File systems -> Network File System -> NFS client support 를 체크하고
NFS client support for NFS version 3 및 Root file system on NFS 를 선택

[ * ] Device Drivers -> USB support -> USB Gadget Support -> USB Gadget Drivers 
      (Ethernet Gadget (with CDC Ethernet support)) 로 변경 및 [*]  아래 RNDIS support (NEW) 확인 
* Built-in으로 변경                                                                               
  • 확인사항
$ vi .config
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_SMSC95XX=y
CONFIG_USB=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_ROOT_NFS=y


3.2 Host Linux에서 NFS Server 설정

기본으로 NFS가 설치가 안되어있기에, NFS관련 PKG 설치 및 설정


~$ sudo apt-get install nfs-kernel-server nfs-common portmap
~$ sudo vi /etc/exports

       /home/jhlee/qtwork/tmp1 *(rw,no_root_squash,no_all_squash,sync)
       /home/jhlee/qtwork/tmp2 *(rw,no_root_squash,no_all_squash,sync)

~$ sudo /etc/init.d/portmap restart
~$ sudo /etc/init.d/nfs-kernel-server restart
~$ sudo /etc/init.d/portmap restart


3.3 Host에서 Virtual Box 관리자 설정 

Device에서 Kernel의 USB Gadget인 USB-CDC의 RNDIS를 이미 설치했기때문에,
아래와 같이 이를 Host에서 인식하기 위해서 Virtual Box를 설정해준다.

Kernel zImage를 적용 후, 다시 Image를 writing 을 한 후 USB 필터 추가

  * WINDOW RNDIS/Ethernet Driver는 필요가 없기에  취소 
  * VirtualBox USB Driver 가 문제가 있다면 아래의 연결에 문제 발생 (재설치)

  • Virtual Box  관리자 설정 
Main Virtual Box  관리자의  머신->설정->USB  추가
         Linux 3.0.68 with s3c-udc RNDIS/Ethernet Gadget [0326] 추가

  • 실행중 Virtual Box 확인
UBOOT에서 dnw 실행 후, 실행 중인  Virtual Box의 장치-> USB 장치 확인 및 앞에 체크 표시 확인

         Linux 3.0.68 with s3c-udc RNDIS/Ethernet Gadget [0326]


3.4 Target Device에서 NFS 및 NETWORK TEST

  • NFS Mount TEST 
TARGET 일반 부팅 후 아래와 같이 NFS TEST

 mount -t nfs 192.168.1.1:/home/jhlee/qtwork/tmp2 /tmp 

그리고 lsusb로  연결확인

  • Network Test 
Guest OS Linux
$ ifconfig usb0 192.168.1.1

TARGET
# ifconfig usb0 192.168.1.2
# ping 192.168.1.1 

기본 동작 Exynos에서 동작은 하는데, TARGET에서 IP가 일정시간이 지나면 없어짐
네트워크문제 발생


4. Linux 개발환경설정 


4.1 Host Linux에서 udev 설정

Host Linux에서는 이제 udev 관련 rules들을 변경하여 Hotplug가 가능하도록 해주자.

1. dnw 관련 uboot에서 tftpboot 처럼 이용하여 kernel Image를 Device로 전송
2. Kernel은 USB-CDC의 Gadget을 이용하여 NFS를 Mount 한다

  • DNW Tool 설정 

$vi  /etc/udev/rules.d/80-dnw.rules
SUBSYSTEMS=="usb",  ATTRS{idVendor}=="04e8",  ATTRS{idProduct}=="1234", 
RUN+="/usr/local/bin/smdk-usbdl  -a  0xc0008000  -f /tftpboot/zImage"

  • NFS 관련설정

$ vi /etc/udev/rules.d/85-ifupdown.rules
ACTION=="remove",  RUN+="/sbin/start-stop-daemon  --start  --background  --pidfile 
/var/run/network/bogus  --startas  /sbin/ifdown  --  --allow  auto  $env{INTERFACE}"
LABEL="net_end"

KERNEL=="usb0"  RUN+="/etc/init.d/nfs-kernel-server  restart"
SUBSYSTEM=="usb",  ACTION=="add",  DRIVERS=="?*",  KERNEL=="usb0",  NAME="eth0" 

상위 파일 존재하고 이미 있다면, 아래부분만 추가 및 확인 ( NFS Restart )

$ vi /etc/udev/rules.d/85-ifupdown.rules
....
KERNEL=="usb0"  RUN+="/etc/init.d/nfs-kernel-server  restart"
SUBSYSTEM=="usb",  ACTION=="add",  DRIVERS=="?*",  KERNEL=="usb0",  NAME="eth0" 


  • USB0 Network 설정 및 network 재설정
Host Linux에서 이제 아래와 같이 usb0의 HOST Server 주소를 고정해준다.
usb0과 eth0을 NAT로 설정한다.

$ vi /etc/newtowrk/interfaces
auto lo
iface lo inet loopback

auto  usb0
iface  usb0  inet  static
address  192.168.1.1
netmask  255.255.255.0
broadcast  192.168.1.255 
up  /sbin/iptables  -A  POSTROUTING  -t  nat  -o  eth0  -j  MASQUERADE
up  echo  1  >  /proc/sys/net/ipv4/ip_forward
down  /sbin/iptables  -D  POSTROUTING  -t  nat  -o  eth0  -j  MASQUERADE
down  echo  0  >  /proc/sys/net/ipv4/ip_forward 


  • iptable 사용법

  http://web.mit.edu/rhel-doc/4/RH-DOCS/rhel-sg-ko-4/s1-firewall-ipt-fwd.html

4.2 Boot 환경설정 (Device)


수정 전 boot.scr
setenv initrd_high "0xffffffff"
setenv fdt_high "0xffffffff"
setenv fb_x_res "1280"
setenv fb_y_res "720"
setenv hdmi_phy_res "720"
setenv bootcmd "fatload mmc 0:1 0x40008000 zImage; fatload mmc 0:1 0x42000000 uInitrd; bootm 0x40008000 0x42000000"
setenv bootargs "console=tty1 console=ttySAC1,115200n8 fb_x_res=${fb_x_res} fb_y_res=${fb_y_res} hdmi_phy_res=${hdmi_phy_res} root=UUID=e139ce78-9841-40fe-8823-96a304a09859 rootwait ro mem=1023M"
boot


수정 후 boot.scr
setenv initrd_high "0xffffffff"
setenv fdt_high "0xffffffff"
setenv fb_x_res "1280"
setenv fb_y_res "720"
setenv hdmi_phy_res "720"
setenv serverip  "192.168.1.1"
setenv ipaddr  "192.168.1.2"
setenv gatewayip  "192.168.1.1"
setenv bootcmd "dnw  0xc0008000; fatload mmc 0:1 0x42000000 uInitrd; bootm 0xc0008000 0x42000000"
setenv bootargs "console=tty1 console=ttySAC1,115200n8 fb_x_res=${fb_x_res} fb_y_res=${fb_y_res} hdmi_phy_res=${hdmi_phy_res} root=/dev/nfs  rw  nfsroot=192.168.1.1:/home/jhlee/qtwork/tmp2 
ip=192.168.1.2:192.168.1.1:192.168.1.1:255.255.255.0::usb0:off init=/init  mem=1023M"
boot




setenv  serverip  192.168.1.1;setenv  ipaddr  192.168.1.2;setenv  gatewayip  192.168.1.1