레이블이 TS-7200인 게시물을 표시합니다. 모든 게시물 표시
레이블이 TS-7200인 게시물을 표시합니다. 모든 게시물 표시

2008년 11월 7일 금요일

Use USB wireless LAN Card

전에 PSP 인터넷 기능을 사용하기 위해서 노트북에 장착할 access point를 위해서 장만한 TW-54G 모델을 가지고 있었는데 혹시나 하는 마음에 한번 TS-7200 보드에 연결해 보았습니다,

Ref) http://www.eunicorn.co.kr/kimsboard7/productintro.php?main_file=product/lancard/tw54g.html

위에 적힌 사항대로라면 Ralink사의 RT2571WF 라는 칩을 사용합니다. rum(4) 를 참조하면 해당 디바이스를 지원합니다. 그리고 해당 디바이스가 evbarm을 지원하는것은 같은 계열의 evbarm 하드웨어에서 사용하는 것을 보면 사용이 가능할 거란 느낌이 들어서 우선 무턱대고 연결해봤습니다.

ugen0 at uhub0 port 1
ugen0: Ralink 802.11 bg WLAN, rev 2.00/0.01, addr 2
ugen0: at uhub0 port 1 (addr 2) disconnected
ugen0 detached
ugen0 at uhub0 port 1
ugen0: Ralink 802.11 bg WLAN, rev 2.00/0.01, addr 2

이런 메시지가 나오기는 하는데 사용은 불가능합니다.

커널 설정에 다음라인을 추가하고 컴파일합니다.

rum* at uhub? port ? # Ralink Technology RT2501/RT2601 802.11a/b/g

그런 다음 커널을 올려주고

# ifconfig rum0 192.168.1.10 netmask 0xffffff00 nwid "IPTIME"
하니

failed loadfirmware of file
에러메시지가 뜨네요. sysctl 결과를 보면

hw.firmware.path = /libdata/firmware:/usr/libdata/firmware:/usr/pkg/libdata/firmware:/usr/pkg/libdata

인데요, 커널 컴파일한 노트북에서 /usr/src/sys/dev/microcode/rum 에 보면 rum-rt2573 이란 파일이 있습니다. 이것을 /lib/data/firmware/rum 디렉토리를 만들어 주고 복사를 하고 나면 끝입니다.

ts-7200# dmesg
...
rum0 at uhub0 port 1
rum0: Ralink 802.11 bg WLAN, rev 2.00/0.01, addr 2
rum0: MAC/BBP RT2573 (rev 0x2573a), RF RT2528, address 00:0e:e8:e3:2b:39
rum0: 11b rates: 1Mbps 2Mbps 5.5Mbps 11Mbps
rum0: 11g rates: 1Mbps 2Mbps 5.5Mbps 11Mbps 6Mbps 9Mbps 12Mbps 18Mbps 24Mbps 36Mbps 48Mbps 54Mbps
....

ts-7200# ifconfig -a
epe0: flags=8863 mtu 1500
address: 00:d0:69:40:87:e4
media: Ethernet autoselect (100baseTX full-duplex)
status: active
inet 192.168.0.250 netmask 0xffffff00 broadcast 192.168.0.255
inet6 fe80::2d0:69ff:fe40:87e4%epe0 prefixlen 64 scopeid 0x1
rum0: flags=8802 mtu 1500
ssid ""
powersave off
address: 00:0e:e8:e3:2b:39
media: IEEE802.11 autoselect
status: no network
lo0: flags=8049 mtu 33192
inet 127.0.0.1 netmask 0xff000000
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3

ts-7200# ifconfig rum0 192.168.1.10 netmask 0xffffff00 nwid "IPTIME"

이제 default gateway 적절히 잡아주고(192.168.1.1 과 같은) ping 으로 외부 시스템을 걸어주면 정상적으로 됩니다.

ref) rum(4), route(8)

2008년 2월 22일 금요일

Use LCDProc in TS-Linux

Preface
-------
우선 NetBSD에 LCDProc 포팅하는 것이 잘되지 않아서 보드에 기본으로 설치되는 Linux(TS- Linux)를 이용해서 LCD 에 글이 표시되는 것을 해봤습니다. TS-Linux라는 게 별게 아니고 Debian Linux 기반으로 하여 업체에서 보드에 포팅한 Linux 정도라고 생각하시면 됩니다.

LCDProc 포팅
------------
LCDProc 에 대해 간략히 설명하자면 왠만한 Character LCD 제품에 대해 포팅하여 쓸수 있는 아주 좋은 프로그램입니다. Server/Client 구조로 되어 있어서 사용하기에도 좋고 사용자가 LCD의 데이터시트 내용까지 알 필요 없게끔 잘 만들었습니다. 이전에 마이컴수준에서 LCD를 사용해 보았는데 LCD에 글씨 출력하는 게 꽤 노가다를 필요로 합니다. 그런데 요 녀석은 그런 수고를 덜어줍니다.

자, 이제 본격적으로 포팅을 준비하겠습니다. 준비물은,
o LCDproc v0.5.0 Relase Version
from http://lcdproc.org
o TS-72xx 용 패치 파일
lcdproc-0.5.0_hd44780_ts7200.patch
from http://tech.groups.yahoo.com/group/ts-7000/files/ (kym_newbery Oct 1, 2007)
o Debian Linux Sarge 가 설치된 시스템
o Cross Compiler
from ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7200-linux/cross-toolchains/crosstool-linux-gcc-3.4.2-glibc-2.3.3.tar.bz2
NOTE. 지금까지 계속 crosstool-linux-gcc-3.3.4-glibc-2.3.2-0.28rc39.tar.bz2 를 사용해 왔었는데요 버전에서만 제대로 실행되는 것을 확인했습니다.

컴파일하는 것은 뭐 잘 아실거라 믿습니다. 패치는 다음 처럼 하시면 됩니다. (bash shell 기준)
% tar zxvf lcdproc-0.5.0.tar.gz
% cd lcdproc
copy lcdproc-0.5.0_hd44780_ts7200.patch in here!
% export CC=arm-ep9312-linux-gnu-gcc
% cd lcdproc-0.5.0
% patch -p1 < ../lcdproc-0.5.0_hd44780_ts7200.patch % ./configure --enable-drivers=hd44780 --host=arm-linux-gnu NOTE. Cross Compiler 이름에 CPU ep9312로 되어 있는데 TS-7200 보드의 ep9302 CPU에 사용해도 무방합니다. 컴파일이 끝나면 우리가 원하는 파일들이 생성됩니다. 리스트는, o lcdproc/lcdproc-0.5.0/server/LCDd LCD Server 프로그램 o lcdproc/lcdproc-0.5.0/server/drivers/hd44780.so LCD Server 실행에 필요한 라이브러리 o lcdproc/lcdproc-0.5.0/LCDd.conf LCD Server 설정 파일 LCD Client 프로그램은 lcdproc/lcdproc-0.5.0/clients 에 위치합니다. C로 된것도 있고 perl 스크립트로 되어 있는 것도 있는데 C로 된 것은 해당 디렉토리에서 make 하면 됩니다. 이제 준비물은 끝이 났습니다. LCDd, hd44780.so, LCDd.conf 를 TS-7200에 넘겨주면 되는데 넘기기 전에 LCDd.conf 를 다음 처럼 바꿉니다. % diff LCDd.conf ~/LCDd.conf 35,36c35,36 < driver="CFontzPacket" driver="hd44780"> #Driver=CFontzPacket
> Driver=hd44780
47c47,48
< bind="127.0.0.1"> #Bind=127.0.0.1
> Bind=0.0.0.0
79c80,81
< driverpath="server/drivers/"> #DriverPath=server/drivers/
> DriverPath=/usr/local/lib/lcdproc/
351c353,354
< connectiontype="4bit"> #ConnectionType=4bit
> ConnectionType=ts7200
373c376,377
< size="20x4"> #Size=20x4
> Size=24x2

즉, [server] 설정탭의 Driver와 DriverPath를 수정하고 [hd44780]탭의 ConnectionType, Size를 변경합니다. 전 24x2 LCD를 가지고 있어서 이렇게 변경했는데 해당 사이즈에 맞게 변경해주면 됩니다. (Suprise!)
NOTE. [server]탭의 Bind 값이 127.0.0.1 로 되어있는데 0.0.0.0 으로 하는것이 바람직한 것으로 보입니다.

TS-7200 보드에 준비물을 다음의 디렉토리 위치에 넣어둡니다.
o /etc/LCDd.conf
o /usr/local/bin/LCDd
o /usr/local/lib/lcdproc/hd44780.so

이제 LCD Server 프로그램 준비가 끝났습니다. LCD Client 프로그램도 스크립트가 아닌 C 프로그램을 컴파일했다면 /usr/local/bin 에 위치시키면 모두 완료.

LCDProc 시험
------------
o TS-7200에서 LCDd를 실행합니다. (-d 옵션을 주면 데몬으로 동작합니다. -h 참고)
o Cross Compile 한 Debian System에서 Client 프로그램을 실행합니다.
lcdproc/lcdproc-0.5.0/clients/examples/*.pl
여기서는 fortune.pl을 사용하겠습니다. 우선 fortune.pl에서 $HOST = "localhost"; 의 localhost를
TS-7200의 IP로 변경합니다.
% ./fortune.pl

이렇게 하면 Character LCD에 글자가 표시됩니다. 나머지 client 프로그램도 한번 시도해보시길...


Appendix A
----------
sourceforce.net 에 가면 lcdprocwin 이라는 프로젝트가 있습니다. LCD 서버 프로그램을 윈도우로 포팅한건데 소스 받아다 컴파일하면 각각 디렉토리에 Shared Library_debug.lib, lcdprocwin.exe 이 생성됩니다. 이것과 함께 소스 최상위에 있는 lcdprocwin.conf 파일을 하나의 디렉토리를 만들어서 그곳에 넣습니다. 설정파일은 크게 바꿀게 없고 단지 [server]탭의 Bind=0.0.0.0 로 해두시면 됩니다. Size 조정 해도 됩니다.

실행하면 다음과 같이 윈도우 보안 경고가 뜨는데 반드시 차단 해제 하셔야합니다. 나중에 다시 확인 버튼 선택하니 Client가 연결이 안됩니다.

실행하고 나면 다음과 같이 나옵니다.


도스 창에서 netstat -an 명령으로 확인해서 0.0.0.0:13666 으로 TCP Listen 상태가 되는지 확인 합니다.


먼저 번 Debian 시스템에 있는 Client 프로그램으로 HOST 값을 바꾸어서 연결하면 해당 글씨가 나옵니다.

Conclusion
----------
아직 KeyPad와 연관해서 사용하는 법은 아직 모르겠습니다. 보드에 서버와 클라이언트를 모두 띄워서 KeyPad를 가지고 조작할수 있으면 참 좋겠는데 전 여기까지만 성공했습니다. (기능은 됩니다)

LCDProc 의외로 사용가치가 높습니다. youtube에서 lcdproc으로 검색하면 꽤 멋진 동영상들 많이 나옵니다.

NetBSD에 LCDProc 포팅하는 건 아직 시작해보지는 않았는데 될거라 봅니다. 적절한 패치만 해서 컴파일만 잘 된다면 동일한 기능이 구현되리라 봅니다.

SBC 와 같은 emebedded system에 프로그래밍을 한다는게 참 어려운 작업인 걸 새삼스럽게 느낍니다. 프로그래밍만 아는 반토막 지식을 가지고는 해결해야 할 사항이 의외로 많더군요. 하드웨어마다 데이터시트도 구해서 읽어봐야하고, 전자공학 지식도 있어야 되고 컴퓨터 구조에 대해서도 잘 알아야하고... 산 너머 산입니다.

그래서, 요즘은 역으로 아니 처음부터 그렇게 했어야 했는데 전자공학 책 사서 보고 있습니다. 보드도 8bit 마이크로컨트롤러 구해다 보고 있습니다. 요 녀석 들여다보니 프로그램 입장에서 거의 똑같더군요. 하기야 8bit 이지만 RISC 칩이라서 뭐 큰 구조는 같은 셈이죠.

2007년 8월 13일 월요일

Serial COM 포트 사용하기

우선 기본적으로 내장되어 있는 Serial Port는 COM1, COM2가 존재하는데 COM1은 일반적으로 콘솔용으로 사용하고 COM2를 serial interface용으로 사용할 수 있습니다. 하드웨어 설명서에 나온대로 본다면,

+---+---+---+---+---+
TX-RX-NC NC TX-
+---+---+---+---+---+
TX+RXDTXDRX+GND
+-------------------+

그런데 기본적으로 COM2는 RXD, TXD, GND만 사용하도록 되어있습니다. RS-485지원할려면 조금 번거로운 작업을 거쳐야 됩니다. 세개의 선만을 연결해서 크로스 케이블을 만듭니다.

이제 테스트만 남았는데 그전에 시리얼 포트에 대한 디바이스 이름을 살펴보면,

in Linux, /dev/ttyAM0(/dev/console), /dev/ttyAM1
in NetBSD, /dev/epcom0(/dev/console), /dev/epcom1

NetBSD에서 디바이스 이름을 몰라서 조금해멨는데 http://www.netbsd.org/ports/evbarm/ 에 이렇게 되어있네요.

Support for the TS-7200 was written by Jesse Off

* On-CPU RS232 UARTs (2) (epcom)

ts-7200# dmesggrep epcom
epcom0 at epsoc0 addr 0x808c0000-0x808c0fff intr 52
epcom0: console
epcom1 at epsoc0 addr 0x808d0000-0x808d0fff intr 54

NetBSD를 설치했을때 epcom* 디바이스가 /dev 에 없어서 다음처럼 디바이스를 생성시켜줍니다.

ts-7200# sh /dev/MAKEDEV epcom0
ts-7200# sh /dev/MAKEDEV epcom1
ts-7200# ls -al /dev/epcom*
crw------- 1 uucp wheel 107, 0 Aug 13 16:05 /dev/epcom0
crw------- 1 uucp wheel 107, 1 Aug 13 16:05 /dev/epcom1
ts-7200# chmod g+rw /dev/epcom*
ts-7200# ls -al /dev/epcom*
crw-rw---- 1 uucp wheel 107, 0 Aug 13 16:05 /dev/epcom0
crw-rw---- 1 uucp wheel 107, 1 Aug 13 16:05 /dev/epcom1

사실상 필요한 것은 /dev/epcom1이고 적절히 권한을 부여합니다. 이 경우에는 user, group에 대해서 read,
write를 할수 있게 했습니다.

이제 테스트 수행만 남았는데 간단하게 tx, rx할수 있는 프로그램을 만들어서 테스트를 해보았습니다.

결과)
ESP-NS(linux) -> TS-7200(NetBSD) : 수신측 TS-7200 보드에서는 8byte, 5byte씩 나누어져서 read된다.
TS-7200(NetBSD) -> ESP-NS(linux) : 수신측 ESP-NS 보드에서 가끔 8byte, 5byte씩 나누어져서 read된다.

Q) 수신 버퍼가 8byte씩 읽어지는 것으로 보입니다. How to increase read buffer? 궁금합니다.

아래 소스

/*
* $Id: txrx.c,v 1.1 2007/08/13 08:04:40 pjy Exp $
*/
#include
#include
#include
#include

typedef struct
{
char speed[20]; /* 1200, 2400, 9600, 19200, 38400 */
char data_bit[20]; /* 5, 6, 7, 8 */
char parity[20]; /* NO, EVEN, ODD */
char stop_bit[20]; /* 1, 2 */
char control[20]; /* NO, Xon/Xoff */
} COMMSET_DS;

struct termios INIT_SETTING;

int setTTY(char*, char*);
int restoreTTY(int, const struct termios*);
int getCommSet(char*, COMMSET_DS*);
void prnCommSet(char*, char*, COMMSET_DS);
void getString(char*, const char*, int, char*);

int main(int argc, char *argv[])
{
int fd, len;
char buf[1024];

if(argc != 4) {
fprintf(stderr, "Usage: %s flag(1:tx, other:rx) device set\n", argv[0]);
fprintf(stderr, " flag: 1(tx), other(rx)\n");
fprintf(stderr, " device: /dev/ttyS03 ~ /dev/ttyS06(ESP-NS linux)\n");
fprintf(stderr, " device: /dev/ttyAM0 ~ /dev/ttyAM1(TS-7200 linux)\n");
fprintf(stderr, " device: /dev/epcom0 ~ /dev/epcom1(TS-7200 NetBSD)\n");
fprintf(stderr, " set: speed:data bit:parity:stop bit:control\n");
fprintf(stderr, " ex) in ESP-NS board(linux)--->\n");
fprintf(stderr, " tx-> %s 1 /dev/ttyS05 115200:8:NO:1:NO\n", argv[0]);
fprintf(stderr, " rx<- %s 2 /dev/ttyS05 115200:8:NO:1:NO\n", argv[0]); fprintf(stderr, " ex) in TS-7200 board(linux)--->\n");
fprintf(stderr, " tx-> %s 1 /dev/ttyAM1 115200:8:NO:1:NO\n", argv[0]);
fprintf(stderr, " rx<- %s 2 /dev/ttyAM1 115200:8:NO:1:NO\n", argv[0]); fprintf(stderr, " ex) in TS-7200 board(NetBSD)--->\n");
fprintf(stderr, " tx-> %s 1 /dev/epcom1 115200:8:NO:1:NO\n", argv[0]);
fprintf(stderr, " rx<- %s 2 /dev/epcom1 115200:8:NO:1:NO\n\n", argv[0]); return 1; } fd = setTTY(argv[2], argv[3]); if(fd < 0) { fprintf(stderr, "Can't set tty.\n"); return 1; } printf("%s Terminal attribute set OK!\n", argv[2]); if(atoi(argv[1]) == 1) { snprintf(buf, sizeof(buf), "Hello, NetBSD"); while(1) { len = write(fd, buf, strlen(buf)); if(len > 0)
printf("send %d bytes: %.*s\n", len, len, buf);
sleep(3);
}
}
else {
while(1) {
len = read(fd, buf, sizeof(buf));
if(len > 0)
printf("read %d bytes: %.*s\n", len, len, buf);
}
}

(void)restoreTTY(fd, &INIT_SETTING);
return 0;
}

int setTTY(char *device, char *comm)
{
struct termios new_settings;
COMMSET_DS commset;
int fd;

printf("---------- %s device set start ----------\n", device);
/********************************************************************
open device and get comm set value
*********************************************************************/
if((fd = open(device, O_RDWR | O_NOCTTY)) < 0) { fprintf(stderr, "Unable to open %s\n", device); return -1; } if(getCommSet(comm, &commset) != 1) { fprintf(stderr, "getCommSet(%s) error\n", comm); return -1; } prnCommSet(device, comm, commset); /******************************************************************** set terminal flag *********************************************************************/ tcgetattr(fd, &INIT_SETTING); new_settings = INIT_SETTING; new_settings.c_iflag &= ~ISTRIP; /* No Character strip */ new_settings.c_iflag |= IGNBRK; /* ignore Break */ #ifdef _TMP_ new_settings.c_iflag |= IGNCR; /* ignore CR */ #endif new_settings.c_iflag &= ~ICRNL; /* no map CR to NL on input */ new_settings.c_iflag &= ~IGNCR; /* enable CR */ new_settings.c_iflag &= ~INLCR; /* no map NL to CR on input */ new_settings.c_iflag |= IGNPAR; /* ignore chars with parity err */ if(!strcmp(commset.control, "NO")) { new_settings.c_iflag &= ~IXON; /* disable input flow control */ new_settings.c_iflag &= ~IXOFF; /* disable output flow control */ printf("NOTE. set flow control flag: disable\n"); } else if(!strcmp(commset.control, "Xon/Xoff")) { new_settings.c_iflag |= IXON; /* enable input flow control */ new_settings.c_iflag |= IXOFF; /* enable output flow control */ printf("NOTE. set flow control flag: Xon/Xoff\n"); } else { new_settings.c_iflag &= ~IXON; /* disable input flow control(default) */ new_settings.c_iflag &= ~IXOFF; /* disable output flow control(default) */ printf("NOTE. set flow control flag: disable(default)\n"); } if(!strcmp(commset.parity, "NO")) { new_settings.c_cflag &= ~PARENB;/* no parity */ printf("NOTE. set parity flag: no parity\n"); } else if(!strcmp(commset.parity, "EVEN")) { new_settings.c_cflag |= PARENB; /* enable parity */ new_settings.c_cflag &= ~PARODD;/* even parity */ printf("NOTE. set parity flag: even parity\n"); } else if(!strcmp(commset.parity, "ODD")) { new_settings.c_cflag |= PARENB; /* enable parity */ new_settings.c_cflag |= PARODD; /* odd parity */ printf("NOTE. set parity flag: odd parity\n"); } else { new_settings.c_cflag &= ~PARENB; /* no parity(default) */ printf("NOTE. set parity flag: no parity(default)\n"); } new_settings.c_cflag &= ~CSIZE; if(!strcmp(commset.data_bit, "5")) { new_settings.c_cflag |= CS5; /* set 5bits/char */ printf("NOTE. set data bit flag: 5bits/char\n"); } else if(!strcmp(commset.data_bit, "6")) { new_settings.c_cflag |= CS6; /* set 6bits/char */ printf("NOTE. set data bit flag: 6bits/char\n"); } else if(!strcmp(commset.data_bit, "7")) { new_settings.c_cflag |= CS7; /* set 7bits/char */ printf("NOTE. set data bit flag: 7bits/char\n"); } else if(!strcmp(commset.data_bit, "8")) { new_settings.c_cflag |= CS8; /* set 8bits/char */ printf("NOTE. set data bit flag: 8bits/char\n"); } else { new_settings.c_cflag |= CS8; /* set 8bits/char(default) */ printf("NOTE. set data bit flag: 8bits/char(default)\n"); } new_settings.c_cflag |= CLOCAL; /* ignore modem status lines */ new_settings.c_cflag |= CREAD; /* enable receiver */ if(!strcmp(commset.stop_bit, "1")) { new_settings.c_cflag &= ~CSTOPB; /* 1 stop bit */ printf("NOTE. set stop bit flag: 1 stop bit\n"); } else if(!strcmp(commset.stop_bit, "2")) { new_settings.c_cflag |= CSTOPB; /* 2 stop bit */ printf("NOTE. set stop bit flag: 2 stop bit\n"); } else { new_settings.c_cflag &= ~CSTOPB; /* 1 stop bit(default) */ printf("NOTE. set stop bit flag: 1 stop bit(default)\n"); } #ifdef _TMP_ new_settings.c_oflag &= ~OPOST; /* ouput processing off */ new_settings.c_oflag |= TAB3; /* expand tabs to space */ #endif new_settings.c_lflag &= ~ICANON; /* non-canonical mode */ new_settings.c_lflag &= ~ECHO; /* echo off */ new_settings.c_lflag &= ~ISIG; /* ignore signal from tty */ /*new_settings.c_lflag &= ~IEXTEN;*//* extended input processing off*/ /*new_settings.c_cc[VMIN] = 1; new_settings.c_cc[VTIME] = 0;*/ if(!strcmp(commset.speed, "1200")) { /* 1200 bps */ cfsetispeed(&new_settings, B1200); cfsetospeed(&new_settings, B1200); printf("NOTE. set speed flag: 1200 bps\n"); } else if(!strcmp(commset.speed, "2400")) { /* 2400 bps */ cfsetispeed(&new_settings, B2400); cfsetospeed(&new_settings, B2400); printf("NOTE. set speed flag: 2400 bps\n"); } else if(!strcmp(commset.speed, "4800")) { /* 4800 bps */ cfsetispeed(&new_settings, B4800); cfsetospeed(&new_settings, B4800); printf("NOTE. set speed flag: 4800 bps\n"); } else if(!strcmp(commset.speed, "9600")) { /* 9600 bps */ cfsetispeed(&new_settings, B9600); cfsetospeed(&new_settings, B9600); printf("NOTE. set speed flag: 9600 bps\n"); } else if(!strcmp(commset.speed, "19200")) { /* 19200 bps */ cfsetispeed(&new_settings, B19200); cfsetospeed(&new_settings, B19200); printf("NOTE. set speed flag: 19200 bps\n"); } else if(!strcmp(commset.speed, "38400")) { /* 38400 bps */ cfsetispeed(&new_settings, B38400); cfsetospeed(&new_settings, B38400); printf("NOTE. set speed flag: 38400 bps\n"); } else if(!strcmp(commset.speed, "57600")) { /* 57600 bps */ cfsetispeed(&new_settings, B57600); cfsetospeed(&new_settings, B57600); printf("NOTE. set speed flag: 57600 bps\n"); } else if(!strcmp(commset.speed, "115200")) { /* 115200 bps */ cfsetispeed(&new_settings, B115200); cfsetospeed(&new_settings, B115200); printf("NOTE. set speed flag: 115200 bps\n"); } else if(!strcmp(commset.speed, "230400")) { /* 230400 bps */ cfsetispeed(&new_settings, B230400); cfsetospeed(&new_settings, B230400); printf("NOTE. set speed flag: B230400 bps\n"); } else { /* 9600 bps(default) */ cfsetispeed(&new_settings, B9600); cfsetospeed(&new_settings, B9600); printf("NOTE. set speed flag: 9600(default) bps\n"); } /******************************************************************** set terminal type *********************************************************************/ if(tcsetattr(fd, TCSANOW, &new_settings) != 0) { fprintf(stderr, "Could not set attributes\n"); return -1; } printf("%s device has been initialized successfully.\n", device); return fd; } int restoreTTY(int fd, const struct termios *init_setting) { if(tcsetattr(fd, TCSANOW, init_setting) != 0) { fprintf(stderr, "Could not restore terminal attribute\n"); return -1; } return 1; } int getCommSet(char *str, COMMSET_DS *pCommSet) { char tmp[100]; getString(str, ":", 0, tmp); memcpy(pCommSet->speed, tmp, sizeof(pCommSet->speed));
/*printf("0(speed) -> %s, %s\n", tmp, pCommSet->speed);
printf("strlen() = %d\n", strlen(pCommSet->speed));*/
if(strlen(pCommSet->speed) < 1) return 0; getString(str, ":", 1, tmp); memcpy(pCommSet->data_bit, tmp, sizeof(pCommSet->data_bit));
/*printf("1(data_bit) -> %s, %s\n", tmp, pCommSet->data_bit);
printf("strlen() = %d\n", strlen(pCommSet->data_bit));*/
if(strlen(pCommSet->data_bit) < 1) return -1; getString(str, ":", 2, tmp); memcpy(pCommSet->parity, tmp, sizeof(pCommSet->parity));
/*printf("2(parity) -> %s, %s\n", tmp, pCommSet->parity);
printf("strlen() = %d\n", strlen(pCommSet->parity));*/
if(strlen(pCommSet->parity) < 1) return -2; getString(str, ":", 3, tmp); memcpy(pCommSet->stop_bit, tmp, sizeof(pCommSet->stop_bit));
/*printf("3(stop_bit) -> %s, %s\n", tmp, pCommSet->stop_bit);
printf("strlen() = %d\n", strlen(pCommSet->stop_bit));*/
if(strlen(pCommSet->stop_bit) < 1) return -3; getString(str, ":", 4, tmp); memcpy(pCommSet->control, tmp, sizeof(pCommSet->control));
/*printf("4(control) -> %s, %s\n", tmp, pCommSet->control);
printf("strlen() = %d\n", strlen(pCommSet->control));*/
if(strlen(pCommSet->control) < 1) return -4; return 1; } void prnCommSet(char *device, char *comm, COMMSET_DS CommSet) { printf("device : %s\n", device); printf("comm set: %s\n", comm); printf(" -> speed : %s\n", CommSet.speed);
printf(" -> data bit : %s\n", CommSet.data_bit);
printf(" -> parity : %s\n", CommSet.parity);
printf(" -> stop bit : %s\n", CommSet.stop_bit);
printf(" -> control : %s\n", CommSet.control);

return;
}

void getString(char *data, const char *delim, int order, char *str)
{
int k = 0;
char *token, ddd[1024];

strncpy(ddd, data, sizeof(ddd));
*str = 0x00;
token = strtok(ddd, delim);
while(token != NULL) {
if(k++ == order) { /* target string */
strcpy(str, token);
break;
}
token = strtok(NULL, delim); /* get next token */
}
}

/************************************************************************
End of Code
*************************************************************************/

2007년 6월 20일 수요일

pkgsrc 설치하기

third party 프로그램을 설치하기 위해서 CF Card에 한번 pkgsrc를 설치해보았습니다.
먼저 /usr/pkgsrc 디렉토리를 root 권한으로 생성한 다음 해당 group에 write권한을 준 다음,

% setenv CVSROOT anoncvs@anoncvs.NetBSD.org:/cvsroot
% setenv CVS_RSH ssh
% cd /usr
% cvs -q checkout -rpkgsrc-2007Q1 -P pkgsrc

설치된 pkgsrc의 크기는 200MB 조금 넘었습니다.
설치전,
% df -h
Filesystem Size Used Avail Capacity Mounted on
/dev/wd0a 1.8G 236M 1.4G 13% /
kernfs 1.0K 1.0K 0B 100% /kern
설치후,
% df -h
Filesystem Size Used Avail Capacity Mounted on
/dev/wd0a 1.8G 543M 1.1G 31% /
kernfs 1.0K 1.0K 0B 100% /kern

그렇다면 걸린 시간은?
무려 20시간 가까이 걸렸습니다. :-(

아무래도 NFS를 쓰는 편이 좋을 듯 싶네요. pkgsrc가 cross compile이 지원되는 날이 빨리 오길 기대하며...

2007년 6월 11일 월요일

SC Card mount

요즘 참 멋진 아이디어를 가진 주변장치가 많이 있더군요. SC Card인데 USB로 연결도 되는 제품도 있고, 가격도 저렴하고... 그래서 SC Card를 USB로 마운트를 해보았습니다.

먼저 USB slot에 SC Card를 연결했을때 TS-7200 Console에 다음과 같은 메시지가 나옵니다.

umass0 at uhub0 port 3 configuration 1 interface 0
umass0: Genesys USB Reader, rev 2.00/94.04, addr 2
umass0: using SCSI over Bulk-Only
scsibus0 at umass0: 2 targets, 1 lun per target
sd0 at scsibus0 target 0 lun 0: disk removable
sd0: fabricating a geometrysd0: 952 MB, 952 cyl, 64 head, 32 sec, 512 bytes/sect x 1950720 sectors

이와 같은 메시지가 나온다는 것은 제대로 연결되었다는 것이니깐 이젠 마운트하는 것만 남았네요. 먼저 disklabel 명령어로 어떻게 구성되었나 알아봅니다.

# disklabel sd0
# /dev/rsd0c:
type: SCSI
disk: mydisk
label: fictitious-MBR
flags:
bytes/sector: 512
sectors/track: 32
tracks/cylinder: 64
sectors/cylinder: 2048
cylinders: 952
total sectors: 1950720
rpm: 3600
interleave: 1
trackskew: 0
cylinderskew: 0headswitch: 0 # microsecond
strack-to-track seek: 0 # microseconds
drivedata: 0

8 partitions:

# size offset fstype [fsize bsize cpg/sgs]
c: 1950720 0 unused 0 0 # (Cyl. 0 - 952*)
e: 1950591 129 MSDOS # (Cyl. 0*- 952*)
disklabel: boot block size 0
disklabel: super block size 0

sd0e가 MSDOS 파일시스템으로 되어있는 것을 알수 있습니다. 이젠 mount명령으로 마운트 해야죠.

# mount -t msdos /dev/sd0e /mnt

그런데 TS-7200 Console 연결 화면에는 다음과 같은 에러메시지가 나오네요.

sd0(umass0:0:0:0): no door lock
sd0: fabricating a geometry

warning 메시지인가 봅니다. 쓰는데는 아무런 문제가 없네요. 마지막으로 unmount하고 USB slot에서 빼면 Console 연결화면에 다음과 같이 나옵니다.

umass0: at uhub0 port 3 (addr 2) disconnected
sd0 detached
scsibus0 detached
umass0 detached

뭐 별거 아니네요. CF Card대신 USB 메모리를 쓴다면 이런식으로 하면 될거 같네요. 속도 비교를 하자면? 둘다 느리긴 마찬가지입니다 :-(

2007년 6월 7일 목요일

button.c 분석

최종 소스는 ftp://ftp.embeddedarm.com/ts-arm-linux-cd/samples/ 에 위치합니다.
button.c는 입력을 받아 보드에 있는 2개의 led에 점멸을 표시합니다. 여기서는 단순히 LED 점멸만 하는 즉, 쓰기 기능을 하는 것으로 하겠습니다.
TS-7200 Hardware Manual(ts-7200-manual-rev2.2.pdf) 의 7.1 Status LEDs를 보면 Red와 Green 두가지의 LED가 board에 존재하는 것을 알수 있습니다. 사실 EP9302 CPU가 두개의 LED를 지원한다고 보는게 맞겠죠. 메모리위치는 0x8080_0020입니다. 소스코드를 살펴보기전에 다시 한번 GPIO에 대해서 개략적으로 살펴보죠. EP9301 User's Guide 의 Chapter 21에 GPIO 대해서 상세히 나옵니다. Instruction의 내용만 훓어보면 EP9302는 7개의 GPIO port를 지원합니다. 각 port는 동일하게 DR, DDR이 존재하고 interrupt 처리와 같은 기능을 위한 resister도 존재하는데 이기능을 지원하는 port를 EGPIO(Enhaunced GPIO) 라고 합니다. port는 A, B, C, D, E, F, G, H가 존재하고 EGPIO에 해당하는 것은 port A, port B, port F입니다. EP9302는 32bit이기 때문에 register크기도 모두 32bit이지만 실질적으로 사용하는 크기는 다음과 같습니다.
- port A: 8bits
- port B: 8bits
- port C: 1bit
- port E: 2bits
- port F: 3bits
- port G: 2bits
- port F: 4bits

우리가 지금부터 하고자하는 것은 port E에 해당합니다. 2bit가 유효한데 각각 Red, Green LED를 의미합니다. 문서에는 RDLED, GRLED라고 되어있네요. jp.c 와는 다르게 여기에서는 LED를 켜고 끄기 위해서는 쓰기 작업을 해야합니다. 따라서 DR 뿐만 아니라 DDR에 대해서도 작업을 수행해야 합니다. 쓰기 작업은 Read Modify Write (RMW) 방식으로 한다고 했는데 여기서는 Write 만 하고 확인은 직접 board의 LED를 보면서 확인할수 있습니다.

번지 번호 하나 외우고 들어가죠. 0x8084_0000 번지. 이 번지에서 부터 차례대로 GPIO의 resister가 매핑되어 있습니다. EP9301 User's Guide 에는 각 port 의 번지가 나와있는데 TS7200 Hardware 매뉴얼에는 해당 기능에 대한 이름을 열거해 두어서 훨씬 보기 편합니다. 우리의 관심사인 port E의 DR, DDR의 번지는 각각 0x8084_0020, 0x8084_0024 번지에 위치합니다. DR과 DDR의 각 비트위치는 서로 일치합니다. 즉, 0번째 bit가 RDLED의 값과 읽기/쓰기 모드를 나타내고 1번째 bit는 GRLED의 값과 읽기/쓰기 모드를 의미합니다. 지금까지 장황하게 설명했으니 실제 소스를 들여다 보죠.

line 17:
volatile unsigned int *PEDR, *PEDDR, *PBDR, *PBDDR, *GPIOBDB;
주요변수에 대해서 volatile 키워드를 사용했습니다. 그전에는 쓸 기회가 없었는데(사실 뭔지도 몰랐음^^) 이럴때 필요 하더군요. 간단히 말하자면 기계어로 컴파일 될때 최적화에 따른 부작용을 없애자는 거죠. 이 키워드를 쓰면 해당 변수가 들어간 코드에 대해서 컴파일러가 최적화 작업을 수행하지 않습니다. 따라서 소스 레벨에서는 문제 없다가 실행시에 문제가 발생하는 것을 사전에 막아줍니다. 여기서는 unsigned int *로 선언을 했습니다. 여기서는 PEDR, PEDDR만 쓸 예정인데 unsigned char *로 해도 사실은 무방합니다.

line 23:
start = mmap(0, getpagesize(), PROT_READPROT_WRITE, MAP_SHARED, fd, 0x80840000);
마지막 파라미터가 많이 보던 값이죠. GPIO에 접근할때는 이 번지로~~

line 26, line 27:
PEDR = (unsigned int *)(start + 0x20); // port e data
PEDDR = (unsigned int *)(start + 0x24); // port e direction register
start를 unsigned char * 로 선언해 둔 이유를 알겠죠. base 번지로 부터의 상대 주소에 접근할 때 요런식으로 많이 씁니다. 소스코드 보기에도 좋구요. 깔끔하잖아요. PEDR, PEDDR을 unsigned int *로 선언했으니 형변환하는 거 잊지말구요.

line 31:
*PEDDR = 0xff; // all output (just 2 bits)
가장 핵심적인 내용인데 LED에 대해서 쓰기 모드로 지정하겠다는 거죠. 나중에 DR에 값을 쓰면 그 값이 써지게 되어서 결과적으로 LED가 점멸하게 되는 것을 알수 있습니다.

line 35, 36, 37:
while (state & 0x01) { // wait until button goes low
state = *PBDR; // remember bit 0 is pulled up with 4.7k ohm
}
요기서는 위의 코드를 그냥 주석처리하세요. input을 기다리는 내용인데 하드웨어 꾸미기 귀찮아서...

line 42, 44:
*PEDR = 0xff;
*PEDR = 0x00;
위의 코드에서 DDR를 write 모드로 변경했기 때문에 DR에 값을 쓰면 그 결과가 바로 눈으로 나옵니다. 42번 라인을 정확하게 한다면 *PEDR = 0x03; 으로 하는게 맞을거 같은데 사실 32bit의 DR 내용중에서 하위 2bit를 제외하고는 사용하지 않는 내용이니 큰 문제가 되지 않습니다. for() 문과 중간에 sleep()을 주어서 반복하게 되니 차례대로 꺼졌다 켜졌다를 반복하는 것을 눈으로 볼수 있습니다. 간단하죠.

그렇다면 NetBSD 에서는 어떻게 확인할까요?
불행히도 빠져 있네요. 하지만 /usr/src/sys/arch/evbarm/tsarm/tspld.c 에 추가해서 sysctl에 표시되게 하는 방법으로 한다면 일관적이고 사용자 입장에서 편할것 같습니다. Jesse Off 가 별로 필요없을 거 같아 추가를 안했을도 있겠네요. 눈으로 보이는데 굳이 프로그램으로 확인할 필요도 없을 거 같구 굳이 그걸 프로그램에서 알 필요도 없지 않을까요.

알고 보면 상당히 간단합니다. 근데 키패드와 Text LCD는 조금 복잡하네요. scan 기법을 쓰다보니 하드웨어적인 사항도 잘 알아야 되고... 다음엔 이것에 대해서 한번 적어 볼까합니다.

jp.c 분석

최종 소스는 ftp://ftp.embeddedarm.com/ts-arm-linux-cd/samples/ 에 위치합니다.

jp.c는 보드의 좌측 하단에 위치한 6개의 점퍼 상태를 읽는 기능을 합니다.
TS-7200 Hardware Manual(ts-7200-manual-rev2.2.pdf) 의 7.2 Jumpers를 보면 각 점퍼에 대한 memory map 정보가 나옵니다. 그런데 JP1에 대한 map 정보는 없습니다.(이상하죠?) JP2~JP5는 0x1080_0000 에 위치하고 JP6는 0x2280_0000 에 위치합니다. 각 데이터는 1bit에 해당을 하네요. 참고로 DR, DDR이란 말이 나오는데 DR(Data Register)는 말그대로 Data가 위치하는 resister이고 DDR(Data Direction Resister)는 읽기/쓰기는 결정하는 resister입니다. 제가 처음 접했을때 resister는 CPU내에 위치한 resister만 생각했는데 여기서는 resister란 용어를 이렇게도 쓰더군요. 결론은 여기서는 DR만 잘 읽어서 처리하면 끝입니다.

8, 9 line:
#define TSSTATUS 0x10800000
#define TSJP6 0x22800000
이렇게 정의를 해두었습니다. 다른 소스도 마찬가지이겠지만 resister의 번지는 다 이런식으로 정의하고 시작합니다.

20 line:
int fd = open("/dev/mem", O_RDWRO_SYNC);
O_SYNC flag는 앞선 글에서 언급한바와 같이 cash에 따른 부작용을 없애기 위해 필요하고 O_RDWR는 read/write 모드로 파일을 open 하겠다는 뜻이겠죠. 굳이 여기서는 write 모드로 열 필요는 없습니다.

40, 41, 42 line:
page = TSSTATUS & 0xfffff000;
start = mmap(0, getpagesize(), PROT_READPROT_WRITE, MAP_SHARED, fd, page);

사실 여기서는 단순하게 다음처럼 하는것이 더 보기 좋을 것 같네요.
start = mmap(0, getpagesize(), PROT_READPROT_WRITE, MAP_SHARED, fd, TSSTATUS);
여기서 한가지 중요한 것은 우리가 bit단위의 data를 read할 예정이므로 start는 unsigned char* 로 선언되어야 한다는 것입니다. 즉, 읽고자 하는 데이터의 길이를 잘 판단해서 선언해야하는 것이죠. 여기서는 read만 하기 때문에 크게 문제가 되질 않지만 write를 할때에는 자칫 큰 문제가 생길수가 있습니다.

43 line:
dat = (unsigned char *)(start + (TSSTATUS & 0xfff));
이것 역시 다음처럼 하는게 더 보기 좋습니다.
dat = start;

이후 소스는 & 연산자를 이용해서 해당 비트를 읽어서 표시하는 것이니깐 그리 어렵지 않게 이해가 될겁니다.

컴파일해서 TS7200 보드에 실행해보면 점퍼가 꽂아져 있는 곳에는 ON이라는 결과가 나올겁니다. 무지 간단하죠.
그렇다면 NetBSD에서는 어떻게 확인할까요?
sysctl 명령으로 알수 있습니다~ 다음 처럼요.
% sysctl -a
...
hw.tspld.jp1 = 0
hw.tspld.jp2 = 1
hw.tspld.jp3 = 1
hw.tspld.jp4 = 0
hw.tspld.jp5 = 0
hw.tspld.jp6 = 0
...

여기서는 jp1의 상태를 알수가 있네요^^ 소스를 PC의 /usr/src에 받아두었다면 /usr/src/sys/arch/evbarm/tsarm/tspld.c 에 점퍼설정에 대한 내용이 있습니다. linux의 jp.c에 비해서 조금 복잡해 보일지도 모르지만 사용하는 입장에서는 너무나 편리합니다.

accessing peripherals basics in ARM

ARM 프로세스는 주변장치에 접근하기 위해서는 memory mapped I/O 방식을 사용합니다.
x86계열과는 다르게 별도로 instruction이 존재하는 것이 아니라 주변 장치를 위해 필요한 모든 정보(register ...)들이 모두 메모리에 위치하게 됩니다. 이때 물리적 메모리(physical memory)를 논리적 메모리(logical memory)로 매핑해주는 MMU(Memory Management Unit) 의 기능이 OS가 부팅될때 활성화되므로 단지 우리는 해당하는 register가 메모리 어느 번지에 위치하는지 테이블만 보고 해당 작업을 해주면 끝입니다. 사실 Linux Driver를 만든다는 것이 따지고 보면 이런 작업을 좀더 쉽게 함수로 제공해 주는 것 정도라고 봐야겠죠. 하지만 모든 일이 그렇듯이 먼저 이런 일을 해 준 사람에게 고마워해야 할겁니다.
ARM에서는 주변장치라는 말 대신 GPIO(General Purpose Input/Output ) pin 이라는 말을 많이 합니다. 주변장치에 접근하는 하나의 방식이지만 현재는 거의 모든 주변장치에 대해서 GPIO 방식을 이용하는 것으로 보입니다. 하드웨어적으로 하나의 pin으로 존재하는 것에 대해서 GPIO에서는 여러가지 방식으로 접근을 합니다. 가장 기본적인 것이 해당 pin에서 데이터를 읽을 것인가 쓸 것인가(Read/Write)를 결정하는 register가 존재하고, 읽고 쓰는 실제 데이터가 위치하는 register가 존재합니다. 쓰기 작업은 Read Modify Write (RMW) 방식으로 차례대로 진행되는 것이 대부분입니다. 즉, 출력용 주변 장치는 RMW 방식으로 접근하면 되는 것이죠. 그에 비해서 읽기 작업은 Read만 하면 되니 상대적으로 쉽습니다.
실제적으로 프로그래밍을 할때 주변장치에 접근하는 방식은 x86과는 사뭇 다릅니다. 앞에서 언급한바와 같이 별도의 instruction이 존재하는 것이 아니기 때문에 처음 접할때는 상당히 당혹스럽습니다. linux에서는 기본적으로 user level에서 접근할수 있는 방식은 /dev/mem을 직접 접근하는 방식입니다. 이 파일을 mmap() 함수를 이용해서 접근하는 방식이죠. 이후 작업은 대개 비트 연산과 같은 저레벨의 연산 작업을 수행하는 것이 전부입니다. 여기서 주의해야 할 사항은 다음과 같습니다.
- /dev/mem 을 열때 O_SYNC flag 사용할것(cash 기능을 없앱니다.)
- 주요 변수에 volatile 키워드를 사용합니다. 이 역시 cash 기능에 따른 부작용을 없애게 됩니다.
주변장치에 접근하는 방식을 이해하는 것은 소스 파일을 보는 것 만큼 쉬운 방법이 없을 겁니다. ftp://ftp.embeddedarm.com/ts-arm-linux-cd/samples/ 에 있는 파일들이 모두 주변 장치에 접근하는 소스 파일들입니다. 가장 쉬운 것이 jp.c 로 단지 Read 기능 만으로 점퍼의 상태를 알수 있습니다. button.c는 소스 중간에 위치한 while() 문만 주석처리하면 led 점멸을 볼 수 있습니다. 즉, Write 기능을 확인할수 있죠. 이 두개파일만 컴퓨터 구조론 공부할때 배운 내용과 잘 접목시켜서 원리를 이해한다면 x86에서는 느껴보지 못한 희열(?)을 느낄수 있을겁니다. RISC 라는 말이 나온것도 같은 맥락으로 생각하시면 되겠죠. 굳이 주변장치를 접근하는데 instruction을 이용할 필요는 없는 셈이죠. 나머지 소스파일도 잘 봐두면 도움이 됩니다. 요것들이 NetBSD에서는 Driver로 지원을 하거든요~~
여기까지 이해를 했으면 이제는 http://www.embeddedarm.com/downloads/Components/EP9301_User_Guide.pdf 의 EP9301 User's Guide(EP9032 User's Guide는 cirrus 측에서 제공하고 있지 않습니다.) 와 http://www.embeddedarm.com/Manuals/ts-7200-manual-rev2.2.pdf 의 TS-7200 Hardware 메뉴얼을 잘 읽어보는 일만 남았습니다. 두 문서에서 메모리맵에 대한 정보를 잘 비교하면 TS-7200에서 어떤 기능을 구현하고 있는지에 대해서 알수 있습니다.
- EP9301 User's Guide: 2.3.6 Internal Register Map
- TS-7200 Hardware Manual: appendix B Memory and Resister Map
Reference) http://www.simtec.co.uk/appnotes/AN0014/
ps) 너무 글을 두서없이 일기처럼 쓰다보니 정신이 없네요. 한번 예쁘게 PDF 파일로 한번 정리를 해봐야겠습니다.

2007년 5월 25일 금요일

키패드와 Text LCD를 로그인으로 사용하기

NetBSD의 gallery란에 Jesse Off 씨가 올린 그림인데 이 그림에 혹해서 사게 된 계기가 되기도 했지만 정말 될까 의심이 많이 되었습니다. 결론은? 된다고 보는게 맞다.


그런데 또 다른 그림을 보면 이렇게 쓰더군요.
그 유명한 toaster 기계. 그런데 잘 보면 입력은 키패드가 아닌 키보드를 연결해서 쓰고 있죠.
그래서 다음 그림을 또 다시 보게 되었죠.



해외 주문해서 살때 가이드가 되어준 그림이기도 한데(저거랑 똑같이 샀음^^) USB 키보드를 연결해 둔 것을 알 수 있습니다.
NetBSD의 놀라운 또한가지의 특이한 사실을 알게 되는 순간이었는데 NetBSD Guide 설명에서 글로만 보았던 Console driver의 놀라운 능력인 Virtual console 기능을 살리고 위와 같이 연결해 두면 키패드, 키보드 두 군데에서 입력받은 문자가 LCD에 출력이 됩니다. 로그인 해서 ls 등등의 명령어도 실행할수 있습니다. 전 여기서 쓰러지는 줄 알았습니다. 너무 기특해서...
CF Card에 설치한 NetBSD에 조금 설정 상태를 바꾸어 주어야하는데 전 다음과 같이 했습니다.
/etc/ttys 변경
--------------
ttyE0 "/usr/libexec/getty Pc" vt220 off secure
ttyE1 "/usr/libexec/getty Pc" vt220 off secure
ttyE2 "/usr/libexec/getty Pc" vt220 off secure
를 다음처럼 변경
ttyE0 "/usr/libexec/getty LCD" vt100 on secure
ttyE1 "/usr/libexec/getty LCD" vt100 on secure
ttyE2 "/usr/libexec/getty LCD" vt100 on secure

/etc/gettytab에 추가
--------------------
LCD:\
:ce:ck:np:im=%s/%m (%t)\r\n:

/etc/rc.conf에 추가
-------------------
wscons=YES

# sh /etc/rc.d/wscons;/etc/rc.d/ttys restart 하면 된다고 했는데 TS-7200 보드에서는 안되는거 같더군요. 재부팅하면 됩니다.
부팅 중이건 기동 중이건 상관없이 USB 키보드를 연결하면 다음과 비슷한 메시지가 console 창에 뜰겁니다. 아래는 logitec 무선 키보드/마우스를 연결한 상황입니다.
uhidev0 at uhub0 port 1 configuration 1 interface 0
uhidev0: Logitech USB Receiver, rev 1.10/38.10, addr 2, iclass 3/1
ukbd0 at uhidev0: 8 modifier keys, 6 key codes
wskbd1 at ukbd0 mux 1
wskbd1: connecting to wsdisplay0
uhidev1 at uhub0 port 1 configuration 1 interface 1
uhidev1: Logitech USB Receiver, rev 1.10/38.10, addr 2, iclass 3/1
uhidev1: 17 report ids
uhid0 at uhidev1 reportid 2: input=6, output=0, feature=0
uhid1 at uhidev1 reportid 3: input=4, output=0, feature=0
uhid2 at uhidev1 reportid 4: input=1, output=0, feature=0
uhid3 at uhidev1 reportid 16: input=6, output=6, feature=0
uhid4 at uhidev1 reportid 17: input=19, output=19, feature=0
ps) Text LCD가 조금만 커도 꽤 쓸만하겠다는 생각이 드네요. 80x24 짜리면 더 없이 좋겠지만... 그리고 저는 LCD에 /dev/ttyE0가 아닌 /dev/ttyE1 이 뜨더군요. 아직 배울게 많은가 봅니다.

Custom kernel 빌드하기

이 부분이 다른 어떤 OS에서도(같은 계열인 FreeBSD, OpenBSD 도 포함) 맛볼수 없는 어찌보면 디자인한 분의 경외심까지 일으키는 부분입니다. 보통 Linux에서 맨 처음 임베디드보드에 개발을 한다고 하면 Target machine인 임베디드보드는 단지 실행환경만 갖춘 컴퓨터이고 Host machine(보통 x86 계열의 PC)에 Cross compiler를 설치해서 소스를 컴파일해서 결과물로 나온 실행파일을 Target machine에 전송하여 실행이 제대로 되는지 확인하는 방법을 이용합니다. 뭐 사실 CF Card에 NetBSD를 설치했으니 compiler가 설치되어 있어서 직접 컴파일도 할수 있습니다. 참 좋은 세상이죠^^ 하지만 kernel build와 같이 많은 시간을 잡아먹는 작업을 Target machine에서 직접한다는 것은 조금은 바보 같은 짓일겁니다. 그런데 Linux에서 Cross compiler 설치하는 작업이 NetBSD에서는 없습니다. 엄밀하게는 존재하겠지만 이것 역시 compile 작업을 통해서 임시로 설치되게 됩니다. 즉, Cross compiler(NetBSD에서는 tool-chain 이라고 합니다.) 역시 컴파일 단계를 거치게 됩니다. 재미있죠. 어쩌면 이것 역시 바보같은 짓 아니냐 할지 모르지만 NetBSD가 얼마나 많은 플랫폼에 포팅이 되어있는지를 안다면 너무나 편리합니다. Linux라고 한다면 Target machine이 서로 다른 CPU를 가진 보드라고 한다면 아마도 Host machine을 각 임베디드 보드 개수만큼 마련해서 Cross compiler를 설치해 두어야 할겁니다. 하지만 NetBSD는 해당 Target machine에 해당하는 tool-chain을 미리컴파일 해두면 그것으로 족합니다. 내용이 너무 장황하게 다른쪽으로 빠지는 것 같아 이만 줄이고 실제 어떻게 진행되는지 출력내용을 가지고 한번 보겠습니다.

저는 편의상 vmware를 이용해서 NetBSD 3.1을 설치해서 Host machine으로 사용하고 있습니다.

1st. tool-chain 만들기
----------------------
netbsd: {91} ./build.sh -m evbarm tools
===> build.sh command: ./build.sh -m evbarm tools
===> build.sh started: Fri May 11 19:23:40 KST 2007
===> No nonexistent/bin/nbmake, needs building.
===> Bootstrapping nbmake
checking for sh... /bin/sh
checking for gcc... cc
checking for C compiler default output... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for executable suffix...
checking for object suffix... o
checking whether we are using the GNU C compiler... yes
checking whether cc accepts -g... yes
checking how to run the C preprocessor... cc -E
.........
===> Tools built to /usr/src/tooldir.NetBSD-3.1-i386
===> build.sh started: Fri May 11 19:23:40 KST 2007
===> build.sh ended: Fri May 11 19:46:06 KST 2007
===> Summary of results:
build.sh command: ./build.sh -m evbarm tools
build.sh started: Fri May 11 19:23:40 KST 2007
No nonexistent/bin/nbmake, needs building.
Bootstrapping nbmake
MACHINE: evbarm
MACHINE_ARCH: arm
TOOLDIR path: /usr/src/tooldir.NetBSD-3.1-i386
DESTDIR path: /usr/src/destdir.evbarm
RELEASEDIR path: /usr/src/releasedir
Created /usr/src/tooldir.NetBSD-3.1-i386/bin/nbmake
makewrapper: /usr/src/tooldir.NetBSD-3.1-i386/bin/nbmake-evbarm
Updated /usr/src/tooldir.NetBSD-3.1-i386/bin/nbmake-evbarm
Tools built to /usr/src/tooldir.NetBSD-3.1-i386
build.sh started: Fri May 11 19:23:40 KST 2007
build.sh ended: Fri May 11 19:46:06 KST 2007

시작, 끝나는 시간을 보면 알겠지만 조금 시간이 걸립니다. 뭐 이걸 가지고 딴지 건다면 뭐라 할말은 없습니다.

2nd. kernel 설정하기
---------------------
/usr/src/sys/arch/evbarm/conf 에 있는 걸 이용해서 설정 파일 만들기 여기서는 기본적으로 있는 TS7200_INSTALL 이용하겠습니다.

3rd. kernel 빌드
-----------------
netbsd: {92} ./build.sh -u -m evbarm kernel=TS7200_INSTALL
.......
===> Kernels built from TS7200_INSTALL:
/usr/src/sys/arch/evbarm/compile/obj/TS7200_INSTALL/netbsd
===> build.sh started: Fri May 11 20:03:09 KST 2007
===> build.sh ended: Fri May 11 20:11:19 KST 2007
===> Summary of results:
build.sh command: ./build.sh -u -m evbarm kernel=TS7200_INSTALL
build.sh started: Fri May 11 20:03:09 KST 2007
No nonexistent/bin/nbmake, needs building.
Bootstrapping nbmake
MACHINE: evbarm
MACHINE_ARCH: arm
TOOLDIR path: /usr/src/tooldir.NetBSD-3.1-i386
DESTDIR path: /usr/src/destdir.evbarm
RELEASEDIR path: /usr/src/releasedir
Created /usr/src/tooldir.NetBSD-3.1-i386/bin/nbmake
makewrapper: /usr/src/tooldir.NetBSD-3.1-i386/bin/nbmake-evbarm
Updated /usr/src/tooldir.NetBSD-3.1-i386/bin/nbmake-evbarm
Building kernel without building new tools
Building kernel: TS7200_INSTALL
Build directory: /usr/src/sys/arch/evbarm/compile/obj/TS7200_INSTALL
Kernels built from TS7200_INSTALL:
/usr/src/sys/arch/evbarm/compile/obj/TS7200_INSTALL/netbsd
build.sh started: Fri May 11 20:03:09 KST 2007

tool-chain 빌드시간보다는 적게 걸렸네요^^

4th. 빌드한 kernel 확인하기
-----------------------------
netbsd: {99} pwd
/usr/obj/sys/arch/evbarm/compile/TS7200_INSTALL
netbsd: {100} ls -al net*
-rwxr-xr-x 1 pjy users 6514722 May 11 20:11 netbsd
-rwxr-xr-x 1 pjy users 6514727 May 11 20:11 netbsd-epe0
-rwxr-xr-x 1 pjy users 6002992 May 11 20:11 netbsd-epe0.bin
-rwxr-xr-x 1 pjy users 6514726 May 11 20:11 netbsd-sd0
-rwxr-xr-x 1 pjy users 6002992 May 11 20:11 netbsd-sd0.bin
-rwxr-xr-x 1 pjy users 6514726 May 11 20:11 netbsd-wd0
-rwxr-xr-x 1 pjy users 6002992 May 11 20:11 netbsd-wd0.bin
-rwxr-xr-x 1 pjy users 6002992 May 11 20:11 netbsd.bin

Jesse Off 씨께서 요렇게 다양한 kernel build물이 나오게끔 설정파일을 만들어 두었습니다. 이건 앞에서의 설정 파일만 조금 보더라도 금방 이해가 갈 겁니다. 그런데 아직 .bin으로 끝나는 것과 아닌것과의 차이를 잘 모르겠네요. CF Card Mount 용 이미지는 netbsd-wd0.bin 이고 CF Card로의 NetBSD 설치에 사용되는 이미지는 netbsd.bin 입니다. 원하는 이미지를 이제 tftp 서버에 위치해두고 Redboot를 이용해서 Kernel을 로드하여 기동하면 다음과 비슷한 메시지가 나오게 됩니다.

RedBoot> go
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
The NetBSD Foundation, Inc. All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.

NetBSD 3.1 (TS7200_INSTALL) #0: Fri May 11 20:11:11 KST 2007
pjy@netbsd.myhome:/usr/obj/sys/arch/evbarm/compile/TS7200_INSTALL

로그인후 uname 명령으로도 알수 있구요.


마지막으로 한가지 더 이야기하자면 지금까지 언급한 kernel 빌드 단계가 굳이 임베디드를 위한 cross-compile 환경이 아닌 native 환경에서도 동일하다는 사실. 놀랍죠~ NetBSD의 "Clean Design" 이라는 문구가 단지 말이 아닌 실체로 느껴지는 순간이기도 하죠.

부트 메시지

커널이 다르고 설치된 하드웨어가 다르다면 당연히 부트메시지가 다르겠죠. 그래서 각각의 부트메시지를 모두 종합해 보았습니다.

Case: NetBSD를 CF Card에 설치하기 위해 netbsd-TS7200_INSTALL.bin 커널을 로드한 경우
-----------------------------------------------------------------------------------------------
>> TS-BOOTROM, Rev 1.08 - built 10:44:37, May 26 2006
>> Copyright (C) 2006, Technologic Systems
>> TS-7200: Rev E0 CPU, Rev C PLD, 32MB SDRAM

+Ethernet eth0: MAC address 00:d0:69:40:87:e4
IP: 192.168.0.50/255.255.255.0, Gateway: 192.168.0.1
Default server: 192.168.0.1

RedBoot(tm) bootstrap and debug environment [ROMRAM]
Non-certified release, version current-TS_5 - built 11:53:02, Jun 7 2006

Platform: TS-7200 Board (ARM920T) Rev A
Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.

RAM: 0x00000000-0x02000000, [0x00044f88-0x01fdd000] available
FLASH: 0x60000000 - 0x61000000, 128 blocks of 0x00020000 bytes each.
== Executing boot script in 0.100 seconds - enter ^C to abort
^C
RedBoot> load -v -r -b 0x00200000 -h 192.168.0.251 netbsd-TS7200_INSTALL.bin
Using default protocol (TFTP)
TFTP timed out 1/15
TFTP timed out 2/15
\
Raw file loaded 0x00200000-0x007c1a07, assumed entry at 0x00200000
RedBoot> go
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
The NetBSD Foundation, Inc. All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.

pmap_postinit: Allocated 35 static L1 descriptor tables
NetBSD 3.0_STABLE (TS7200_INSTALL) #1: Fri Jul 21 09:59:42 MST 2006
joff@construct:/home/joff/NetBSD-3/obj/home/joff/NetBSD-3/pristine-src/sys/arch/evbarm/compile/TS7200_INSTALL
total memory = 32768 KB
avail memory = 25188 KB
mainbus0 (root)
cpu0 at mainbus0: ARM920T rev 0 (ARM9TDMI core)
cpu0: DC enabled IC enabled WB enabled EABT
cpu0: 16KB/32B 64-way Instruction cache
cpu0: 16KB/32B 64-way write-back-locking-A Data cache
epsoc0 at mainbus0: Cirrus Logic EP93xx SoC rev E0
epsoc0: fclk 200.03 Mhz hclk 100.01 Mhz pclk 50.01 Mhz
ohci0 at epsoc0 addr 0x80020000-0x80020fff intr 56
epclk0 at epsoc0 addr 0x80810000-0x8081008f intr 35
epe0 at epsoc0 addr 0x80010000-0x8001ffff intr 39
epe0: MAC address 00:d0:69:40:87:e4
ukphy0 at epe0 phy 1: Generic IEEE 802.3u media interface
ukphy0: OUI 0x0010a1, model 0x0021, rev. 9
ukphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
epcom0 at epsoc0 addr 0x808c0000-0x808c0fff intr 52
epcom0: console
epcom1 at epsoc0 addr 0x808d0000-0x808d0fff intr 54
ohci0: OHCI version 1.0
usb0 at ohci0: USB revision 1.0
uhub0 at usb0
uhub0: Cirrus Logic OHCI root hub, class 9/0, rev 1.00/1.00, addr 1
uhub0: 3 ports with 3 removable, self powered
tspld0 at mainbus0: Technologic Systems TS-7200 rev C, features 0x0
tspld0: jumpers 0x3
wdc0 at tspld0
atabus0 at wdc0 channel 0
tslcd0 at tspld0
wsdisplay0 at tslcd0 kbdmux 1
wsmux1: connecting to wsdisplay0
tskp0 at tspld0: 4x4 matrix keypad, polling at 64 hz
wskbd0 at tskp0 mux 1
wskbd0: connecting to wsdisplay0
tssd0 at tspld0: TS-SDCORE SD flash card core
isa0 at tspld0: PC/104 expansion bus
md0: internal 3075 KB image area
wd0 at atabus0 drive 0:
wd0: drive supports 4-sector PIO transfers, LBA addressing
wd0: 1953 MB, 3970 cyl, 16 head, 63 sec, 512 bytes/sect x 4001760 sectors
wd0: drive supports PIO mode 4, DMA mode 2
boot device:
root on md0a dumps on md0b
root file system type: ffs
WARNING: CHECK AND RESET THE DATE!
erase ^?, werase ^W, kill ^U, intr ^C


Case: CF Card 마운트용 커널인 netbsd-wd0.bin-TS7200 를 로드한 경우
--------------------------------------------------------------------------
>> TS-BOOTROM, Rev 1.08 - built 10:44:37, May 26 2006
>> Copyright (C) 2006, Technologic Systems
>> TS-7200: Rev E0 CPU, Rev C PLD, 32MB SDRAM

+Ethernet eth0: MAC address 00:d0:69:40:87:e4
IP: 192.168.0.50/255.255.255.0, Gateway: 192.168.0.1
Default server: 192.168.0.1

RedBoot(tm) bootstrap and debug environment [ROMRAM]
Non-certified release, version current-TS_5 - built 11:53:02, Jun 7 2006

Platform: TS-7200 Board (ARM920T) Rev A
Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.

RAM: 0x00000000-0x02000000, [0x00044f88-0x01fdd000] available
FLASH: 0x60000000 - 0x61000000, 128 blocks of 0x00020000 bytes each.
== Executing boot script in 0.100 seconds - enter ^C to abort
^C
RedBoot> fconfig -l
Run script at boot: true
Boot script:
.. fis load vmlinux
.. exec -c "console=ttyAM0,115200 root=/dev/mtdblock1"

Boot script timeout (100ms resolution): 1
Use BOOTP for network configuration: false
Gateway IP address: 192.168.0.1
Local IP address: 192.168.0.50
Local IP address mask: 255.255.255.0
Default server IP address: 192.168.0.1
dns_ip: 192.168.0.1
Network hardware address [MAC]: 0x00:0xD0:0x69:0x40:0x87:0xE4
GDB connection port: 9000
Force console for special debug messages: false
Network debug at boot time: false
RedBoot> ip_address
IP: 192.168.0.50/255.255.255.0, Gateway: 192.168.0.1
Default server: 192.168.0.1
RedBoot> load -v -r -b 0x00200000 -h 192.168.0.251 -m tftp netbsd-wd0.bin-TS7200
/
Raw file loaded 0x00200000-0x004c0def, assumed entry at 0x00200000
RedBoot> go
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
The NetBSD Foundation, Inc. All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.

pmap_postinit: Allocated 35 static L1 descriptor tables
NetBSD 3.0_STABLE (TS7200) #1: Fri Jul 21 09:59:22 MST 2006
joff@construct:/home/joff/NetBSD-3/obj/home/joff/NetBSD-3/pristine-src/sys/arch/evbarm/compile/TS7200
total memory = 32768 KB
avail memory = 28196 KB
mainbus0 (root)
cpu0 at mainbus0: ARM920T rev 0 (ARM9TDMI core)
cpu0: DC enabled IC enabled WB enabled EABT
cpu0: 16KB/32B 64-way Instruction cache
cpu0: 16KB/32B 64-way write-back-locking-A Data cache
epsoc0 at mainbus0: Cirrus Logic EP93xx SoC rev E0
epsoc0: fclk 200.03 Mhz hclk 100.01 Mhz pclk 50.01 Mhz
ohci0 at epsoc0 addr 0x80020000-0x80020fff intr 56
epclk0 at epsoc0 addr 0x80810000-0x8081008f intr 35
epe0 at epsoc0 addr 0x80010000-0x8001ffff intr 39
epe0: MAC address 00:d0:69:40:87:e4
ukphy0 at epe0 phy 1: Generic IEEE 802.3u media interface
ukphy0: OUI 0x0010a1, model 0x0021, rev. 9
ukphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
epcom0 at epsoc0 addr 0x808c0000-0x808c0fff intr 52
epcom0: console
epcom1 at epsoc0 addr 0x808d0000-0x808d0fff intr 54
ohci0: OHCI version 1.0
usb0 at ohci0: USB revision 1.0
uhub0 at usb0
uhub0: Cirrus Logic OHCI root hub, class 9/0, rev 1.00/1.00, addr 1
uhub0: 3 ports with 3 removable, self powered
tspld0 at mainbus0: Technologic Systems TS-7200 rev C, features 0x0
tspld0: jumpers 0x3
wdc0 at tspld0
atabus0 at wdc0 channel 0
tslcd0 at tspld0
wsdisplay0 at tslcd0 kbdmux 1
wsmux1: connecting to wsdisplay0
tskp0 at tspld0: 4x4 matrix keypad, polling at 64 hz
wskbd0 at tskp0 mux 1
wskbd0: connecting to wsdisplay0
tssd0 at tspld0: TS-SDCORE SD flash card core
isa0 at tspld0: PC/104 expansion bus
wd0 at atabus0 drive 0:
wd0: drive supports 4-sector PIO transfers, LBA addressing
wd0: 1953 MB, 3970 cyl, 16 head, 63 sec, 512 bytes/sect x 4001760 sectors
wd0: drive supports PIO mode 4, DMA mode 2
boot device:
root on wd0a dumps on wd0b
WARNING: CHECK AND RESET THE DATE!
Sat Jul 22 02:55:44 KST 2006
swapctl: adding /dev/wd0b as swap device at priority 0
Checking for botched superblock upgrades: done.
Starting file system checks:
/dev/rwd0a: file system is clean; not checking
Setting tty flags.
Setting sysctl variables:
Starting network.
Hostname: ts-7200.
IPv6 mode: host
Configuring network interfaces: epe0.
add net default: gateway 192.168.0.1
Adding interface aliases:
Building databases...
Starting syslogd.
Checking for core dump...
savecore: can't find device 365/452205
Jul 22 02:55:53 ts-7200 savecore: can't find device 365/452205
Mounting all filesystems...
Clearing /tmp.
Creating a.out runtime link editor directory cache.
Checking quotas: done.
Setting securelevel: kern.securelevel: 0 -> 1
Starting virecover.
Starting local daemons:.
Updating motd.
Starting sendmail.
Starting inetd.
Starting cron.
Sat Jul 22 02:56:00 KST 2006

NetBSD/evbarm (ts-7200.) (console)

login:

Case: custom 커널을 로드한 경우
----------------------------------
>> TS-BOOTROM, Rev 1.08 - built 10:44:37, May 26 2006
>> Copyright (C) 2006, Technologic Systems
>> TS-7200: Rev E0 CPU, Rev C PLD, 32MB SDRAM

+Ethernet eth0: MAC address 00:d0:69:40:87:e4
IP: 192.168.0.50/255.255.255.0, Gateway: 192.168.0.1
Default server: 192.168.0.1

RedBoot(tm) bootstrap and debug environment [ROMRAM]
Non-certified release, version current-TS_5 - built 11:53:02, Jun 7 2006

Platform: TS-7200 Board (ARM920T) Rev A
Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.

RAM: 0x00000000-0x02000000, [0x00044f88-0x01fdd000] available
FLASH: 0x60000000 - 0x61000000, 128 blocks of 0x00020000 bytes each.
== Executing boot script in 0.100 seconds - enter ^C to abort
^C
RedBoot> load -v -r -b 0x00200000 -h 192.168.0.251 -m tftp netbsd-wd0.bin

Raw file loaded 0x00200000-0x007b992f, assumed entry at 0x00200000
RedBoot> go
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
The NetBSD Foundation, Inc. All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.

NetBSD 3.1 (TS7200_INSTALL) #0: Fri May 11 20:11:11 KST 2007
pjy@netbsd.myhome:/usr/obj/sys/arch/evbarm/compile/TS7200_INSTALL
total memory = 32768 KB
avail memory = 25220 KB
mainbus0 (root)
cpu0 at mainbus0: ARM920T rev 0 (ARM9TDMI core)
cpu0: DC enabled IC enabled WB enabled EABT
cpu0: 16KB/32B 64-way Instruction cache
cpu0: 16KB/32B 64-way write-back-locking-A Data cache
epsoc0 at mainbus0: Cirrus Logic EP93xx SoC rev E0
epsoc0: fclk 200.03 Mhz hclk 100.01 Mhz pclk 50.01 Mhz
ohci0 at epsoc0 addr 0x80020000-0x80020fff intr 56
epclk0 at epsoc0 addr 0x80810000-0x8081008f intr 35
epe0 at epsoc0 addr 0x80010000-0x8001ffff intr 39
epe0: MAC address 00:d0:69:40:87:e4
ukphy0 at epe0 phy 1: Generic IEEE 802.3u media interface
ukphy0: OUI 0x0010a1, model 0x0021, rev. 9
ukphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
epcom0 at epsoc0 addr 0x808c0000-0x808c0fff intr 52
epcom0: console
epcom1 at epsoc0 addr 0x808d0000-0x808d0fff intr 54
ohci0: OHCI version 1.0
usb0 at ohci0: USB revision 1.0
uhub0 at usb0
uhub0: Cirrus Logic OHCI root hub, class 9/0, rev 1.00/1.00, addr 1
uhub0: 3 ports with 3 removable, self powered
tspld0 at mainbus0: Technologic Systems TS-7200 rev C, features 0x0
tspld0: jumpers 0x3
isa0 at tspld0: PC/104 expansion bus
wdc0 at tspld0
atabus0 at wdc0 channel 0
tslcd0 at tspld0
wsdisplay0 at tslcd0 kbdmux 1
wsmux1: connecting to wsdisplay0
tskp0 at tspld0: 4x4 matrix keypad, polling at 64 hz
wskbd0 at tskp0 mux 1
wskbd0: connecting to wsdisplay0
md0: internal 3075 KB image area
wd0 at atabus0 drive 0:
wd0: drive supports 4-sector PIO transfers, LBA addressing
wd0: 1953 MB, 3970 cyl, 16 head, 63 sec, 512 bytes/sect x 4001760 sectors
wd0: drive supports PIO mode 4, DMA mode 2
boot device:
root on wd0a dumps on wd0b
WARNING: CHECK AND RESET THE DATE!
Sat Jul 22 10:16:13 KST 2006
swapctl: adding /dev/wd0b as swap device at priority 0
Checking for botched superblock upgrades: done.
Starting file system checks:
/dev/rwd0a: file system is clean; not checking
Setting tty flags.
Setting sysctl variables:
Starting network.
Hostname: ts-7200.
IPv6 mode: host
Configuring network interfaces: epe0.
add net default: gateway 192.168.0.1
Adding interface aliases:
Building databases...
wsdisplay0: screen 1 added (std_tslcd, vt100 emulation)
wsdisplay0: screen 2 added (std_tslcd, vt100 emulation)
wsdisplay0: screen 3 added (std_tslcd, vt100 emulation)
wsdisplay0: screen 4 added (std_tslcd, vt100 emulation)
Starting syslogd.
Checking for core dump...
savecore: can't find device 0/0
Jul 22 10:16:22 ts-7200 savecore: can't find device 0/0
Mounting all filesystems...
Clearing /tmp.
Creating a.out runtime link editor directory cache.
Checking quotas: done.
Setting securelevel: kern.securelevel: 0 -> 1
Starting virecover.
Starting local daemons:.
Updating motd.
Starting sendmail.
Starting inetd.
Starting cron.
Sat Jul 22 10:16:31 KST 2006

NetBSD/evbarm (ts-7200.) (console)

login:


ps) 참고로 저는 RTC를 위해서 TS5620을 같이 구입했는데 해당 하드웨어를 TS-7200에 설치하고 부팅하면 다음 메시지가 나옵니다.

>> TS-BOOTROM, Rev 1.08 - built 10:44:37, May 26 2006
>> Copyright (C) 2006, Technologic Systems
>> TS-7200: Rev E0 CPU, Rev C PLD, 32MB SDRAM
>> TS-5620: detected, battery OK, time ( 11:59:54, May 11 2007 )
....
tsrtc0 at tspld0: mc146818 compatible time-of-day clock

NetBSD 설치하기

Reference: http://www.embeddedarm.com/~joff/
ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-3.1/evbarm/INSTALL.html 도 설치 관련한 문서이지만 이것 때문에 처음에 상당한 혼란이 왔습니다. 그것뿐만 아니라 binary 설치 파일도 netbsd의 것과 ftp.embeddedarm.com 의 것이 또 달랐습니다. 두개 문서를 1주일동안 외우다시피 보고 또 그것가지고는 아직 설치 계획이 떠오르지 않아서 http://tech.groups.yahoo.com/group/ts-7000/ 의 메일링리스트를 뒤져서 겨우 방법을 알아냈습니다. 제가 원하고 발견한 방법은 다음과 같습니다.

1. 기설치된 flash memory내의 리눅스에 대해서는 어떠한 변경도 가하지 않는다.
2. CF Card를 설치해서 NetBSD 프로그램을 설치한다.
3. Kernel은 tftp로 다운로드 받아서 기동한다.

요약하자면, 물 건너온 이녀석에 대해서 기 설치된 Linux 커널을 손대지 않고 NetBSD를 쓰는게 목적이죠. 그럴수밖에 없는게 이미 설치된 Linux 커널이 정확히 어떤 것인지 알 수가 없었고 또 괜히 바꾸었다가 Linux로의 부팅도 되지 않을거 같은 불안한 마음 때문에 어쩔수가 없었습니다. 이런말 하기 좀 그렇지만 물어볼 사람도 없구요^^

설치 단계는 다음과 같습니다.

1. NetBSD를 CF Card에 설치하기 위한 kernel load
2. CF Card로의 부팅용 kernel을 tftp에서 다운로드 받아서 사용
3. Post installation

각 단계별로 자세하게 살펴보면,

단계 1) NetBSD를 CF Card에 설치하기 위한 kernel load
---------------------------------------------------------
1st. 자기 PC에 ftp://ftp.embeddedarm.com/evbarm/installation/instkernel/netbsd-TS7200_INSTALL.bin 를 다운로드 받습니다.
2nd. PC 에 tftp를 기동하고 준비합니다.
ex) My PC IP = 192.168.0.251
3rd. TS-7200 을 부팅하자마자 Ctrl-C를 눌러서 Redboot Command 모드로 진입한후 다음 명령어를 입력합니다. 참고로 TS-7200 디폴트 IP address는 192.168.0.50 입니다.

RedBoot> load -v -r -b 0x00200000 -h 192.168.0.251 netbsd-TS7200_INSTALL.bin
RedBoot> go

단계 2) CF Card로의 부팅용 kernel을 tftp에서 다운로드 받아서 사용
----------------------------------------------------------------------
단계 1)에서 CF Card로 NetBSD 프로그램을 설치하게 됩니다. 이부분은 다음에 한번 써야 될거 같네요. 일단 설치가 제대로 되었다고 가정하고 재부팅을 한다음에 다시 Ctrl-C를 눌러서 Redboot Command 모드로 진입한 다음 다음 명령어를 입력합니다. 그전에 우선 ftp://ftp.embeddedarm.com/evbarm/binary/kernel/netbsd-wd0.bin-TS7200.gz 를 미리 자기 PC에 다운로드 받습니다.

RedBoot> load -v -r -b 0x00200000 -h 192.168.0.251 -m tftp netbsd-wd0.bin-TS7200
RedBoot> go

단계 3) Post installation
-------------------------
이건 사실 키패드를 사지 않았다면 불필요한 사항인데 전 LCD랑 키패드도 같이 구입을 한 상태여서 LCD 관련 driver를 생성해야 합니다.

# /dev/MAKEDEV tslcd
# ls -al /dev/tsl*
crw-rw---- 1 root wheel 108, 0 Jul 22 06:19 tslcd0

이렇게 생성하는 이유는 단계1에서 설치한 NetBSD 프로그램내에 위의 driver가 설치되어 있지 않은 상태로 되어 있어서 그렇게 하면 되고 사용법은 메일링 리스트에 Jesse Off 가 올린 글에 따르면 다음과 같습니다.

Hitachi HD44780 LCD driver, /dev/tslcd0. You can just echo -n "foo" > /dev/tslcd0, or do more complex manipulations using ioctl()'s if you connect an LCD up to the LCD header.

TS-7200 사용수기를 시작하면서

우연한 기회에 FreeBSD를 접하게 되면서 기존에 어렵게 혼자서 Linux를 사용해오던 환경을 접고 BSD의 매력에 푹 빠져 집에서 쓰지 않는 386 PC에 FreeBSD를 설치해서 1년 가까이 지켜보면서 배우게 되었습니다. 그러다 OpenBSD, NetBSD라는게 또 있다는 것을 알게되고 이것도 역시 설치해서 쓰다가 최근에 NetBSD의 gallery란에 신기한 Single Board Computer를 보고 이젠 저것을 가지고 놀아볼 생각으로 해외 주문으로 사게되었죠. 관세까지 물어가면서... 그런데 써보면 써볼수록 참 재미있는 보드라는 생각이 듭니다. 크기도 작고 CF Card를 달면 완전 데스크탑 수준으로도 손색이 없는 것 같습니다. 보통 임베디드 시스템이라고 하면 Linux를 많이 생각하게 되는데 솔직히 성능만 놓고 본다면 훨씬 낫습니다. 하지만 전 목적이 NetBSD가 OS로 설치되어 운영되는 임베디드 보드를 가지고 놀 목적이기 때문에 그건 별로 문제가 되질 않습니다. 성능이라고 하는 것도 따지고 보면 부팅 시간이 얼마나 빠르냐 인데 그이후에는 오히려 환경이 NetBSD가 훨씬 유연하다는 느낌이 듭니다.

참고로 현재 TS-7200 을 지원하는 스펙은 다음과 같습니다.

- On-CPU RS232 UARTs (2) (epcom)
- On-CPU 10/100 Ethernet MAC (epe)
- CompactFlash socket (wdc)
- USB 1.1 ports (2) (ohci)
- Watchdog timer on CPLD (tspld)
- TMP124 high precision temperature sensor via sysctl
- 64Hz system clock from on-CPU timers (epclk)
- HD44780 2x24 text mode LCD (tslcd)
- 4x4 16 button matrix keypad (wskbd)
- TS-5620 battery backed RTC daughter-card (tsrtc)
- 1,2,4 port serial TS-SER daughter cards (com)
- Up to 4 10Mb TS-ETH10 daughter cards (tscs)
- Other devices inserted into the PC/104 (isa) expansion slot