출처 : http://stackoverflow.com/questions/15430921/how-to-pass-parameters-from-makefile-to-linux-kernel-module-source-code



As the Linux build system uses kernel provided Makefiles that can reasonably not be changed. I'd suggest to place your version number directly into the source code instead of in the Makefile.

There's a possibility thought. You can define a CPPFLAGS environment variable. It should be passed by the kernel Makefile to the C compiler command line. If you define this CPPFLAGS variable as -DVERSION=42, maybe you can use this VERSION macro inside your source file.

all:
    CPPFLAGS="-DVERSION=42" make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

Note that CPPFLAGS stands for "C PreProcessor FLAGS". It is unrelated to C++.

After testing it. This does not work. There's a solution however. The kernel Makefile allows (and uses) the definition of the KCPPFLAGS environment variable that will be added to the kernel Makefile defined own CPPFLAGS.

You have to use:

all:
    KCPPFLAGS="-DVERSION=42" make -C /lib/modules/$(shell uname -r)/build M=$(PWD) 


WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,

출처 : http://blog.naver.com/PostView.nhn?blogId=dolicom&logNo=10096312448


보통 리눅스 커널을 디버깅 하려면 쉽게 log 메세지를 이용할 수 있다. 이럴 때는 printk 함수를 사용하면 되는데 디버깅이 끝나면 제거 하면 된다.


#ifdef DEBUG

#define DPRINTF(fmt,args,...) printk(##args)

#else

 #define DPRINTF

#endif


이렇게 하면

DPRINTF을 골라서 쉽게 제거할 수 있다.


예를 들어 특정 부분만을 디버깅 할 때만 printf 한다면


#include <stdio.h>


#define DEBUG

#ifdef DEBUG
#define DPRINTF(fmt,args,...) printf( "%s:%s:%d: " fmt, __FILE__,  __FUNCTION__, __LINE__, ##args)
#else
#define DPRINTF   - 코드내의 이 함수를 제거 하여 출력하지 않는다.
#endif


int main( int argc, char *argv[])
{
   int i = 0;

   if (argc < 2) {
      DPRINTF( "argc=%d\n", argc);
   } else {
      DPRINTF( "argc=%d,argv1=%s\n", argc, argv[1]);
   }

   printf("파일이름: %s\n", __FILE__);
   printf("현재 라인번호 : %d\n", __LINE__);
   printf("현재 출력되는 함수 : %s\n", __FUNCTION__);
   printf("컴파일 날짜 : %s\n", __DATE__);
   printf("컴파일 시간 : %s\n", __TIME__);

   return 0;
}


실행 :

C:\defexam\defexam\defexam.cpp:main:23: argc=1
파일이름: c:\defexam\defexam\defexam.cpp
현재 라인번호 : 29

현재 출력되는 함수 : main
컴파일 날짜 : Nov 14 2010
컴파일 시간 : 21:55:14




#와 ##


#   : 스트링화 한다.

## : 토큰을 연결하여 하나의 토큰으로 만든다.



Token


프로그램을 구성하고 있는 문법적으로 의미 있는 최소 단위

          

if (i<100) sum+=i;
===> if, (, i, <, 100, ), sum, +=, i, ;

10개의 토큰으로 이루어 진다.



토큰의 예

  • 키워드 : int, while, if, else, auto, char, for…
  • 식별자 : main, printf, scanf, i, j…
  • 연산자 : +, -, *, /, =, <. >=…
  • 수치상수 : 124, 12.35, 7E9 등과 같은 수
  • 문자상수 : 단일 인용 부호(' ')내의 단일 문자나 문자열
  • 특수문자 : (, ), ;와 같이 구분자로 사용되는 문자
  • 주해 : /*와 */사이에 있는 임의의 문자열, 컴파일러에 의해 번역되지 않는다.

#예 :

#define QUOTEME(x) #x
printf("%s\n", QUOTEME(1+2));
===>
printf("%s\n", "1+2");


Token concatenation


#define CATTOK(x,y)  x##y


  int manage;

   manage = 10;

   printf("%d\n", CATTOK(man,age));

===>

   printf("%d\n", manage );



 

 

예 1 :


#define FORMAT_(type) FORMAT_##type
#define FORMAT_int    "%d"
#define FORMAT_double "%g"


 

void print_star(const starStruct *const star) {
  /* FORMAT_(type) will be replaced with FORMAT_int or FORMAT_double */
  #define EXPAND_STAR_MEMBER(member, type) \
    printf("%s: " FORMAT_(type) "\n", #member, star->member);
  EXPAND_STAR
  #undef EXPAND_STAR_MEMBER
  }

 

예 2 :

 

#define MYCASE(item,id) \
case id: \
  item##_##id = id;\
break

switch(x) {
    MYCASE(widget,23);
}

===>

case 23:
  widget_23 = 23;
break;

 


예 3 :


#define     CONCAT(a, b)     a##b


// main 함수

int main(void)

{

          int arr〔2〕= { 100, 200 };


          printf("%d \n", CONCAT(2, 4));

          printf("%d %d \n", CONCAT(arr, 〔0〕), CONCAT(arr, 〔1〕));


          return 0;

}



printf 사용시 방법 몇가지


 

#define print_int(val)    printf("%d", val)
#define print_double(val) printf("%g", val




#define DPRINTF(a,args...) fprintf( stderr, "%s:%d:"#a"\n", __FUNCTION__, __LINE__, ##args)


예:


#define DPRINTF(fmt,args,...) printf( "%s:%d:" fmt, __FUNCTION__, __LINE__, ##args)


int main( int argc, char *argv[])
{
   int i = 0;


   if (argc < 2) {

      DPRINTF( "argc=%d", argc);

   }


   printf("End of program\n");
   return 0;
}


#define CHECK1(x,format,args) if(x) {printf(format,args);}


#define fcntl( fd, command, ... ) \
wpurple_fcntl( fd, command, ##__VA_ARGS__ )

#define gprintk(fmt, x... ) printk( "%s: " fmt, __FUNCTION__ , ## x)

 

다른 예


#define a /*
#<?php echo "\\010Hello, world!\\n"// 2> /dev/null > /dev/null \\
;
// 2> /dev/null; x=a;
$x=5 // 2> /dev/null \\
;
if (($x))
// 2> /dev/null; then
return 0;
// 2> /dev/null; fi
#define e ?>
#define b */
#include
#define main() int main()
#define printf printf(
#define true )
#define function
function main()
{
printf "Hello, world!\\n"true/* 2> /dev/null | grep -v true*/;
return 0;
}
#define c /*
main
#*/


예 :


#define printf(fmt, args...)    test_print(fmt, ##args)


int ttyS1_fd;


void test_print(char *fmt, ...)
{
   write(ttyS1_fd, fmt, strlen(fmt));
}

int main(void)
{
   if ( (ttyS1_fd = open("/dev/ttyS1", O_RDWR|O_NOCTTY)) < 0 ) {
       printf(" /dev/ttyS1" open failed\n");
       return 1;
   }

   while (1) {
      printf("abcde %d\n", 1);
      sleep(1)
   }

  return 0;
}

 

#define sum(x,y)  (x+y)


#define LEN 100

#define WIDTH 100

   char array[LEN][WIDTH];

#undef LEN

#undef WIDTH




printk 사용


참고로 printk 함수는

printk()는 카널의 메시지를 콘솔이나 dmesg, syslog 데몬에게 넘겨주는 일을 한다.



1. printk

 

 include/linux/kernel.h


일반적인 프로그램을 작성할때도 로그정책은 매우 중요하다. 보통 레벨 1은 가장 낮은 수준의 디버그 메시지 레벨 3은 모든 디버그 메시지를 모두 남기는 식으로 정하는데 priorities를 이용해서 발생되는 로그에 레벨을 부여해 줄 수 있다.

priority 는 다음과 같이 커널에 정의되어 있다.

#define KERN_EMERG    "<0>"  /* system is unusable               */ 
#define KERN_ALERT "<1>" /* action must be taken immediately */
#define KERN_CRIT "<2>" /* critical conditions */
#define KERN_ERR "<3>" /* error conditions */
#define KERN_WARNING "<4>" /* warning conditions */
#define KERN_NOTICE "<5>" /* normal but significant condition */
#define KERN_INFO "<6>" /* informational */
#define KERN_DEBUG "<7>" /* debug-level messages */

2. printk 사용

 

KERN_INFO의 동일한 표현

printk(KERN_INFO "system ok\n");

printk("<6>" "system ok\n");

printk("<6>system ok\n");


기타 예 :

printk(KERN_INFO "i = %u\n", i);

printk("<0> %s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__);

레벨에 대한 표시를 하지 않는다면 default 레벨은 "KERN_WARNING" 이다.

 

3. 커널 메시지 관리 데몬

- klogd : 커널에서 발생하는 메시지를 기록하고 관리한다.

- syslogd : 커널에서 발생한느 메시지와 응용 프로그램에서 요청한 시스템 정보를 기록하고 관리한다.

- /var/log/messages 파일에 모든 커널메시지가 저장된다.

 

4. 로그 정보보기

- dmesg

- cat /proc/kmsg : 커널 메시지가 발생할 때 즉시 출력.



Windows CE에서 사용법


보통 디버깅 시 정의하는 것을 바꿀 필요가 생긴다. 지금 WindowsCE의 메세지를 PC WIN32 MFC로 바꾸려면 RETAILMSG과 TRACE의 정의가 틀리다. 따라서 이것을 조정하기 위한 정의 이다.


RETAILMSG 함수의 첫번째 인수 n을 제거하는 것이다.


#define RETAILMSG(n, args...) TRACE(##args)   ---> ##다음 부터는 그대로



RETAILMSG(1, (TEXT("Invalid parameter to ReadChunk()\r\n")));

===> TRACE( (TEXT("Invalid parameter to ReadChunk()\r\n")));


RETAILMSG(1, (TEXT("Error opening %s. Error code = 0x%08x\n"), pszFilename, GetLastError()));

===> TRACE( (TEXT("Error opening %s. Error code = 0x%08x\n"), pszFilename, GetLastError()));


'Linux' 카테고리의 다른 글

LIDS 내부구조(리눅스 파일 보안)  (0) 2011.02.16
__attribute__ __context__ sparse  (0) 2011.02.15
linux directory dirent.h  (0) 2010.12.05
insmod,rmmod,lsmod,modprobe,depmod,modinfo  (0) 2010.12.05
[MTD] NAND: nandsim page-wise allocation  (0) 2010.12.05

WRITTEN BY
RootFriend
개인적으로... 나쁜 기억력에 도움되라고 만들게되었습니다.

,