본문 바로가기
Linux BSP

[Linux Kernel] 디바이스 드라이버 커널에 빌트인으로 포함하기

by TYB 2024. 2. 29.
반응형

 

 

3가지가 있어야 커널의 빌트인 시스템을 이용해서 컴파일 할 수 있음.

1source

2kconfig

3makefile

 

 

ubuntu@ubuntu8:~/pi_bsp/kernel/linux/drivers/char$ ls
Kconfig            mem.c               random.o
Makefile           mem.o               raspberrypi-gpiomem.c
adi.c              misc.c              raspberrypi-gpiomem.ko
agp                misc.o              raspberrypi-gpiomem.mod
apm-emulation.c    modules.order       raspberrypi-gpiomem.mod.c
applicom.c         mspec.c             raspberrypi-gpiomem.mod.o
applicom.h         mwave               raspberrypi-gpiomem.o
broadcom           nsc_gpio.c          scx200_gpio.c
bsr.c              nvram.c             sonypi.c
built-in.a         nwbutton.c          tlclk.c
ds1620.c           nwbutton.h          toshiba.c
dsp56k.c           nwflash.c           tpm
dtlk.c             pc8736x_gpio.c      ttyprintk.c
hangcheck-timer.c  pcmcia              ttyprintk.o
hpet.c             powernv-op-panel.c  uv_mmtimer.c
hw_random          ppdev.c             virtio_console.c
ipmi               ps3flash.c          xilinx_hwicap
lp.c               random.c            xillybus

 

ubuntu@ubuntu8:~/pi_bsp/kernel/linux$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig

char 밑에 메뉴를 넣기 위해서는 어디에 정의를 해서 넣어줘야 되는지 궁금하죠?

char devices는 어디에 정의되어 있는지 알고싶다.
여기에 보면 define된 곳이 나와 있음.

ubuntu@ubuntu8:~/pi_bsp/kernel/linux$ vi drivers/char/Kconfig

 

6번 라인이 아까 menuconfig에서 나온 타이틀이고

8번라인이 그 하위에 들어가있는 하위 메뉴임 저 경로 안으로 들어가면 하위 경로의 menu가 똑같이 들어가 있음.

우리가 새로 만들꺼 8번라인에 추가해주자~

 

이렇게 하면 아까 menu config에서 char devices 메뉴 선택할 때 8번 라인에 구성한 메뉴가 charater devices 밑의 1번 항목에 표시될거임.

 

ubuntu@ubuntu8:~/pi_bsp/kernel/linux$ vi drivers/char/Makefile

obj-$(CONFIG_KCCI_LEDKEY)   += kcci_ledkey/

 

 

6번 라인 추가 커널에 포함시킬 수도 있고 모듈로 컴파일 할 수도 있으니, 변수 CONFIG_KCCI_LEDKEY를 추가해주고

커널에 포함만 시킬거라면 그냥 obj-y만 써줘도 됨.

 

여기서 추가해준 변수는 menu config에서 이따 GUI 상에서 선택해주면 적용되는거ㅇㅇ

 

 

 

디렉터리 만들어주고

ubuntu@ubuntu8:~/pi_bsp/kernel/linux$ mkdir drivers/char/kcci_ledkey

 

아까 3가지가 있어야 커널의 빌트인 시스템을 이용해서 컴파일 할 수 있다고 했죠?


1. Source 

 

디렉터리로 들어가서 dev source코드를 복사해온다.

ubuntu@ubuntu8:~/pi_bsp/kernel/linux/drivers/char/kcci_ledkey$ cp /home/ubuntu/pi_bsp/drivers/p432_ledkey_poll/*dev.c .
ubuntu@ubuntu8:~/pi_bsp/kernel/linux/drivers/char/kcci_ledkey$ ls
ledkey_dev.c

 

 

코드가 없다면 여기에 있음.

 

[Linux Device Driver] 입출력 다중화(Poll)과 Blocking I/O를 구현한 디바이스 드라이버

지금까지 디바이스 드라이버에서 했던 모든 걸 종합해서 한번 만들어볼게유 사용한 기술: 입출력 다중화 Poll Blocking I/O ioctl 함수 커널 타이머 코드임다. ubuntu@ubuntu8:~/pi_bsp/drivers/keyled_wcm$ cat Makefi

program-developers-story.tistory.com

 

 

 

 

ubuntu@ubuntu8:~/pi_bsp/kernel/linux/drivers/char/kcci_ledkey$ vi ledkey_dev.c

 

기존의 코드는 insmod를 통해 커널에 적재되는 것이엇는데, 부팅시에 커널에 자동으로 적재하기 위해서는 호출하게 하는 코드를 추가해줘야함.

 

부팅할 때 init을 실행하고 shutdown할때 exit을 실행하게 하고 싶다.

 

이렇게 __init과 __exit만 추가해주면 됨. 이러면 커널이 부팅할 때 load됨 b

이렇게 하면 소스는 준비완료된거고


2. Kconfig

ubuntu@ubuntu8:~/pi_bsp/kernel/linux/drivers/char/kcci_ledkey$ vi Kconfig

 

menu "kcci gpio test device driver"
        depends on ARM
        config KCCI_LEDKEY
tristate "kcci ledkey device driver"
        help
        sample driver for ledkey device
endmenu

1번 라인은 메인 메뉴라고 하면 3번라인에 있는게 서브 메뉴 이름인거임. 4번 라인은 메뉴에 3가지 선택 옵션을 주겠다는 거임. 보통 커널의 핵심코드들은 커널에 빌트인 할거냐 말거냐 두가지 BOOL 타입으로 주는데, 우리는 커널에 포함시키기도 하고 모듈로 독립적으로 하기도 하고, 포함 안시키기도 하니까 tri-state를 주는거임.

5번은 make menuconfig 할 때 선택하면 help 메뉴를 선택할 때 보여줄 내용을 적는거임.

 

KCCI_LEDKEY 변수를 선택하면 


3. Makefile

Makefile은 KCCI_LEDKEY 변수가 선택이 되면 컴파일 할 지 말지 결정해주는 파일임.

ubuntu@ubuntu8:~/pi_bsp/kernel/linux/drivers/char/kcci_ledkey$ vi Makefile
obj-$(CONFIG_KCCI_LEDKEY)  +=ledkey_dev.o

 

 

커널에 load할거면 .o가 만드는거


번외로, 모듈로 컴파일하면 .ko가 만들어지고  아래글 Makefile 보면 그렇게 되있음.

 

 

[Linux Device Driver] 입출력 다중화(Poll)과 Blocking I/O를 구현한 디바이스 드라이버

지금까지 디바이스 드라이버에서 했던 모든 걸 종합해서 한번 만들어볼게유 사용한 기술: 입출력 다중화 Poll Blocking I/O ioctl 함수 커널 타이머 코드임다. ubuntu@ubuntu8:~/pi_bsp/drivers/keyled_wcm$ cat Makefi

program-developers-story.tistory.com

ubuntu@ubuntu8:~/pi_bsp/drivers/keyled_wcm$ cat Makefile


APP := keyled_app
MOD := keyled_dev
OBJ := $(APP).o
obj-m := $(MOD).o

CROSS = ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
CC := arm-linux-gnueabihf-gcc
KDIR := /home/ubuntu/pi_bsp/kernel/linux
PWD := $(shell pwd)

default:$(OBJ)
        $(MAKE) -C $(KDIR) M=$(PWD) modules $(CROSS)
        cp $(MOD).ko /srv/nfs
%.o:%.c
        $(CC) -o $(APP) $<
        cp $(APP) /srv/nfs
clean:
        rm -rf *.ko
        rm -rf *.mod.*
        rm -rf .*.cmd
        rm -rf *.o
        rm -rf modules.order
        rm -rf Module.symvers
        rm -rf $(MOD).mod
        rm -rf .tmp_versions
        rm -rf $(APP)


 

ubuntu@ubuntu8:~/pi_bsp/kernel/linux$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig

device drivers -> char devices 밑에 들어가면

이렇게 우리가 만든게 들어가 있음.
엔터쳐서 선택하면 안에 서브메뉴도 있음 b (NEW)는 메뉴에 처음 들어오면 뜨는거임. 한번 저장되면 그 후엔 안뜸.

space bar를

1번 누르면 M module 나옴

2번 누르면 built in

3번 누르면 다시 취소

 

우리는 built in 선택하고 나갑시당.

 

 

잘 적용됬는지 확인합시다. 절대 수정하면 안됩니다. READ ONLY입니다. menuconfig로 수정하는거에요

 

ubuntu@ubuntu8:~/pi_bsp/kernel/linux$ vi .config

여기까지 됬으면

아까 Makefile에서 넣어준 코드가 저 config변수가 y라면 object file로 컴파일 하는거

obj-$(CONFIG_KCCI_LEDKEY)  +=ledkey_dev.o

 


빌트인으로 되있기 때문에 커널을 컴파일 해야겠죠?

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage

 


모듈로 만들거면

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs -j4

안되네유?

오타죠?

수정하고 다시하면 됩니다.

그럼 이제 컴파일 된 커널 이미지를 라즈베리로 옮겨줘야겠죠?

 

ubuntu@ubuntu8:~/pi_bsp/kernel/linux$ cp arch/arm/boot/zImage /srv/nfs/zImage

 

라즈베리파이 켜주고 커널 업그레이드

sudo cp zImage /boot/firmware/kernel7l.img

sync
sudo reboot

 

app 코드 69번 라인 주석처리 해주고 70번 라인 buff =(char_strtoul (keyStr, 0, 16);

ledkey_app실행시켜주면 

똑같이 작동함.

 

lsmod하면 안보임. insmod로 모듈화해서 올린것만보임.

cat /proc/devices에서 찾아야됨 .230번에 ledkey_dev 올라가있는지 확인하면 됨.


 

반응형