본문 바로가기
Linux BSP

[RaspberryPi DeviceDriver] 디바이스 드라이버 코드 수정해서 커널에 포함시키기

by TYB 2024. 2. 21.
반응형

디바이스 드라이버에 대한 간단한 이론 지식은 아랫글의 중후반부에 있음

 

[Linux DeviceDriver] Yocto Project 설정 초기화 및 디바이스 파일 만들어보기

[Linux File System] Yocto Project 2 이전 글 먼저 진행해야됩니다! [Linux File System] Yocto Project Linux에서 부팅되고, 로그인되고, 다양한 데몬 구동, 배쉬 할당 등을 위해 반드시 필요한 파일들을 Root File System

program-developers-story.tistory.com

 

ubuntu@ubuntu8:~/pi_bsp/drivers/p106$ vi hello.c

/*모듈 소스 2.6(/base/test.c)*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

static int hello_init(void)
{
        printk("Hello, world \n");
        return 0;
}

static void hello_exit(void)
{
        printk("GoodBye, world \n");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("Dual BSD/GPL");

 

Makefile

MOD := hello
obj-m := $(MOD).o

CROSS = ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-
#KDIR := /lib/modules/$(shell uname -r)/build
KDIR := /home/ubuntu/pi_bsp/kernel/linux
PWD := $(shell pwd)

default:
        $(MAKE) -C $(KDIR) M=$(PWD) modules $(CROSS)
        cp $(MOD).ko /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

KDIR이 커널 디렉터리

 

 

ubuntu@ubuntu8:~/pi_bsp/drivers/p106$ make

 

파이로 복사해주고

ubuntu@ubuntu8:~/pi_bsp/drivers/p106$ cp hello.ko /srv/nfs/

 

파이로 넘어와서

pi@pi08:/mnt/ubuntu_nfs $ ls -l hello.ko
-rw-rw-r-- 1 pi pi 4364 Feb 21 15:07 hello.ko

 

pi@pi08:/mnt/ubuntu_nfs $ file hello.ko
hello.ko: ELF 32-bit LSB relocatable, ARM, EABI5 version 1 (SYSV), BuildID[sha1]=2d1e26330e265b4647a778ed176d4cdbd4cccb77, not stripped

 

실행파일이 아니므로 relocatable로 나옴 커널에 적재되어 호출된 후 메모리에 재배치후 실행되는 파일. 

 

 

pi@pi08:/mnt/ubuntu_nfs $ lsmod | wc -l
84

84가 아니라면 다시해..난 62야..

 

pi@pi08:/mnt/ubuntu_nfs $ sudo insmod hello.ko

모듈을 동적으로 커널에 적재하겠다는 뜻이고

 

pi@pi08:/mnt/ubuntu_nfs $ lsmod | wc -l
63

 

최상단에 hello 올라가있음.

pi@pi08:/mnt/ubuntu_nfs $ lsmod |more

Module                  Size  Used by
hello                  16384  0

 

dmesg하면 커널 메시지 나오는데 Hello, World 찍혀있죠?

pi@pi08:/mnt/ubuntu_nfs $ dmesg

[15293.495454] Hello, world

 

 

커널에서 동적으로 내릴 때는 .ko 생략가능함.

pi@pi08:/mnt/ubuntu_nfs $ sudo rmmod hello

 

[15463.941997] GoodBye, world
pi@pi08:/mnt/ubuntu_nfs $ dmesg

 

다 됬쥬~?

 


그럼 응용 실습해봅싀다~

ubuntu@ubuntu8:~/pi_bsp/drivers/p106$ make clean
ubuntu@ubuntu8:~/pi_bsp/drivers/p106$ ls
Makefile  hello.c

해서 make로 생성된 파일들 지워주고

그대로 복사해서 다른 폴더로 복사해주겠으

 

led 버튼 제어하는 이전에 사용한 코드

#include <linux/kernel.h>
#include <linux/gpio.h>

#define OFF 0
#define ON 1
#define GPIOLEDCNT 8
#define GPIOKEYCNT 8
int gpioLed[GPIOLEDCNT] = {6,7,8,9,10,11,12,13};
int gpioKey[GPIOKEYCNT] = {16,17,18,19,20,21,22,23};

int     gpioLedInit(void);
void gpioLedSet(long);
void gpioLedFree(void);
int     gpioKeyInit(void);
int gpioKeyGet(void);
void gpioKeyFree(void);

asmlinkage long sys_mysyscall(long val)
{
//      printk(KERN_INFO "Welcome to KCCI's Embedded System!! app value=%ld\n",val);
        int ret;
        ret=gpioLedInit();
        if(ret < 0)
                return ret;
        gpioLedSet(val);
        gpioLedFree();

        ret=gpioKeyInit();
        if(ret < 0)
                return ret;
        ret=gpioKeyGet();
        gpioKeyFree();
        return ret;
}

int gpioLedInit(void)
{
        int i;
        int ret=0;
        char gpioName[10];
        for(i=0;i<GPIOLEDCNT;i++)
        {
                sprintf(gpioName,"led%d",i);
                ret = gpio_request(gpioLed[i],gpioName);
                if(ret < 0) {
                        printk("Failed gpio_request() gpio%d error \n",i);
                        return ret;
                }

                ret = gpio_direction_output(gpioLed[i],OFF);
                if(ret < 0) {
                        printk("Failed gpio_direction_output() gpio%d error \n",i);
                        return ret;
                }
        }
        return ret;
}

void gpioLedSet(long val)
{
        int i;
        for(i=0;i<GPIOLEDCNT;i++)
        {
                gpio_set_value(gpioLed[i],(val>>i) & 0x1);
        }
}
void gpioLedFree(void)
{
        int i;
        for(i=0;i<GPIOLEDCNT;i++)
        {
                gpio_free(gpioLed[i]);
        }
}
int gpioKeyInit(void)
{
        int i;
        int ret=0;
        char gpioName[10];
        for(i=0;i<GPIOKEYCNT;i++)
        {
                sprintf(gpioName,"key%d",gpioKey[i]);
                ret = gpio_request(gpioKey[i], gpioName);
                if(ret < 0) {
                        printk("Failed Request gpio%d error\n", 6);
                        return ret;
                }
        }
        for(i=0;i<GPIOKEYCNT;i++)
        {
                ret = gpio_direction_input(gpioKey[i]);
                if(ret < 0) {
                        printk("Failed direction_output gpio%d error\n", 6);
                return ret;
                }
        }
        return ret;
}
int     gpioKeyGet(void)
{
        int i;
        int ret;
        int keyData=0;
        for(i=0;i<GPIOKEYCNT;i++)
        {
//              ret=gpio_get_value(gpioKey[i]) << i;
//              keyData |= ret;
                ret=gpio_get_value(gpioKey[i]);
                keyData = keyData | ( ret << i );
        }
        return keyData;
}
void gpioKeyFree(void)
{
        int i;
        for(i=0;i<GPIOKEYCNT;i++)
        {
                gpio_free(gpioKey[i]);
        }
}

 

 

파일이름 led.c로

 

 

Makefile 내용 수정해주고 led를 make하겠다.라는 뜻임
ubuntu@ubuntu8:~/pi_bsp/drivers/p106_led$ vi Makefile

  1 MOD := led

 

커널에 동적으로 로드 될 때 led 8개 켜지고

 

커널에 동적으로 내릴 때 led 8개 꺼지도록

 

코드를 작성해봅시다~


ubuntu@ubuntu8:~/pi_bsp/drivers/p106_led$ vi test_mysyscall.c

test_mysyscall.c의 36번부터 끝까지 복사하고 싶으니, 열어주고 vi에서

:36,$w gpio.txt

36번라인부터 $끝까지 write하겠다. gpio.txt파일로

 

자 그럼 led.c로 가서 붙여넣고 싶은 위치로 이동 후   :r gpio.txt  하면 현재 커서 뒤로 쭉 붙여넣기 됨.

 

ubuntu@ubuntu8:~/pi_bsp/drivers/p106_led$ cat led.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/gpio.h>

#define OFF 0
#define ON 1
#define GPIOLEDCNT 8
#define GPIOKEYCNT 8
static int gpioLed[GPIOLEDCNT] = {6,7,8,9,10,11,12,13};
static int gpioKey[GPIOKEYCNT] = {16,17,18,19,20,21,22,23};

static int gpioLedInit(void);
static void gpioLedSet(long);
static void gpioLedFree(void);
static int gpioKeyInit(void);
static int gpioKeyGet(void);
static void gpioKeyFree(void);

static int gpioLedInit(void)
{
        int i;
        int ret=0;
        char gpioName[10];
        for(i=0;i<GPIOLEDCNT;i++)
        {
                sprintf(gpioName,"led%d",i);
                ret = gpio_request(gpioLed[i],gpioName);
                if(ret < 0) {
                        printk("Failed gpio_request() gpio%d error \n",i);
                        return ret;
                }

                ret = gpio_direction_output(gpioLed[i],OFF);
                if(ret < 0) {
                        printk("Failed gpio_direction_output() gpio%d error \n",i);
                        return ret;
                }
        }
        return ret;
}

static void gpioLedSet(long val)
{
        int i;
        for(i=0;i<GPIOLEDCNT;i++)
        {
                gpio_set_value(gpioLed[i],(val>>i) & 0x1);
        }
}
static void gpioLedFree(void)
{
        int i;
        for(i=0;i<GPIOLEDCNT;i++)
        {
                gpio_free(gpioLed[i]);
        }
}
static int gpioKeyInit(void)
{
        int i;
        int ret=0;
        char gpioName[10];
        for(i=0;i<GPIOKEYCNT;i++)
        {
                sprintf(gpioName,"key%d",gpioKey[i]);
                ret = gpio_request(gpioKey[i], gpioName);
                if(ret < 0) {
                        printk("Failed Request gpio%d error\n", 6);
                        return ret;
                }
        }
        for(i=0;i<GPIOKEYCNT;i++)
        {
                ret = gpio_direction_input(gpioKey[i]);
                if(ret < 0) {
                        printk("Failed direction_output gpio%d error\n", 6);
                return ret;
                }
        }
        return ret;
}
static int      gpioKeyGet(void)
{
        int i;
        int ret;
        int keyData=0;
        for(i=0;i<GPIOKEYCNT;i++)
        {
//              ret=gpio_get_value(gpioKey[i]) << i;
//              keyData |= ret;
                ret=gpio_get_value(gpioKey[i]);
                keyData = keyData | ( ret << i );
        }
        return keyData;
}
static void gpioKeyFree(void)
{
        int i;
        for(i=0;i<GPIOKEYCNT;i++)
        {
                gpio_free(gpioKey[i]);
        }
}

static int hello_init(void)
{
        int ret;
        printk("Hello, world \n");
    ret=gpioLedInit();
    if(ret < 0)
        return ret;
    gpioLedSet(0xff);
        printk("led all on \n");

        return 0;
}
static void hello_exit(void)
{
        printk("Goodbye, world \n");
        gpioLedSet(0x00);
        printk("led all off \n");
    gpioLedFree();
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("Dual BSD/GPL");

 

커널에 동적으로 로드 될 때 led 8개 켜지고

 

커널에 동적으로 내릴 때 led 8개 꺼지죠?

 


자 이제 커널에 올릴 때 led 다 켜지고 

 

버튼을 누를경우 해당 버튼에 해당되는 led만 켜지도록 수정

 

커널 내릴 때 led 다 꺼지게 만들어 보자

 

아래 코드를 윗 코드랑 합쳐서 만들자~

#include <common.h>
#include <command.h>
#include <asm/io.h>

#define BCM2711_GPIO_GPFSEL0 	0xFE200000 	
#define BCM2711_GPIO_GPFSEL1 	0xFE200004 
#define BCM2711_GPIO_GPFSEL2 	0xFE200008 
#define BCM2711_GPIO_GPSET0 	0xFE20001C
#define BCM2711_GPIO_GPCLR0 	0xFE200028
#define BCM2711_GPIO_GPLEV0 	0xFE200034

#define GPIO6_9_SIG_OUTPUT 		0x09240000
#define GPIO10_13_SIG_OUTPUT 	0x00000249  

struct cmd_tbl_t;
void led_init(void)
{
	unsigned long temp;
	temp = readl(BCM2711_GPIO_GPFSEL0);
	temp = temp & 0x0003ffff;
//	temp = temp & ~0xfffc0000;
	temp = temp | GPIO6_9_SIG_OUTPUT;
	writel(temp,BCM2711_GPIO_GPFSEL0);  	
//	writel(GPIO6_9_SIG_OUTPUT,BCM2711_GPIO_GPFSEL0);  	

	temp = readl(BCM2711_GPIO_GPFSEL1);	//gpio10~13 read
	temp = temp & 0x3ffff000; 			//gpio10~13 clear
	temp = temp | GPIO10_13_SIG_OUTPUT;//gpio10~13 output
	writel(temp,BCM2711_GPIO_GPFSEL1);  //gpio10~13 write	
//	writel(GPIO10_13_SIG_OUTPUT,BCM2711_GPIO_GPFSEL1);  
}
void led_write(unsigned long led_data)
{
	writel(0x3fc0,BCM2711_GPIO_GPCLR0); 	//led all off
	led_data = led_data << 6;
	writel(led_data,BCM2711_GPIO_GPSET0);  //ledX on
}
void key_init(void)
{
	unsigned long temp;
	temp = readl(BCM2711_GPIO_GPFSEL1);
	temp = temp & 0x0003ffff;			//gpio16~20 input
	writel(temp,BCM2711_GPIO_GPFSEL1);  	

	temp = readl(BCM2711_GPIO_GPFSEL2);
	temp = temp & 0x3ffff000;			//gpio21~23 input
	writel(temp,BCM2711_GPIO_GPFSEL2);
}
void key_read(unsigned long * key_data)
{
	*key_data =(readl(BCM2711_GPIO_GPLEV0) >> 16) & 0x000000ff;
}
static int do_KCCI_LED(struct cmd_tbl *cmdtp,int flag, int argc, char * const argv[])
{
	unsigned long led_data;
	unsigned long key_data;
	unsigned long key_data_old=0;
	unsigned long i;
  	if(argc != 2)
	{
		cmd_usage(cmdtp);
		return 1;
	}
	printf("*LED TEST START\n");
  	led_init();
	led_data = simple_strtoul(argv[1],NULL,16);
  	led_write(led_data);

	key_init();
	do {
		key_read(&key_data);
		if(key_data != key_data_old)
		{
			if(key_data)
			{
				led_write(key_data);
				puts("0:1:2:3:4:5:6:7\n");
				for(i=0;i<8;i++)
				{
					if(key_data & (0x01 << i))
						putc('O');
					else
						putc('X');
					if(i !=7 )
						putc(':');
					else
						putc('\n');
				}
				putc('\n');
			}
			key_data_old = key_data;
			if (key_data == 0x80)
				break;
		}
	} while(1);

	printf("*LED TEST END(%s : %#04x)\n\n ",argv[0],(unsigned int)key_data);
	return 0;
}
U_BOOT_CMD(
	led,2,0,do_KCCI_LED,
	"led - kcci LED Test.",
	"number - Input argument is only one.(led [0x00~0xff])\n");

 

Makefile

MOD := ledkey

 

 

 

ledkey.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/gpio.h>
#define OFF 0
#define ON 1
#define GPIOLEDCNT 8
#define GPIOKEYCNT 8
static int gpioLed[GPIOLEDCNT] = {6,7,8,9,10,11,12,13};
static int gpioKey[GPIOKEYCNT] = {16,17,18,19,20,21,22,23};

static int gpioLedInit(void);
static void gpioLedSet(long);
static void gpioLedFree(void);
static int gpioKeyInit(void);
static unsigned long gpioKeyGet(void);
static void gpioKeyFree(void);

static int gpioLedInit(void)
{
        int i;
        int ret=0;
        char gpioName[10];
        for(i=0;i<GPIOLEDCNT;i++)
        {
                sprintf(gpioName,"led%d",i);
                ret = gpio_request(gpioLed[i],gpioName);
                if(ret < 0) {
                        printk("Failed gpio_request() gpio%d error \n",i);
                        return ret;
                }

                ret = gpio_direction_output(gpioLed[i],OFF);
                if(ret < 0) {
                        printk("Failed gpio_direction_output() gpio%d error \n",i);
                        return ret;
                }
        }
        return ret;
}

static void gpioLedSet(long val)
{
        int i;
        for(i=0;i<GPIOLEDCNT;i++)
        {
                gpio_set_value(gpioLed[i],(val>>i) & 0x1);
        }
}
static void gpioLedFree(void)
{
        int i;
        for(i=0;i<GPIOLEDCNT;i++)
        {
                gpio_free(gpioLed[i]);
        }
}
static int gpioKeyInit(void)
{
        int i;
        int ret=0;
        char gpioName[10];
        for(i=0;i<GPIOKEYCNT;i++)
        {
                sprintf(gpioName,"key%d",gpioKey[i]);
                ret = gpio_request(gpioKey[i], gpioName);
                if(ret < 0) {
                        printk("Failed Request gpio%d error\n", 6);
                        return ret;
                }
        }
        for(i=0;i<GPIOKEYCNT;i++)
        {
                ret = gpio_direction_input(gpioKey[i]);
                if(ret < 0) {
                        printk("Failed direction_output gpio%d error\n", 6);
                return ret;
                }
        }
        return ret;
}
static unsigned long gpioKeyGet(void)
{
        int i;
        int ret;
        unsigned long keyData=0;
        for(i=0;i<GPIOKEYCNT;i++)
        {
//              ret=gpio_get_value(gpioKey[i]) << i;
//              keyData |= ret;
                ret=gpio_get_value(gpioKey[i]);
                keyData = keyData | ( ret << i );
        }
        return keyData;
}
static void gpioKeyFree(void)
{
        int i;
        for(i=0;i<GPIOKEYCNT;i++)
        {
                gpio_free(gpioKey[i]);
        }
}

static int hello_init(void)
{
        int ret;
        unsigned long led_data;
        unsigned long key_data;
        unsigned long key_data_old=0;
        unsigned long i;
        int index =0;
        printk("Hello, world \n");
    ret=gpioLedInit();
    if(ret < 0)
        return ret;
    gpioLedSet(0xff);
        printk("led all on \n");
    ret=gpioKeyInit();
    if(ret < 0)
        return ret;
        do{
                char printmsg[20];
                key_data=gpioKeyGet();
                if(key_data!=key_data_old)
                {
                        if(key_data)
                        {

                                gpioLedSet(key_data);
                                printk("0:1:2:3:4:5:6:7\n");
                                for(i=0;i<8;i++)
                                {

                                        if(key_data & (0x01 << i))
                                                printmsg[index++]='O';
                                        else
                                                printmsg[index++]='X';
                                        if(i !=7 )
                                                printmsg[index++]=':';
                                }
                                printmsg[index]='\0';
                                printk("%s\n\n",printmsg);
                                index=0;
                        }
                }
                key_data_old = key_data;
                if(key_data == 0x80)
                        break;
        }while(1);
        return 0;
}
static void hello_exit(void)
{
        printk("Goodbye, world \n");
        gpioLedSet(0x00);
        printk("led all off \n");
    gpioLedFree();
    gpioKeyFree();
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("Dual BSD/GPL");

 

이렇게 하면 잘됨 b

 

하지만 좋은 코드는 아님.

커널 내부에서 무한 루프를 돌리게 되면 커널에 부하를 많이 주게 되므로,

다른 곳에서 커널 사용하는데 영향을 많이 미침.

순수하게 led와 key만 한번 제어해보자고 사용하는거임.

 

실제로는 이렇게 짜면 절대 안됨.

 


좀 더 펌웨어적으로 최적화된 코드

 

#include <linux/delay.h>

 

126         if(key_data!=key_data_old)
127         {
128             if(key_data)
129             {
130                 mdelay(100);

 

mdelay를 추가해서 부하를 조금이라도 줄여주는거

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/gpio.h>

#define OFF 0
#define ON 1
#define GPIOLEDCNT 8
#define GPIOKEYCNT 8
static int gpioLed[GPIOLEDCNT] = {6,7,8,9,10,11,12,13};
static int gpioKey[GPIOKEYCNT] = {16,17,18,19,20,21,22,23};

static int gpioLedInit(void);
static void gpioLedSet(long);
static void gpioLedFree(void);
static int gpioKeyInit(void);
static int gpioKeyGet(void);
static void gpioKeyFree(void);

static int gpioLedInit(void)
{
        int i;
        int ret=0;
        char gpioName[10];
        for(i=0;i<GPIOLEDCNT;i++)
        {
                sprintf(gpioName,"led%d",i);
                ret = gpio_request(gpioLed[i],gpioName);
                if(ret < 0) {
                        printk("Failed gpio_request() gpio%d error \n",i);
                        return ret;
                }

                ret = gpio_direction_output(gpioLed[i],OFF);
                if(ret < 0) {
                        printk("Failed gpio_direction_output() gpio%d error \n",i);
                        return ret;
                }
        }
        return ret;
}

static void gpioLedSet(long val)
{
        int i;
        for(i=0;i<GPIOLEDCNT;i++)
        {
                gpio_set_value(gpioLed[i],(val>>i) & 0x1);
        }
}
static void gpioLedFree(void)
{
        int i;
        for(i=0;i<GPIOLEDCNT;i++)
        {
                gpio_free(gpioLed[i]);
        }
}
static int gpioKeyInit(void)
{
        int i;
        int ret=0;
        char gpioName[10];
        for(i=0;i<GPIOKEYCNT;i++)
        {
                sprintf(gpioName,"key%d",gpioKey[i]);
                ret = gpio_request(gpioKey[i], gpioName);
                if(ret < 0) {
                        printk("Failed Request gpio%d error\n", 6);
                        return ret;
                }
        }
        for(i=0;i<GPIOKEYCNT;i++)
        {
                ret = gpio_direction_input(gpioKey[i]);
                if(ret < 0) {
                        printk("Failed direction_output gpio%d error\n", 6);
                return ret;
                }
        }
        return ret;
}
static int      gpioKeyGet(void)
{
        int i;
        int ret;
        int keyData=0;
        for(i=0;i<GPIOKEYCNT;i++)
        {
//              ret=gpio_get_value(gpioKey[i]) << i;
//              keyData |= ret;
                ret=gpio_get_value(gpioKey[i]);
                keyData = keyData | ( ret << i );
        }
        return keyData;
}
static void gpioKeyFree(void)
{
        int i;
        for(i=0;i<GPIOKEYCNT;i++)
        {
                gpio_free(gpioKey[i]);
        }
}

static int hello_init(void)
{
        int ret, i;
        int key_data;
        int key_data_old = 0;
        char ledStatus[16]=" : : : : : : : ";
        printk("Hello, world \n");
    ret=gpioLedInit();
    if(ret < 0)
        return ret;
    ret=gpioKeyInit();
    if(ret < 0)
        return ret;

        do {
//              key_read(&key_data);
                key_data = gpioKeyGet();
                if(key_data != key_data_old)
                {
                        if(key_data)
                        {
//                              led_write(key_data);
                                gpioLedSet(key_data);
                                printk("0:1:2:3:4:5:6:7\n");
                                for(i=0;i<8;i++)
                                {
                                        if((key_data >> i) & 0x01)
                                                ledStatus[i*2] = 'O';
//                                              putc('O');
                                        else
//                                              putc('X');
                                                ledStatus[i*2] = 'X';
                                }
//                              putc('\n');
                                printk("%s\n",ledStatus);
                        }
                        key_data_old = key_data;
                        if (key_data == 0x80)
                                break;
                }
        } while(1);

//    gpioLedSet(0xff);
//      printk("led all on \n");

        return 0;
}
static void hello_exit(void)
{
        printk("Goodbye, world \n");
        gpioLedSet(0x00);
//      printk("led all off \n");
    gpioLedFree();
        gpioKeyFree();
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("Dual BSD/GPL");

커널 메시지 확인 방법

1.

dmesg 하면 부팅하고 지금까지 쌓여있는게 한번에 다 출력됨. 쌓이면 출력하는데 1~2분 걸림 

dmesg | grep welcome 이런식으로 찾는거도 가능하긴함.

2.

sudo cat /proc/kmsg 를 치면 버퍼에 있는 내용을 비워주면서 실시간으로 출력해줌 버퍼에서 비워지면 없어지므로 한번만 출력이 가능함. 최근 커널 메시지를 실시간으로 볼 때 유용함.

3.

apt에서 rsyslog 패키지를 설치하고

/var/log 디렉터리에서

tail -f kern.log를 치면 명령어를 실행할 때마다 실시간으로 확인이 가능하다.

 

최근 커널 메시지 확인만 하고 싶다면  아래 명령어 사용

pi@pi08:/var/log $ tail -5 kern.log를 쓰면 5개만 출력하고 끝남.

 


gets 와 fgets의 차이

 

gets는 문자열의 시작주소만 넘겨줌, \0이 있을 때 까지 출력하므로, Buffer Overflow 발생 가능성이 있음.

gets는 문자열의 시작주소와 읽을 주소와 문자열의 길이를 넘겨줌, 문자열의 길이만큼 출력하므로, Buffer Overflow 발생 가능성이 없음.

 


나중에 커널 부팅시에 프로그램을 실행하도록 하고 싶다면?

static int __hello_init(void)

static void __hello_exit(void)

이런식으로 init과 exit 함수 앞에 __를 붙여줘야함

 


insmod로 커널에 적재되어 있을 때 해당되는 파일이 몇번지를 사용하는지 알고 싶다면

sudo cat /proc/kallsyms |grep hello

몇번지에 로드되어 실행되는지 출력해준다.

pi@pi08:/lib/modules/6.1.77-v7l+ $ sudo cat /proc/kallsyms |grep hello
bf707040 t hello_init   [ledkey]
bf7072cc t hello_exit   [ledkey]

 


ubuntu@ubuntu8:~/pi_bsp/drivers/p106_ledkey$ vi ledkey.c

최하단 license 위에 추가해주자

164 MODULE_AUTHOR("WCM-device driver");
165 MODULE_DESCRIPTION("led key test module");

make 해주고나면

pi에서 modinfo로 ko파일의 내용을 확인 할 수 있음.

아까 작성했던 내용들이 여기에 출력됨.

pi@pi08:/mnt/ubuntu_nfs $ modinfo ledkey.ko
filename:       /mnt/ubuntu_nfs/ledkey.ko
license:        Dual BSD/GPL
description:    led key test module
author:         WCM-device driver
srcversion:     495D804C6E4FA94A3EB7292
depends:
name:           ledkey
vermagic:       6.1.77-v7l+ SMP mod_unload modversions ARMv7 p2v8

 

반응형