이 매뉴얼은 JK전자(JK Electronics) 에 의해서 번역, 수정, 작성 되었고 소유권 또한 JK전자(JK Electronics)의 것입니다. 소유권자의 허가를 받지 않고 무단으로 수정, 삭제하거나 배포 할 수 없습니다. 제품 구매 : http://www.toolparts.co.kr | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
S3C6410 Start Kit Linux Developer Guide | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
* Update history - 2011.1.13 : 초기 Release | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
S3C6410 Startkit 의 모든 예제와 컴파일 과정은 VMWare에 설치된 Fedora9 머신에서 실행 하였습니다. 다른 리눅스 환경에서는 테스트 되지 않았습니다. 폐도라 리눅스의 전체 설치 과정은 여기 Installation Fedora9 을 참조하시기 바랍니다. |
#include <stdio.h> int main(void) { printf("hello, FriendlyARM!\n"); } |
Step1 : Compile Hello, World
# cd /opt/FriendlyARM/mini6410/linux/examples/hello
# make
컴파일이 완료된 바이너리 파일의 정보를 볼 수 있습니다.
Step2 : Download Hello, World example to development board
개발보드에 컴파일된 예제를 다운로드 하는 방법에는 4가지 정도의 방법이 있습니다.
(1) FTP를 이용한 다운로드하는 방법
(2) USB 메모리 or SD 메모리 카드를 이용해서 타겟 보드에 마운트 후 복사하는 방법
(3) 시리얼 포트를 이용해서 다운로드 하는 방법
(4) NFS를 이용해서 바로 실행 하는 방법
(1) FTP를 이용한 다운로드하는 방법 (recommended)
아래와 같이 개발용 Linux PC에서 타겟 보드에 FTP로 접속후 다운로드 합니다.
다운로드가 완료되면 타겟 보드에서 다운로드한 파일에 실행 권한을 부여 합니다.
(2) USB 메모리 or SD 메모리 카드를 이용해서 타겟 보드에 마운트 후 복사하는 방법
PC에서 아래 명령을 이용해서 USB 메모리를 마운트 한다음 예제 파일을 USB메모리에 복사합니다.
# mount /dev/sda1 /mnt
# cp hello /mnt
# umount /mnt
USB 메모리를 타겟 개발보드에 연결 하면 자동으리 /udisk로 마운트가 되고 아래과 같은 명령으로 실행 해 볼 수 있습니다.
# cd /udisk
# ./hello
(3) 시리얼 포트를 이용해서 다운로드 하는 방법
시리얼을 통한 파일 다운로드 하는 방법은 리눅스 사용자 가이드 "1.2.4 시리얼 포트를 이용한 PC파일 전송" 을 참조하시기 바랍니다.
다운로드한 파일에 실행 권한을 부여 합니다.
# chmod +x hello
(4) NFS를 이용해서 바로 실행 하는 방법
"192.168.1.111" 는 NFS서버 PC의 IP 주소 입니다.
# mount -t nfs -o nolock192.168.1.111:/opt/FriendlyARM/mini6410/linux/rootfs_qtopia_qt4 /mnt
NFS마운트가 성공적으로 연결이 되면 /mnt 디렉토리에 NFS서버의 "opt/FriendlyARM/mini6410/linux/rootfs_qtopia_qt4" 디렉토리가 마운트 되어 접근 할 수 있습니다.
# cd /mnt
# ./hello
1.12.2 LED Test Program
드라이버 소스 파일 이름 | mini6410_leds.c |
Device Type | misc |
Device Name | /dev/leds |
소스 디렉토리 | /opt/FriendlyARM/mini6410/linux/examples/leds |
예제 이름 | led.c |
예제 실행 파일 이름 | led |
LED driver has been compiled into the default kernel, so can not be loaded using insmod. | |
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> int main(int argc, char **argv) { int on; int led_no; int fd; /* check led control of two parameters, if no parameter input is out. */ if (argc != 3 || sscanf(argv[1], "%d", &led_no) != 1 || sscanf(argv[2],"%d", &on) != 1 || on < 0 || on > 1 || led_no < 0 || led_no > 3) { fprintf(stderr, "Usage: leds led_no 0|1\n"); exit(1); } /* open /dev/ leds device file */ fd = open("/dev/leds0", 0); if (fd < 0) { fd = open("/dev/leds", 0); } if (fd < 0) { perror("open device leds"); exit(1); } /* the ioctl system call and input the parameter control led */ ioctl(fd, on, led_no); /* close the device handle */ close(fd); return 0; } |
컴파일하고 타겟보드에 다운로드 해서 실행하는 방법은 Hello, World 예제와 동일 합니다.
1.12.3 Button Test Program
드라이버 소스 디렉토리 | /opt/FriendlyARM/mini6410/linux/linux-2.6.36/drivers/char |
드라이버 소스 파일 이름 | Mini6410_buttons.c |
Device Type | misc |
Device Name | /dev/buttons |
소스 디렉토리 | /opt/FriendlyARM/mini6410/linux/examples/buttons |
예제 이름 | buttons_test.c |
예제 실행 파일 이름 | buttons |
Button driver has been compiled into the default kernel, so can not be loaded using insmod. | |
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/select.h> #include <sys/time.h> #include <errno.h> int main(void) { int buttons_fd; char buttons[6] = {'0', '0', '0', '0', '0', '0'}; buttons_fd = open("/dev/buttons", 0); if (buttons_fd < 0) { perror("open device buttons"); exit(1); } for (;;) { char current_buttons[6]; int count_of_changed_key; int i; if (read(buttons_fd, current_buttons, sizeof current_buttons) != sizeof current_buttons) { perror("read buttons:"); exit(1); } for (i = 0, count_of_changed_key = 0; i < sizeof buttons / sizeof buttons[0]; i++) { if (buttons[i] != current_buttons[i]) { buttons[i] = current_buttons[i]; printf("%skey %d is %s", count_of_changed_key? ", ": "", i+1, buttons[i] == '0' ? "up" : "down"); count_of_changed_key++; } } if (count_of_changed_key) { printf("\n"); } } close(buttons_fd); return 0; } |
1.12.4 PWM Buzzer Test Program
드라이버 소스 디렉토리 | /opt/FriendlyARM/mini6410/linux/linux-2.6.36/drivers/char |
드라이버 소스 파일 이름 | Mini6410_pwm.c |
Device Type | misc |
Device Name | /dev/pwm |
소스 디렉토리 | /opt/FriendlyARM/mini6410/linux/examples/pwm |
예제 이름 | pwm_test.c |
예제 실행 파일 이름 | Pwm_test |
PWM driver has been compiled into the default kernel, so can not be loaded using insmod. | |
#include <stdio.h> #include <termios.h> #include <unistd.h> #include <stdlib.h> #define PWM_IOCTL_SET_FREQ 1 #define PWM_IOCTL_STOP 2 #define ESC_KEY 0x1b static int getch(void) { struct termios oldt,newt; int ch; if (!isatty(STDIN_FILENO)) { fprintf(stderr, "this problem should be run at a terminal\n"); exit(1); } // save terminal setting if(tcgetattr(STDIN_FILENO, &oldt) < 0) { perror("save the terminal setting"); exit(1); } // set terminal as need newt = oldt; newt.c_lflag &= ~( ICANON | ECHO ); if(tcsetattr(STDIN_FILENO,TCSANOW, &newt) < 0) { perror("set terminal"); exit(1); } ch = getchar(); // restore termial setting if(tcsetattr(STDIN_FILENO,TCSANOW,&oldt) < 0) { perror("restore the termial setting"); exit(1); } return ch; } static int fd = -1; static void close_buzzer(void); static void open_buzzer(void) { fd = open("/dev/pwm", 0); if (fd < 0) { perror("open pwm_buzzer device"); exit(1); } // any function exit call will stop the buzzer atexit(close_buzzer); } static void close_buzzer(void) { if (fd >= 0) { ioctl(fd, PWM_IOCTL_STOP); close(fd); fd = -1; } } static void set_buzzer_freq(int freq) { // this IOCTL command is the key to set frequency int ret = ioctl(fd, PWM_IOCTL_SET_FREQ, freq); if(ret < 0) { perror("set the frequency of the buzzer"); exit(1); } } static void stop_buzzer(void) { int ret = ioctl(fd, PWM_IOCTL_STOP); if(ret < 0) { perror("stop the buzzer"); exit(1); } } int main(int argc, char **argv) { int freq = 1000 ; open_buzzer(); printf( "\nBUZZER TEST ( PWM Control )\n" ); printf( "Press +/- to increase/reduce the frequency of the BUZZER\n" ) ; printf( "Press 'ESC' key to Exit this program\n\n" ); while( 1 ) { int key; set_buzzer_freq(freq); printf( "\tFreq = %d\n", freq ); key = getch(); switch(key) { case '+': if( freq < 20000 ) freq += 10; break; case '-': if( freq > 11 ) freq -= 10 ; break; case ESC_KEY: case EOF: stop_buzzer(); exit(0); default: break; } } } |
1.12.5 I2C-EEPROM programming example
드라이버 소스 디렉토리 | /opt/FriendlyARM/mini6410/linux/linux-2.6.36/drivers/i2c/busses |
드라이버 소스 파일 이름 | I2c-s3c2410.c |
Device Type | Char device |
Device Name | /dev/i2c/0 |
소스 디렉토리 | /opt/FriendlyARM/mini6410/linux/examples/i2c |
예제 이름 | eeprog.c 24cXX.c |
예제 실행 파일 이름 | i2c |
PWM driver has been compiled into the default kernel, so can not be loaded using insmod. | |
#include <stdio.h> #include <fcntl.h> #include <getopt.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include "24cXX.h" #define usage_if(a) do { do_usage_if( a , __LINE__); } while(0); void do_usage_if(int b, int line) { const static char *eeprog_usage = "I2C-24C08(256 bytes) Read/Write Program, ONLY FOR TEST!\n" "FriendlyARM Computer Tech. 2009\n"; if(!b) return; fprintf(stderr, "%s\n[line %d]\n", eeprog_usage, line); exit(1); } #define die_if(a, msg) do { do_die_if( a , msg, __LINE__); } while(0); void do_die_if(int b, char* msg, int line) { if(!b) return; fprintf(stderr, "Error at line %d: %s\n", line, msg); fprintf(stderr, " sysmsg: %s\n", strerror(errno)); exit(1); } static int read_from_eeprom(struct eeprom *e, int addr, int size) { int ch, i; for(i = 0; i < size; ++i, ++addr) { die_if((ch = eeprom_read_byte(e, addr)) < 0, "read error"); if( (i % 16) == 0 ) printf("\n %.4x| ", addr); else if( (i % 8) == 0 ) printf(" "); printf("%.2x ", ch); fflush(stdout); } fprintf(stderr, "\n\n"); return 0; } static int write_to_eeprom(struct eeprom *e, int addr) { int i; for(i=0, addr=0; i<256; i++, addr++) { if( (i % 16) == 0 ) printf("\n %.4x| ", addr); else if( (i % 8) == 0 ) printf(" "); printf("%.2x ", i); fflush(stdout); die_if(eeprom_write_byte(e, addr, i), "write error"); } fprintf(stderr, "\n\n"); return 0; } int main(int argc, char** argv) { struct eeprom e; int op; op = 0; usage_if(argc != 2 || argv[1][0] != '-' || argv[1][2] != '\0'); op = argv[1][1]; fprintf(stderr, "Open /dev/i2c/0 with 8bit mode\n"); die_if(eeprom_open("/dev/i2c/0", 0x50, EEPROM_TYPE_8BIT_ADDR, &e) < 0, "unable to open eeprom device file " "(check that the file exists and that it's readable)"); switch(op) { case 'r': fprintf(stderr, " Reading 256 bytes from 0x0\n"); read_from_eeprom(&e, 0, 256); break; case 'w': fprintf(stderr, " Writing 0x00-0xff into 24C08 \n"); write_to_eeprom(&e, 0); break; default: usage_if(1); exit(1); } eeprom_close(&e); return 0; } |
1.12.6 Serial Programming Example
드라이버 소스 디렉토리 | /opt/FriendlyARM/mini6410/linux/linux-2.6.36/drivers/serial/ |
드라이버 소스 파일 이름 | S3c6400.c |
Device Name | /dev/ttySAC0,1,2,4 |
소스 디렉토리 | /opt/FriendlyARM/mini6410/linux/examples/comtest |
예제 이름 | comtest.c |
예제 실행 파일 이름 | armcomtest |
Test program compiled x86 version and arm version available, and its source code is exactly the same | |
# include <stdio.h> # include <stdlib.h> # include <termio.h> # include <unistd.h> # include <fcntl.h> # include <getopt.h> # include <time.h> # include <errno.h> # include <string.h> static void Error(const char *Msg) { fprintf (stderr, "%s\n", Msg); fprintf (stderr, "strerror() is %s\n", strerror(errno)); exit(1); } static void Warning(const char *Msg) { fprintf (stderr, "Warning: %s\n", Msg); } static int SerialSpeed(const char *SpeedString) { int SpeedNumber = atoi(SpeedString); # define TestSpeed(Speed) if (SpeedNumber == Speed) return B##Speed TestSpeed(1200); TestSpeed(2400); TestSpeed(4800); TestSpeed(9600); TestSpeed(19200); TestSpeed(38400); TestSpeed(57600); TestSpeed(115200); TestSpeed(230400); Error("Bad speed"); return -1; } static void PrintUsage(void) { fprintf(stderr, "comtest - interactive program of comm port\n"); fprintf(stderr, "press [ESC] 3 times to quit\n\n"); fprintf(stderr, "Usage: comtest [-d device] [-t tty] [-s speed] [-7] [-c] [-x] [-o] [-h]\n"); fprintf(stderr, " -7 7 bit\n"); fprintf(stderr, " -x hex mode\n"); fprintf(stderr, " -o output to stdout too\n"); fprintf(stderr, " -c stdout output use color\n"); fprintf(stderr, " -h print this help\n"); exit(-1); } static inline void WaitFdWriteable(int Fd) { fd_set WriteSetFD; FD_ZERO(&WriteSetFD); FD_SET(Fd, &WriteSetFD); if (select(Fd + 1, NULL, &WriteSetFD, NULL, NULL) < 0) { Error(strerror(errno)); } } int main(int argc, char **argv) { int CommFd, TtyFd; struct termios TtyAttr; struct termios BackupTtyAttr; int DeviceSpeed = B115200; int TtySpeed = B115200; int ByteBits = CS8; const char *DeviceName = "/dev/ttyS0"; const char *TtyName = "/dev/tty"; int OutputHex = 0; int OutputToStdout = 0; int UseColor = 0; opterr = 0; for (;;) { int c = getopt(argc, argv, "d:s:t:7xoch"); if (c == -1) break; switch(c) { case 'd': DeviceName = optarg; break; case 't': TtyName = optarg; break; case 's': if (optarg[0] == 'd') { DeviceSpeed = SerialSpeed(optarg + 1); } else if (optarg[0] == 't') { TtySpeed = SerialSpeed(optarg + 1); } else TtySpeed = DeviceSpeed = SerialSpeed(optarg); break; case 'o': OutputToStdout = 1; break; case '7': ByteBits = CS7; break; case 'x': OutputHex = 1; break; case 'c': UseColor = 1; break; case '?': case 'h': default: PrintUsage(); } } if (optind != argc) PrintUsage(); CommFd = open(DeviceName, O_RDWR, 0); if (CommFd < 0) Error("Unable to open device"); if (fcntl(CommFd, F_SETFL, O_NONBLOCK) < 0) Error("Unable set to NONBLOCK mode"); memset(&TtyAttr, 0, sizeof(struct termios)); TtyAttr.c_iflag = IGNPAR; TtyAttr.c_cflag = DeviceSpeed | HUPCL | ByteBits | CREAD | CLOCAL; TtyAttr.c_cc[VMIN] = 1; if (tcsetattr(CommFd, TCSANOW, &TtyAttr) < 0) Warning("Unable to set comm port"); TtyFd = open(TtyName, O_RDWR | O_NDELAY, 0); if (TtyFd < 0) Error("Unable to open tty"); TtyAttr.c_cflag = TtySpeed | HUPCL | ByteBits | CREAD | CLOCAL; if (tcgetattr(TtyFd, &BackupTtyAttr) < 0) Error("Unable to get tty"); if (tcsetattr(TtyFd, TCSANOW, &TtyAttr) < 0) Error("Unable to set tty"); for (;;) { unsigned char Char = 0; fd_set ReadSetFD; void OutputStdChar(FILE *File) { char Buffer[10]; int Len = sprintf(Buffer, OutputHex ? "%.2X " : "%c", Char); fwrite(Buffer, 1, Len, File); } FD_ZERO(&ReadSetFD); FD_SET(CommFd, &ReadSetFD); FD_SET( TtyFd, &ReadSetFD); # define max(x,y) ( ((x) >= (y)) ? (x) : (y) ) if (select(max(CommFd, TtyFd) + 1, &ReadSetFD, NULL, NULL, NULL) < 0) { Error(strerror(errno)); } # undef max if (FD_ISSET(CommFd, &ReadSetFD)) { while (read(CommFd, &Char, 1) == 1) { WaitFdWriteable(TtyFd); if (write(TtyFd, &Char, 1) < 0) { Error(strerror(errno)); } if (OutputToStdout) { if (UseColor) fwrite("\x1b[01;34m", 1, 8, stdout); OutputStdChar(stdout); if (UseColor) fwrite("\x1b[00m", 1, 8, stdout); fflush(stdout); } } } if (FD_ISSET(TtyFd, &ReadSetFD)) { while (read(TtyFd, &Char, 1) == 1) { static int EscKeyCount = 0; WaitFdWriteable(CommFd); if (write(CommFd, &Char, 1) < 0) { Error(strerror(errno)); } if (OutputToStdout) { if (UseColor) fwrite("\x1b[01;31m", 1, 8, stderr); OutputStdChar(stderr); if (UseColor) fwrite("\x1b[00m", 1, 8, stderr); fflush(stderr); } if (Char == '\x1b') { EscKeyCount ++; if (EscKeyCount >= 3) goto ExitLabel; } else EscKeyCount = 0; } } } ExitLabel: if (tcsetattr(TtyFd, TCSANOW, &BackupTtyAttr) < 0) Error("Unable to set tty"); return 0; } |
1.12.7 UDP Network Programming
드라이버 소스 디렉토리 | /opt/FriendlyARM/mini6410/linux/linux-2.6.36/drivers/net/ |
드라이버 소스 파일 이름 | dm9000.c |
Device Name | eth0 |
소스 디렉토리 | /opt/FriendlyARM/mini6410/linux/examples/udptak |
예제 이름 | udptalk.c |
예제 실행 파일 이름 | udptalk |
Test program compiled x86 version and arm version available, and its source code is exactly the same | |
예제의 전체 코드는 소스파일을 참조하세요. |
1.13 Device Driver Programming
1.12 절에서는 리눅스 User mode 에서의 예제들에 대해서 살펴 보았습니다. 이번 절에서는 커널 모드에서의 리눅스 디바이스 작성 예제들을 살펴 보도록 합니다.1.13.1 Hello, Module-simple Device Driver Example
드라이버 소스 디렉토리 | /opt/FriendlyARM/mini6410/linux/linux-2.6.36/drivers/char |
드라이버 소스 파일 이름 | Mini6410_hello_module.c |
The driver will not load any device in the dev node | |
#include <linux/kernel.h> #include <linux/module.h> static int __init mini6410_hello_module_init(void) { printk("Hello, Mini6410 module is installed !\n"); return 0; } static void __exit mini6410_hello_module_cleanup(void) { printk("Good-bye, Mini6410 module was removed!\n"); } module_init(mini6410_hello_module_init); module_exit(mini6410_hello_module_cleanup); MODULE_LICENSE("GPL"); |
(1) "Hello, Module" 을 커널 소스 트리에 넣어서 컴파일 하는 방법(added to the kernel source tree, and compile)
General compile the driver module version 2.6 driver code need to be added to the kernel source tree, and make the appropriate configuration. make menuconfig 명령에 의해서 선택 할 수 있도록 합니다.
Step1 : Kconfig 파일을 열어 다음과 같이 수정 합니다. Open "linux-2.6.36/drivers/char/Kconfig" file
linux-2.6.36 커널이 있는 디렉토리에서 "make menuconfig" 명령을 실행 합니다.
Device
Drivers -> Character devices -> "Mini6410 module sample" 에서 <M> 을 선택하면 모듈로 컴파일 된다는 의미이고 "*" 를 선택하면 커널에 포함해서 컴파일 한다는 의미 입니다. 여기에서는 <M> 으로 선택합니다.
Step2: Step1에서의 설정은 커널 컨피규레이션상의 설정이고 실제로는 이번 단계에서 Makefile을 수정 한것이 컴파일시 반영이 됩니다. "linux-2.6.36/drivers/char/Makefile" 파일을 Open 합니다.
Step3: 이번 단계에서는 실제로 모듈로 소스 파일을 컴파일 하는 단계 입니다.
(2) "Hello, Module download and install it using the development board
FTP를 이용해서 타겟 개발보드의 "/lib/modules/2.6.36-FriendlyARM" 위치에 "mini6410_hello_module.ko" 파일을 다운로드 합니다. 그리고 나서 "modprobe" 명령을 위해서 모듈을 커널에 Load 합니다 modprobe 명령시 "ko" 확장자는 붙이지 않습니다.
# modprobe mini6410_hello_module
다음 명령은 모듈은 Unload 하는 명령 입니다.
# rmmod mini6410_hello_module
1.13.2 LED Driver
LED1 ~ LED4까지를 컨트롤 하는 디바이스 드라이버 예제 입니다. 각 LED들의 6410 CPU에 할당된 리소스 입니다.
LED | IO 포트 이름 | CPU Pin name |
LED1 | GPK4 | R23 |
LED2 | GPK5 | R22 |
LED3 | GPK6 | R24 |
LED4 | GPK7 | R25 |
드라이버 소스 디렉토리 | /opt/FriendlyARM/mini6410/linux/linux-2.6.36/drivers/char |
드라이버 소스 파일 이름 | Mini6410_leds.c |
Device Type | misc |
Device Name | /dev/leds |
예제 소스 디렉토리 위치 | /opt/FriendlyARM/mini6410/linux/examples/leds |
드라이버 소스 파일 이름 | led.c |
드라이버 파일 이름 | led |
The driver will not load any device in the dev node | |
#include <linux/miscdevice.h> #include <linux/delay.h> #include <asm/irq.h> //#include <mach/regs-gpio.h> #include <mach/hardware.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/fs.h> #include <linux/types.h> #include <linux/delay.h> #include <linux/moduleparam.h> #include <linux/slab.h> #include <linux/errno.h> #include <linux/ioctl.h> #include <linux/cdev.h> #include <linux/string.h> #include <linux/list.h> #include <linux/pci.h> #include <asm/uaccess.h> #include <asm/atomic.h> #include <asm/unistd.h> #include <mach/map.h> #include <mach/regs-clock.h> #include <mach/regs-gpio.h> #include <plat/gpio-cfg.h> #include <mach/gpio-bank-e.h> #include <mach/gpio-bank-k.h> #define DEVICE_NAME "leds" static long sbc2440_leds_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { switch(cmd) { unsigned tmp; case 0: case 1: if (arg > 4) { return -EINVAL; } tmp = readl(S3C64XX_GPKDAT); tmp &= ~(1 << (4 + arg)); tmp |= ( (!cmd) << (4 + arg) ); writel(tmp, S3C64XX_GPKDAT); //printk (DEVICE_NAME": %d %d\n", arg, cmd); return 0; default: return -EINVAL; } } static struct file_operations dev_fops = { .owner = THIS_MODULE, .unlocked_ioctl = sbc2440_leds_ioctl, }; static struct miscdevice misc = { .minor = MISC_DYNAMIC_MINOR, .name = DEVICE_NAME, .fops = &dev_fops, }; static int __init dev_init(void) { int ret; { unsigned tmp; (tmp & ~(0xffffU<<16))|(0x1111U<<16); writel(tmp, S3C64XX_GPKCON); tmp = readl(S3C64XX_GPKDAT); tmp |= (0xF << 4); writel(tmp, S3C64XX_GPKDAT); } ret = misc_register(&misc); printk (DEVICE_NAME"\tinitialized\n"); return ret; } static void __exit dev_exit(void) { misc_deregister(&misc); } module_init(dev_init); module_exit(dev_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("FriendlyARM Inc."); |
1.14 Compile Qtopia-2.2.0
Qtopia-2.2.0을 컴파일 하는 방법은 앞에서 했던 커널이나 부트로더 컴파일 방법보다 좀더 복잡합니다. 아래에서 자세한 과정을 설명 합니다. x86, ARM 버젼의 "run" 스크립트는 아주 동일 합니다.
1.14.1 Compile and run x86 versions of Qtopia-2.2.0
작업 디렉토리로 이동 해서 빌드, 컴파일 하는시간은 시스템에 따라서 약간 차이가 있을수는 있지만 30분 정도가 소요 됩니다.
# cd /opt/FriendlyARM/mini6410/linux/x86-qtopia
# ./build-all
"build-all" 옵션으로 컴파일 하면 Complete Qtopia and embedded browser 가 모두 포함이 되어 컴파일이 되고,
"build-konq" 옵션으로 컴파일 하면 각각 모듈별로 컴파일 할 수 있습니다. 컴파일이 완료되고 실행을 시키는 것은 간단 합니다. 빌드가 완료된 디렉토리에서
# ./run
Qtopia가 실행된 화면 입니다.
1.14.2 Compile and run ARM versions of Qtopia-2.2.0
반드시 "arm-linux-gcc-4.4.1" 크로스 컴파일러를 이용해서 빌드 해야 합니다.
# cd /opt/FriendlyARM/mini6410/linux/arm-qtopia
# ./build-all
# ./mktarget
Produced for target root file system image file binary package, will generate "target-qtopia-konq.tgz"
컴파일된 Qtopia를 개발 보드에 설치 합니다.
#tar xvzf /home/plg/target-qtopia-konq.tgz -C /
"build-all" 이라는 스크립트를 이용해서 빌드 과정을 매우 간소화 시켰습니다. 전체 빌드가 아니라 항목별 빌드 하기 위해서는 "build-all" 파일을 수정해서 사용하시기 바랍니다.
1.14 Compile QtE-4.7.0
1.15.1 compile and run ARM versions QtE-4.7.0
반드시 "arm-linux-gcc-4.5.1" 를 이용해서 빌드해야 합니다. 컴파일 하는 방법은 "Qtopia-2.2.0" 컴파일과 동일 합니다.
# cd /opt/FriendlyARM/mini6410/linux/arm-qte-4.7.0
# ./build-all
컴파일이 완료되면 타겟 개발보드에 설치 합니다.
#tar xvzf target-qte-4.7.0.tgz -C /
댓글 없음:
댓글 쓰기