hello 디바이스 만들기
프로그래밍 첨하면 아무나 다하는 hello.c를 만들어 보겠다.

#include <linux/init.h>

#include <linux/module.h>

MODULE_LICENSE("Dual BSD/GPL");


static int __init hello_init(void) {

        printk(KERN_ALERT "Hello, world\n");

        return 0;

}

static void __exit hello_exit(void) {

        printk(KERN_ALERT "Goodbye, world\n");

}

module_init(hello_init);

module_exit(hello_exit);

뭐하는 설명 안해도 다 알만한 프로그램이다.
여기서 기존의 프로그램과 다른점은 printf 대신 printk 를 썻다는 것이다.
저 코드들은 커널 에서 실행되기때문에 유저스페이스의 함수를 사용할 수 없다.
그래서 stdio 같은것들을 인클루드 하면 안된다. 모두 커널상의 함수를 사용해야한다.
printk 역시 커널 함수로 printf와 거의 유사한 기능을 한다.

중간에 __init 과 __exit 가 좀 수상쩍어 보인다.
이것은 필수는 아니지만 써주는게 좋다. 그 이유는 커널에게 시작할때 한번 끝날때 한번 실행하는 함수라고 알려서 실행되고 바로 메모리에서 삭제하도록 할 수있다.

MODULE_LICENSE 는 라이센스를 지정하는 부분인데 이부분이 재미있다.
여기에 들어갈 수 있는 스트링은 아래와 같다.

"GPL"  ,  "GPL v2"  ,  "GPL and additional rights"  ,  "Dual BSD/GPL"  ,  "Dual MPL/GPL"

"Proprietary"

 사실 MODULE_LICENSE 는 옵션이다. 그러나 지정하지 않은 모듈을 적재시 "오염 상태" 가 된다.

makefile 만들기

KERNELDIR ?= /lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)

obj-m := hello.o


default:

        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules


clean:

        rm *.ko *.o Module.* modules.* *.mod.c

KERNELDIR 에는 커널헤더 경로가 들어가기 때문에 위와 같은 명령을 사용하면 헤더의 경로를 가져올 수 있다.
자 이제 make 를 실행해 보자.

root@cranix-desktop:~/work/drivers# make

make -C /lib/modules/2.6.31-20-generic-pae/build M=/root/work/drivers modules

make[1]: Entering directory `/usr/src/linux-headers-2.6.31-20-generic-pae'

  CC [M]  /root/work/drivers/hello.o

  Building modules, stage 2.

  MODPOST 1 modules

  CC      /root/work/drivers/hello.mod.o

  LD [M]  /root/work/drivers/hello.ko

make[1]: Leaving directory `/usr/src/linux-headers-2.6.31-20-generic-pae'

위와 같이 나오면 제대로 컴파일 된 것이고 hello.ko 파일이 생겼을 것이다.
ko 란 커널 오브젝트의 약자로서 2.6 넘어오면서 커널오브젝트와 다른 오브젝트를 구분하기위해 생긴것이다.


hello 디바이스 적재및 삭제

root@cranix-desktop:~/work/drivers# insmod hello.ko

root@cranix-desktop:~/work/drivers# lsmod |grep hello

hello                   1052  0

root@cranix-desktop:~/work/drivers# rmmod hello

root@cranix-desktop:~/work/drivers# lsmod |grep hello

root@cranix-desktop:~/work/drivers#  

위와같이 디바이스 드라이버는 insmod 와 rmmod 로 적재와 삭제를 하고 lsmod 로 리스트를 볼 수 있다.



커널로그 보기
분명 적재는 했는데 printk 로 출력한 메시지는 어떻게 볼 수 있을까?

root@cranix-desktop:~/work/drivers# dmesg

...

...

[ 2747.649737] Hello, world

[ 2759.753311] Goodbye, world

메시지가 쭈욱 나오는데 제일 아래보면 원하던 메시지를 볼 수 있을 것이다.



신고

'알짜정보 > Linux device driver' 카테고리의 다른 글

hello 디바스 드라이버  (46) 2010.03.18
by cranix 2010.03.18 23:50
- 현 리눅스의 커널버젼 알아보기
- # uname -r

- 우분투에서 apt-cache 으로 현재의 리눅스 커널 소스를 검색하기
- # apt-cache search linux-source-*

- 우분투에서 apt-get 으로 검색한 커널 설치하기
- # apt-get install linux-source-2.6.xxxx..

- 받아진 커널 소스 압축풀기
- /usr/src 디렉토리 안에 커널소스 파일이 들어있다.
- ex) # tar -xjf linux-source-2.6.31.tar.bz2

- 커널 컴파일 하기
- # make menuconfig 명령으로 커널설정을 먼저 한다.
- # make

신고
by cranix 2010.03.03 09:12

윈도우에서 JAVA 로 IP 주소 가지고 오는소스는 아래와 같다.

[code]try {
    ip = InetAddress.getLocalHost().getHostAddress();
   } catch (UnknownHostException e) {
    e.printStackTrace();
}[/code]


그러나 이것을 리눅스에서 쓴다면 127.0.0.1 즉 루프백 아이피 주소가 나오게 된다.
어떻게 해야할까?
구글링결과 아래와같은 결론을 얻었다.

[code]try {
    boolean isLoopBack = true;
    Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
    while(en.hasMoreElements()) {
     NetworkInterface ni = en.nextElement();
     if (ni.isLoopback())
      continue;
     
     Enumeration<InetAddress> inetAddresses = ni.getInetAddresses();
     while(inetAddresses.hasMoreElements()) {
      InetAddress ia = inetAddresses.nextElement();
      if (ia.getHostAddress() != null && ia.getHostAddress().indexOf(".") != -1) {
       ip = ia.getHostAddress();
       isLoopBack = false;
       break;
      }
     }
     if (!isLoopBack)
      break;
    }
   } catch (SocketException e1) {
    e1.printStackTrace();
   }[/code]

NetworkInterface 라는 클래스를 이용하여 각 네트웍 인터페이스를 검색해서 알아내는 방법이다.
어찌되었건 이렇게 하면 윈도우건 리눅스건 돌아간다.
 
어째 자바스크립트가 된 기분이다.
이것은 자바의 철학인 WORA(Write Once Run Anyware) 를 위배한다.

앞으로 자바가 어떻게 발전할지는 모르겠지만 가장 기본적인 자바 철학은 지켜 주었으면 하는 바램이다.

신고

'알짜정보 > Java' 카테고리의 다른 글

자바 힙덤프 뜨기  (69) 2012.12.18
JNLP 테스트  (36) 2010.02.14
JAVA 리눅스 IP 주소 알아내기  (38) 2008.12.02
apache 프로젝트의 commons-dbcp 를 이용하여 connection pool 만들기.  (42) 2008.08.15
java 에서 xmlrpc 사용하기  (38) 2008.07.13
annotation 주석?  (43) 2006.12.16
by cranix 2008.12.02 00:15
| 1 |