關於我自己

2019年3月5日 星期二

sock 練習 - IPv4 TCP




Server:

// Server side C/C++ program to demonstrate Socket programming
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#define PORT 8080
int main(int argc, char const *argv[])
{
    int server_fd, new_socket, valread;
    struct sockaddr_in address;
    int opt = 1;
    int addrlen = sizeof(address);
    char buffer[1024] = {0};
    char hello[] = "Hello from server";
     
    // Creating socket file descriptor
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
    {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }
     
    // Forcefully attaching socket to the port 8080
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
                                                  &opt, sizeof(opt)))
    {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons( PORT );
     
    // Forcefully attaching socket to the port 8080
    if (bind(server_fd, (struct sockaddr *)&address,
                                 sizeof(address))<0)
    {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }
    if (listen(server_fd, 3) < 0)
    {
        perror("listen");
        exit(EXIT_FAILURE);
    }
    if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
                       (socklen_t*)&addrlen))<0)
    {
        perror("accept");
        exit(EXIT_FAILURE);
    }
    valread = read( new_socket , buffer, 1024);
    printf("%s\n",buffer );
    send(new_socket , hello , strlen(hello) , 0 );
    printf("Hello message sent\n");
    return 0;
}


Client:

// Client side C/C++ program to demonstrate Socket programming
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
//#include <netinet/in.h>
#include <arpa/inet.h> //inet_pton
#include <unistd.h>

#include <string.h>
#define PORT 8080
 
int main(int argc, char const *argv[])
{
    struct sockaddr_in address;
    int sock = 0, valread;
    struct sockaddr_in serv_addr;
    char hello[] = "Hello from client";
char hostString[128]= {0};
    char buffer[1024] = {0};

if(argc < 2 )
strncpy(hostString,"127.0.0.1",128);
else
strncpy(hostString,argv[1],128);

printf("Target address : %s\n",hostString);
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("\n Socket creation error \n");
        return -1;
    }
 
    memset(&serv_addr, '0', sizeof(serv_addr));
 
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);
     
    // Convert IPv4 and IPv6 addresses from text to binary form
    if(inet_pton(AF_INET, hostString , &serv_addr.sin_addr)<=0)
    {
        printf("\nInvalid address/ Address not supported \n");
        return -1;
    }
 
    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
        printf("\nConnection Failed \n");
        return -1;
    }
    send(sock , hello , strlen(hello) , 0 );
    printf("Hello message sent\n");
    valread = read( sock , buffer, 1024);
    printf("%s\n",buffer );
    return 0;





來源:
https://www.geeksforgeeks.org/socket-programming-cc/

2018年10月14日 星期日

[面試] 群聯 Linux kernel 2018/10/9


群聯

筆試給了試題和兩張白紙,第一題就是寫出keygen,
以前也有寫過JS版本的
分析:
面試主要是Linux相關所以用C/C++撰寫
C的版本在於只有兩張紙還有大約10題,必定不適合寫個Link list...
於是直接alloc裝Key...




1. 寫一個keygen 0-F 6個字gen出不重複的key

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define ARRY_SIZE(A) (sizeof(A)/sizeof(A[0]))
char allowChar [] =
{
    '0','1','2','3','4','6','7','8','9','A','B','C','D','E','F'
};


char *keyList;



char getChar(){
    return allowChar[rand()%ARRY_SIZE(allowChar)];
}

bool inList(  char * keyListPtr , int currentListLength , int keySize ,char *tmpKey )
{
    char *keyPtr;

    int i;
    for(i  = 0 ; i < currentListLength; i ++ )
    {
        keyPtr = keyListPtr+ i*keySize;
        if( strcmp(keyPtr ,tmpKey ) == 0)
            return true;

    }
return false;
}
char *genKey( char *keyListPtr ,int keyNumber,int Length){
    int i,j,totalBufferSize,keySize;
    keySize =  Length +1 ;
    totalBufferSize = keyNumber*keySize;
    char *tmpKey = (char *)malloc(keySize);
    keyListPtr = (char * ) malloc( totalBufferSize  );
    memset(keyListPtr , 0 , totalBufferSize);

    j = 0;
    while( j < keyNumber )
    {
        memset(tmpKey, 0 ,keySize);
        for( i = 0 ; i < Length ; i++ )
            *(tmpKey+i) = getChar();
        if( !inList(  keyListPtr , j , keySize ,tmpKey )  )
        {
            memcpy( keyListPtr + j*keySize , tmpKey , keySize);
            j++;
        }
    }
    free(tmpKey);
    printf("Gen Done!\n");
    return keyListPtr;
}


void display(  char * keyListPtr , int currentListLength , int keySize ){
    char *keyPtr;

    int i;

    for(i  = 0 ; i < currentListLength; i ++ )
    {
        keyPtr = keyListPtr + i*keySize;
        printf("key[%4d] : %s\n",i,keyPtr);

    }
return ;
}

int main()
{
    int keyNumber = 30;
    int keyLength = 6;
    char * keyList;


    keyList = genKey( keyList , keyNumber , keyLength );
    display(keyList ,keyNumber  , keyLength + 1  );

    free(keyList);

    return 0;
}



find gcc in linux kernel

find /usr/ -type f -name "gcc"

2018年6月16日 星期六

Aeron Chair 全功能版該不該買?


1. 是否能承擔腰痛造成的困擾?

2. 是否能承擔腰痛到無不睡著的代價?

4. 目前家具搬家費用預估1萬NT 是否能承擔?
Y

5. 2018/06/17 陸製全功能版 特價25999 造成負擔很大嗎?
閒錢,只是嫌貴

6. 是否要每次因為特價浪費一整天看網頁?


7. 買了之後發現不好用是否能承擔二手轉賣的價差?
YES



2017年9月24日 星期日

RW Memory


// program
//DJgpp compiler
//

#include <stdio.h>
#include <string.h>

#ifndef OS_TYPE
#define OS_TYPE 0
#endif

#ifdef  __linux
#undef  OS_TYPE
#define OS_TYPE 2
#endif


#if (OS_TYPE == 0)
//----------------------------------------------------------------------------
//          DOS_SUPPORT(Default)
//----------------------------------------------------------------------------
//  <  --  http://www.delorie.com/djgpp/doc/libc/libc_473.html --  >
#include <pc.h>  //nportb inportl outportb outportl
//  <  --  http://www.delorie.com/djgpp/doc/libc/libc_128.html --  >
#include <dos.h> // 1sec = delay(1000)                       */
//#include  <unistd.h> //1s=sleep(1) 1s=usleep(1000000)


#elif (OS_TYPE ==2) || (OS_TYPE ==5)
//----------------------------------------------------------------------------
//          LINUX_SUPPORT
//----------------------------------------------------------------------------
//  <  --  http://man7.org/linux/man-pages/man2/outb_p.2.html --  >
#include <sys/io.h> //IO

//  <  --  http://pubs.opengroup.org/onlinepubs/7908799/xsh/unistd.h.html --  >
#include <unistd.h> //1s=sleep(1) 1s=usleep(1000000)
                                       
                                       
#elif (OS_TYPE ==1) || (OS_TYPE ==4)

     #if WINIO_SUPPORT_BUILD && WINIO_SUPPORT
            //----------------------------------------------------------------------------
            //   WINDOWSx86/x64_SUPPORT
            //----------------------------------------------------------------------------
        //  <  -- WINIO http://www.internals.com/ --  >
         #include <windows.h> //IO. Sleep   1s=Sleep(1000)
                                               
                                                   
   #endif//#if WINIO_SUPPORT_BUILD && WINIO_SUPPORT
#endif//#elif (OS_TYPE ==1) || (OS_TYPE ==4)


#define DEV_PACKAGE_ID      mini_v1.01.8

//----------------------------------------------------------------------------
//      Global Define  
//----------------------------------------------------------------------------

#ifndef IN
#define IN
#endif

#ifndef OUT
#define OUT
#endif


#ifndef NULL
#define NULL  ((VOID *) 0)
#endif

#ifndef TRUE
#define TRUE  ((BOOLEAN) (1 == 1))
#endif

#ifndef FALSE
#define FALSE ((BOOLEAN) (0 == 1))
#endif
//----------------------------------------------------------------------------
//        ERROR CODE      
//----------------------------------------------------------------------------
//typedef UINT8 EFI_STATUS;

#define EFI_SUCCESS               0
#define EFI_FAIL               0x01
#define EFI_SHOW_NOTHING       0x02
#define EFI_SHOW_DATA          0x03



//----------------------------------------------------------------------------
//      Define  BIT MAP    
//----------------------------------------------------------------------------
#ifndef BIT0          
#define BIT0              0x01
#define BIT1              0x02
#define BIT2              0x04
#define BIT3              0x08
#define BIT4              0x10
#define BIT5              0x20
#define BIT6              0x40
#define BIT7              0x80
#endif

#ifndef BIT00        
#define BIT00             0x01
#define BIT01             0x02
#define BIT02             0x04
#define BIT03             0x08
#define BIT04             0x10
#define BIT05             0x20
#define BIT06             0x40
#define BIT07             0x80
#define BIT08           0x0100
#define BIT09           0x0200
#define BIT10           0x0400
#endif

#ifndef BIT11
#define BIT11           0x0800
#define BIT12           0x1000
#define BIT13           0x2000
#define BIT14           0x4000
#define BIT15           0x8000
#define BIT16       0x00010000
#define BIT17       0x00020000
#define BIT18       0x00040000
#define BIT19       0x00080000
#define BIT20       0x00100000
#define BIT21       0x00200000
#define BIT22       0x00400000
#define BIT23       0x00800000
#define BIT24       0x01000000
#define BIT25       0x02000000
#define BIT26       0x04000000
#define BIT27       0x08000000
#define BIT28       0x10000000
#define BIT29       0x20000000
#define BIT30       0x40000000
#define BIT31       0x80000000
#endif


//---------------------------//
//      Define GPIO         //
//---------------------------//
#define IS_GPIO                 1
#define IS_NOT_GPIO             0
#define IS_HIGH                         1
#define IS_LOW                          0
#define IS_GPI                        1
#define IS_GPO                        0
#define IS_OD                   1



//---------------------------//
//      Define Macro         //
//---------------------------//
//MATH
#define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
#define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )

//TO UPPER CASE
#define UPCASE( c ) ( ((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c) )

//GET ARRY SIZE
#define ARRY_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )


//println
#define printfln(x); printf((x)); printf("\n");

//Strize
#define _STR(s) #s
#define STR(s) _STR(s)

//Check Hex
#define HEXCHK( c )  \
                                      ( \
                                       ((c) >= '0' && (c) <= '9') || \
                                         ((c) >= 'A' && (c) <= 'F') || \
                                         ((c) >= 'a' && (c) <= 'f')    \
                                        )


//---------------------------//
//      RW MARCO             //
//---------------------------//
#define IOWrite8(x , y)      WriteIO8( x , y)
#define IORead8( x )         ReadIO8( x )
#define IOWrite32(x , y)     WriteIO32( x , y)
#define IORead32(x )         ReadIO32( x )



//---------------------------//
//      Define   Size        //
//---------------------------//
#if OS_TYPE == 0 //  DOS  //
  typedef unsigned long  long      UINT64;
  typedef unsigned int             UINT32;
  typedef unsigned short           UINT16;
  typedef unsigned char            UINT8;
  typedef UINT64                   UINTN;

#elif OS_TYPE == 1 //  winx86 //

  typedef unsigned long  long      UINT64;
  typedef unsigned int             UINT32;
  typedef unsigned short           UINT16;
  typedef unsigned char            UINT8;
  typedef UINT64                   UINTN;


#elif OS_TYPE == 2//  linux86 //
  typedef unsigned long  long      UINT64;
  typedef unsigned int             UINT32;
  typedef unsigned short           UINT16;
  typedef unsigned char            UINT8;
  typedef UINT64                   UINTN;
#elif OS_TYPE == 3 //  EFI_SHELLx86 //
  typedef unsigned long  long      UINT64;
  typedef unsigned int             UINT32;
  typedef unsigned short           UINT16;
  typedef unsigned char            UINT8;
  typedef UINT64                   UINTN;
#elif OS_TYPE == 4//  winx64 //
  typedef unsigned long  long      UINT64;
  typedef unsigned int             UINT32;
  typedef unsigned short           UINT16;
  typedef unsigned char            UINT8;
  typedef UINT64                   UINTN;
#elif OS_TYPE == 5//  linxux64 //
  typedef unsigned long  long      UINT64;
  typedef unsigned int             UINT32;
  typedef unsigned short           UINT16;
  typedef unsigned char            UINT8;
  typedef UINT64                   UINTN;
el#if OS_TYPE == 6 //  EFI_SHELLx64 //
  typedef unsigned long  long      UINT64;
  typedef unsigned int             UINT32;
  typedef unsigned short           UINT16;
  typedef unsigned char            UINT8;
  typedef UINT64                   UINTN;
#endif

typedef UINT8 boolean;
typedef boolean BOOLEAN;
//---------------------------//
//      IO  RW  typedefine   //
//---------------------------//

  #if (OS_TYPE ==1) || (OS_TYPE ==4) //WINDOWSx86/x64_SUPPORT
    #if WINIO_SUPPORT_BUILD && WINIO_SUPPORT
      typedef BOOL (WINAPI   *  DLL_InitializeWinIo)();
      DLL_InitializeWinIo InitializeWinIo;
      typedef BOOL (WINAPI   *  DLL_RemoveWinIoDriver)();
      DLL_RemoveWinIoDriver RemoveWinIoDriver;
      typedef void (WINAPI   *  DLL_ShutdownWinIo)();
      DLL_ShutdownWinIo ShutdownWinIo;
      typedef BOOL (WINAPI   *  DLL_GetPortVal)(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize);
      DLL_GetPortVal GetPortVal;
      typedef BOOL (WINAPI   *  DLL_SetPortVal)(WORD wPortAddr, DWORD dwPortVal, BYTE bSize);
      DLL_SetPortVal SetPortVal;
    #elif !WINIO_SUPPORT_BUILD && WINIO_SUPPORT      
      typedef UINT8 BOOL;
      typedef UINT16 WORD;
      typedef UINT32 DWORD;
      typedef UINT32 *PDWORD;
    #endif//WINIO_SUPPORT_BUILD && WINIO_SUPPORT
  #endif

   
//--------------------------//
//    Argv typedef          //
//--------------------------//

  typedef int (*Project_ptr)(int *argc, char *argv[]) ;
  typedef Project_ptr FUNC_PTR;
  typedef struct _ONE_COMMAND{
  char        *argv1;
  char        *argv1_t;
  FUNC_PTR    Func_ptr;
  }ONE_COMMAND;
 


//--------------------------//
//    Global typedef        //
//--------------------------//
typedef UINT8 EFI_STATUS;


//--------------------------//
//    Global String        //
//--------------------------//

#if OS_TYPE == 0
char OSstring []="DOS";
#elif OS_TYPE == 1
char OSstring []="Windows_x86";
#elif OS_TYPE == 2
char OSstring []="Linux";
#elif OS_TYPE == 3
char OSstring []="UEFI_SHELL";
#elif OS_TYPE == 4
char OSstring []="Windows_x64";
#elif OS_TYPE == 5
char OSstring []="Linux";
#elif OS_TYPE == 6
char OSstring []="UEFI_SHELL";
#endif



//--------------------------//
//     RW  Variable         //
//--------------------------//
#if (OS_TYPE ==1) || (OS_TYPE ==4)
#if WINIO_SUPPORT_BUILD && WINIO_SUPPORT
HINSTANCE hDLL;

#endif
#endif


//--------------------------//
//     RW  Function Link    //
//--------------------------//
void CHECK_EFI_SIZE();
void WriteIO8(IN UINT16  address,IN UINT8   value);
void WriteIO32(IN UINT16  address,IN UINT32   value);
UINT8 ReadIO8(IN UINT16);
UINT32 ReadIO32(IN UINT16);
#if (OS_TYPE !=0)
void outportb(UINT16 reg, UINT8 val);
void outportl(UINT16 reg, UINT32 val);
UINT8 inportb(UINT16 reg);
UINT32 inportl(UINT16 reg);
void delay(int val);
#endif

#if (OS_TYPE ==1) || (OS_TYPE ==4)
  #if WINIO_SUPPORT_BUILD && WINIO_SUPPORT
    BOOL Enable_WinIO();
    BOOL Free_WinIO();
  #elif !WINIO_SUPPORT_BUILD && WINIO_SUPPORT
    void SetPortVal (UINT32 address , UINT32  data , UINT8 byte);
    void GetPortVal (UINT32 address , UINT32 *data , UINT8 byte);
    void Sleep(UINT32 input);
    BOOL Enable_WinIO();
    BOOL Free_WinIO();
  #endif

#endif
//--------------------------//
//    debug Function Link    //
//--------------------------//
void UnusedVariable_error(void *  compilerWarning);

//--------------------------//
//    Argv Function Link    //
//--------------------------//




//<_START>
//-----------------------------------------------------------------------------------------------//
// FUNCTION   : Argv_Init
// INPUT      : argc,argv,*CommandTable,CommandTableSize
// OUTPUT     :
// DESCRIPTION:
//
//-----------------------------------------------------------------------------------------------//
//<_END>
int
Argv_Init(
  IN    int                 *argc,
  IN    char                *argv[],
  IN  int         checkPoint,
  IN    ONE_COMMAND *CommandTable,
  IN    int                 CommandTableSize
){
  int           status;
  UINT16            i,size;
  ONE_COMMAND *table;


  status     = EFI_FAIL;
  table          = CommandTable;
  size       = CommandTableSize;
 


  for(i=0;i<size;i++)
  {
      if(( strcmp(*(argv+checkPoint), (table+i)->argv1 ) == 0 ) || (strcmp(*(argv+checkPoint), (table+i)->argv1_t ) == 0))
       {
       
        status = (table+i)->Func_ptr(argc,argv);
 
        break;
       
        }
      else
         status = EFI_FAIL;      
     }

 
return status;
}




//<_START>
//-----------------------------------------------------------------------------------------------//
// Procedure    : CHECK_EFI_SIZE
// input        : address,value
// output       :
// Description  : check unsigned size by RD
//
//-----------------------------------------------------------------------------------------------//
//<_START>
void
CHECK_EFI_SIZE(
)
{
int *p;
            printf("sizeof(unsigned long )        = %d \n", (UINT32)sizeof(unsigned long)*8);
            printf("sizeof(unsigned long long)    = %d \n", (UINT32)sizeof(unsigned long long)*8);
            printf("sizeof(unsigned char)         = %d \n", (UINT32)sizeof(unsigned char)*8);
            printf("sizeof(unsigned short)        = %d \n", (UINT32)sizeof(unsigned short)*8);
            printf("sizeof(unsigned int)          = %d \n", (UINT32)sizeof(unsigned int)*8);
            printf("sizeof(*p)                    = %d \n", (UINT32)sizeof(p)*8);
}


//<_START>
//-----------------------------------------------------------------------------------------------//
// Procedure      : WriteIO8
// input        : UINT16 address,UINT8 value
// output       :
// Description      : Provid WritIO with delay
//
//-----------------------------------------------------------------------------------------------//
//<_START>
void
WriteIO8(
      IN UINT16  address,
      IN UINT8   value
){
 delay(1);//Don't Change

 outportb( address , value);
}

//<_START>
//-----------------------------------------------------------------------------------------------//
// Procedure      : ReadIO8
// input          : UINT16 address
// output         : UINT8  data
// Description    : Provid ReadIO with delay
//
//-----------------------------------------------------------------------------------------------//
//<_START>
UINT8
ReadIO8(
  IN UINT16 address
){
 delay(1);
 return inportb(address);//Don't Change
}


//<_START>
//-----------------------------------------------------------------------------------------------//
// Procedure      : WriteIO32
// input          : UINT16 address,UINT8 value
// output         :
// Description    : Provid WritIO with delay
//
//-----------------------------------------------------------------------------------------------//
//<_START>
void
WriteIO32(
      IN UINT16  address,
      IN UINT32  value
){
 delay(1);
 outportl( address , value);//Don't Change
}

//<_START>
//-----------------------------------------------------------------------------------------------//
// Procedure      : ReadIO32
// input          : UINT16 address
// output         : UINT32  data
// Description    : Provid ReadIO with delay
//
//-----------------------------------------------------------------------------------------------//
//<_START>
UINT32
ReadIO32(
  IN UINT16 address
){
 delay(1);
 return inportl(address);//Don't Change
}


//<_START>
//-----------------------------------------------------------------------------------------------//
// Procedure      : RWIO8
// input          : UINT16 address,UINT8 mask,UINT8 value
// output         :
// Description    : Provid WritIO with delay
//
//-----------------------------------------------------------------------------------------------//
//<_START>          
void
RWIO8(
      IN UINT16    address,
      IN UINT8     mask,
      IN UINT8     value
){

  WriteIO8(address,  (ReadIO8(address)  & mask )| value  );

}
//<_START>
//-----------------------------------------------------------------------------------------------//
// Procedure      : RWIO32  
// input          : UINT16 address,UINT32 mask,UINT32 value
// output         :
// Description    : Provid WritIO with delay
//
//-----------------------------------------------------------------------------------------------//
//<_START>          
void
RWIO32(
      IN UINT16    address,
      IN UINT32     mask,
      IN UINT32     value
){

  WriteIO32(address,  (ReadIO32(address)  & mask )| value  );

}

//<_START>
//-----------------------------------------------------------------------------------------------//
// Procedure      : UnusedVariable_error
// input          : void *
// output         :
// Description    : some variable for debug,but no use to user,
//          those variable will cause warning, but no matter.
//-----------------------------------------------------------------------------------------------//
//<_START>          
void
UnusedVariable_error(
        IN void *compilerWarning
){

}



//<_START>
//-----------------------------------------------------------------------------------------------//
// FUNCTION   : LOW LEVEL IO Porting
//-----------------------------------------------------------------------------------------------//
//<_END>
#if (OS_TYPE ==2) || (OS_TYPE == 5)//LINUX_SUPPORT

//WRITE
void
  outportb(UINT16 reg, UINT8 val){
  outb_p(val, reg);
}


void
  outportl(UINT16 reg, UINT32 val){
  outl_p(val, reg);
}

//READ
UINT8
  inportb(UINT16 reg){
  return inb_p(reg);
}

UINT32
inportl
(UINT16 reg)
{
  return inl_p(reg);
}

//Delay

void
  delay(int val)
{
usleep(val*1000); //Linux
//1 sec = usleep(1000000) //value = 1,000,000~0
//1 sec = sleep(1)
}
#elif (OS_TYPE ==1) || (OS_TYPE ==4) //WINDOWSx86/x64_SUPPORT

  #if WINIO_SUPPORT_BUILD && WINIO_SUPPORT
    BOOL Enable_WinIO(){
    BOOL bRet = EFI_FAIL;
   
  #if defined(_WIN64)
    hDLL = GetModuleHandle((LPCWSTR)L"WinIo64.dll");
    if(hDLL == NULL)
      hDLL = LoadLibrary((LPCWSTR)L"WinIo64.dll");
  #elif defined(_WIN32)
    hDLL = GetModuleHandle((LPCWSTR)L"WinIo32.dll");
    if(hDLL == NULL)
      hDLL = LoadLibrary((LPCWSTR)L"WinIo32.dll");
  #endif
   


    if (hDLL == NULL)
        {
          printf("Error load winio.dll fail. %08X\n", GetLastError());  
          return EFI_FAIL;
        }

    InitializeWinIo = (DLL_InitializeWinIo)GetProcAddress(hDLL, ("InitializeWinIo"));
    if (!InitializeWinIo)
        {
          // handle the error
          printf("Error InitializeWinIo fail. %08X\n", GetLastError());  
          FreeLibrary(hDLL);
          return EFI_FAIL;
        }

    RemoveWinIoDriver = (DLL_RemoveWinIoDriver)GetProcAddress(hDLL, ("RemoveWinIoDriver"));
    if (!RemoveWinIoDriver)
        {
          // handle the error
          printf("Error RemoveWinIoDriver fail. %08X\n", GetLastError());  
          FreeLibrary(hDLL);
          return EFI_FAIL;
        }  

    ShutdownWinIo = (DLL_ShutdownWinIo)GetProcAddress(hDLL, ("ShutdownWinIo"));
    if (!ShutdownWinIo)
        {
          // handle the error
          printf("Error ShutdownWinIo fail. %08X\n", GetLastError());  
          FreeLibrary(hDLL);
          return EFI_FAIL;
        }


    GetPortVal = (DLL_GetPortVal)GetProcAddress(hDLL, ("GetPortVal"));
    if (!GetPortVal)
        {
          // handle the error
          printf("Error GetPortVal fail. %08X\n", GetLastError());  
          FreeLibrary(hDLL);
          return EFI_FAIL;
        }

    SetPortVal = (DLL_SetPortVal)GetProcAddress(hDLL, ("SetPortVal"));
    if (!SetPortVal)
        {
        // handle the error
        printf("Error SetPortVal fail. %08X\n", GetLastError());  
        FreeLibrary(hDLL);
        return EFI_FAIL;
        }


        bRet = InitializeWinIo();
        if (!bRet)  
        {
          printf("Error during initialization of WinIo. %08X\n", GetLastError());
          FreeLibrary(hDLL);
          return EFI_FAIL;
        }
    return EFI_SUCCESS;
  }

  BOOL Free_WinIO(){
    BOOL bRet = FALSE;
    //if(OI_status != FALSE)
    bRet = RemoveWinIoDriver();
    ShutdownWinIo ();
    FreeLibrary(hDLL);  
    return bRet;
  }

//WRITE
void
outportb
(UINT16 reg, UINT8 val)
{
  SetPortVal(reg, (UINT32)val, 1 );
}


void
outportl
(UINT16 reg, UINT32 val)
{
  SetPortVal(reg, val , 4 );
}

//READ
UINT8
inportb
(UINT16 reg)
{
  UINT32 data;

  GetPortVal(reg , (PDWORD)&data , 1);
  return  (UINT8)(data);
}

UINT32
inportl
(UINT16 reg)
{
  UINT32 data;
  GetPortVal(reg , (PDWORD)&data , 4);
  return  data;
}

//Delay
void
  delay(int val)
{
  Sleep(val);
  //1 sec = Sleep(1000) //Windows
}
#elif !WINIO_SUPPORT_BUILD && WINIO_SUPPORT
  void SetPortVal (UINT32 address , UINT32 data , UINT8 byte){

  }

  void GetPortVal (UINT32 address , UINT32 *data , UINT8 byte){

   }


  void Sleep(UINT32 input){

 }


  BOOL Enable_WinIO(){

  return EFI_SUCCESS;
}

  BOOL Free_WinIO(){
    return EFI_SUCCESS;

}

 
//WRITE
void
outportb
(UINT16 reg, UINT8 val)
{

}


void
outportl
(UINT16 reg, UINT32 val)
{

}

//READ
UINT8
inportb
(UINT16 reg)
{

  UINT32 data=0;


  return  (UINT8)(data);
}

UINT32
inportl
(UINT16 reg)
{
  UINT32 data=0;
 
  return  data;
}

//Delay

 void
  delay(int val)
 {
 
 }
#endif //END notsupport WinIO in build

#endif //END OS_TYPE

//<_START>
//-----------------------------------------------------------------------------------------------//
// Procedure      : IO_Init
// input          :
// output         :
// Description    : If init IO fail,will report fail to stop project
//-----------------------------------------------------------------------------------------------//
//<_START>
int
IO_Init(
){
  int               status;
  BOOLEAN     OI_status;

  status        = EFI_SUCCESS;
  OI_status = FALSE;
 
       
  // - Linux - Enable High IO//
  #if( (OS_TYPE ==2) || (OS_TYPE == 5) )
    OI_status = iopl(3);
    if (OI_status == 0xFF ) {
    printf("Inital IO Fail\n");
    status = EFI_FAIL;
    }  
   
  //Suppoer Windows Enable Win IO
    #elif (WINIO_SUPPORT ==1) && ( (OS_TYPE ==1) || (OS_TYPE ==4) ) //Winx86 & Win_x64
    OI_status = Enable_WinIO();
    if(OI_status == EFI_FAIL) {
    printf("Inital IO Fail");
    getchar();
    status = EFI_FAIL;
    }
  #endif
 
  UnusedVariable_error( (void *)&OI_status);
  return status;
}

//<_START>
//-----------------------------------------------------------------------------------------------//
// Procedure      : IO_Free
// input          : void *
// output         :
// Description    : If free IO fail, don't have any error message
//-----------------------------------------------------------------------------------------------//
//<_START>
void
IO_Free(
){
  BOOLEAN    OI_status;
 
  OI_status = FALSE;
 
  // - Linux - //
  #if( (OS_TYPE ==2) || (OS_TYPE == 5) )
  iopl(0);
  //Suppoer Windows Free WinIO
  #elif (WINIO_SUPPORT ==1) && ( (OS_TYPE ==1) || (OS_TYPE ==4) ) //Winx86 & Win_x64
  OI_status = Free_WinIO();
  //  getchar();
  #endif


  //Windows compiler stop before release
  #if  (WINIO_SUPPORT_BUILD == 0) && ( (OS_TYPE ==1) || (OS_TYPE ==4) ) //Winx86 & Win_x64
  printf("Finish\n");
  getchar();
  #endif
 
  UnusedVariable_error((void *)&OI_status);
}





2017年9月23日 星期六

kernel\linux\Documentation\kbuild\makefiles.txt

kernel\linux\Documentation\kbuild\makefiles.txt




=== 1 Overview
=== 2 Who does what
=== 3 The kbuild files
--- 3.1 Goal definitions
--- 3.2 Built-in object goals - obj-y
--- 3.3 Loadable module goals - obj-m
--- 3.4 Objects which export symbols
--- 3.5 Library file goals - lib-y
--- 3.6 Descending down in directories
--- 3.7 Compilation flags
--- 3.8 Command line dependency
--- 3.9 Dependency tracking
--- 3.10 Special Rules
--- 3.11 $(CC) support functions


=== 4 Host Program support
--- 4.1 Simple Host Program
--- 4.2 Composite Host Programs
--- 4.3 Defining shared libraries
--- 4.4 Using C++ for host programs
--- 4.5 Controlling compiler options for host programs
--- 4.6 When host programs are actually built
--- 4.7 Using hostprogs-$(CONFIG_FOO)


=== 5 Kbuild clean infrastructure


=== 6 Architecture Makefiles
--- 6.1 Set variables to tweak the build to the architecture
--- 6.2 Add prerequisites to archprepare:
--- 6.3 List directories to visit when descending
--- 6.4 Architecture-specific boot images
--- 6.5 Building non-kbuild targets
--- 6.6 Commands useful for building a boot image
--- 6.7 Custom kbuild commands
--- 6.8 Preprocessing linker scripts


=== 7 Kbuild syntax for exported headers
--- 7.1 header-y
--- 7.2 objhdr-y
--- 7.3 destination-y
--- 7.4 unifdef-y (deprecated)


=== 8 Kbuild Variables
=== 9 Makefile language
=== 10 Credits
=== 11 TODO




1.

Makefile                                 the top Makefile. .config                         the kernel configuration file.
arch/$(ARCH)/Makefile           the arch Makefile.
scripts/Makefile.*                         common rules etc. for all kbuild Makefiles.
kbuild Makefiles                          there are about 500 of these.

        arch Makefile with the name arch/$(ARCH)/Makefile






3.0
The preferred name for the kbuild files are 'Makefile'
but 'Kbuild' can be used and
if both a 'Makefile' and a 'Kbuild' file exists, then the 'Kbuild' file will be used.


3.1
Built-in object goals - obj-y
(如果要built-in kernel 就將object 加入 obj-y list
)
Loadable module goals - obj-m
(如果單純只是module 就將object 加入 obj-m list)

ibrary file goals - lib-y
list objects that will be included in a library, lib.a.

ibrary file goals - lib-m
lib-m will be included in lib.a.

Example:
obj-$(CONFIG_FOO) += foo.o
  為了可以改變object的類別所以用變數$(CONFIG_xxxx) 代入m或y





3.2
The kbuild Makefile specifies object files for vmlinux in the $(obj-y) lists

Kbuild compiles all the $(obj-y) files.
It then calls "$(LD) -r" to merge these files into one built-in.o file.
built-in.o is later linked into vmlinux by the parent Makefile.

$(obj-y)  list上的接下來都會被compiler,並且透過"$(LD) -r"去產生built-in.o
這些built-in.o會被連結進 vmlinux


圖中每個目錄下都有各自的 built-in.o








3.3

 If a kernel module is built from several source files, you specify that you want to build a module in the same way as above.


module 可能包含很多個.o檔,最後產生.ko

Example:
#drivers/isdn/i4l/Makefile
obj-$(CONFIG_ISDN) += isdn.o
isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o


Example:
#fs/ext2/Makefile
       obj-$(CONFIG_EXT2_FS)                  += ext2.o
ext2-y                                                    := balloc.o bitmap.o
       ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o

被包入的.o也可以透過變數改變,如果CONFIG_EXT2_FS_XATTR是y,則會被包入kernel



3.4   Objects which export symbols

No special notation is required in the makefiles for modules exporting symbols.
..... ???

3.5
ibrary file goals - lib-y

Objects that are listed in obj-y and additionally listed in lib-y will not be included in the library, since they will be accessible anyway.

All objects listed with lib-y are combined in a single library for that directory.

Example:
#arch/i386/lib/Makefile
        lib-y    := checksum.o delay.o

This will create a library lib.a based on checksum.o and delay.o.
For kbuild to actually recognize that there is a lib.a being built,
the directory shall be listed in libs-y.

Use of lib-y is normally restricted to lib/ and arch/*/lib.

資料夾內產生 lib.a檔,通常會限制在lib/ 或arch/*/lib. 資料夾



3.6 Descending down in directories

ext2 lives in a separate directory, and the Makefile present in fs/
tells kbuild to descend down using the following assignment.

Example:
 #fs/Makefile
obj-$(CONFIG_EXT2_FS) += ext2/

如果添加目錄的方式,則會到下一層目錄執行下一層目錄的makefile


 
   linux/drivers/scsi/Makefile



       linux/drivers/Makefile



 
     linux/Makefile

    driver/scsi/  依 linux/drivers/Makefile最後產生  built-in.o 或 scsi_mod.ko
    driver/         依linux/Makefile 會產生 built-in.o
 



3.7

          (全域變數)
        ccflags-y, asflags-y and ldflags-y
        Flags with the same behaviour were previously named:
EXTRA_CFLAGS, EXTRA_AFLAGS and EXTRA_LDFLAGS.
ccflags-y specifies options for compiling C files with $(CC).
Example:
# drivers/sound/emu10k1/Makefile
ccflags-y += -I$(obj)
ccflags-$(DEBUG) += -DEMU10K1_DEBUG

asflags-y is a similar string for per-directory options when compiling assembly language source.
Example:
#arch/x86_64/kernel/Makefile
asflags-y := -traditional

ldflags-y is a string for per-directory options to $(LD).
Example:
#arch/m68k/fpsp040/Makefile
ldflags-y := -x

       (區域性,作用在subdir)
       subdir-ccflags-y,
       subdir-asflags-y
        (索有子目錄都會套用)
The two flags listed above are similar to ccflags-y and as-falgs-y.
The difference is that the subdir- variants has effect for the kbuild
file where tey are present and all subdirectories.
Options specified using subdir-* are added to the commandline before
the options specified using the non-subdir variants.
Example:
subdir-ccflags-y := -Werror

       (區域性,只作用在這個Makefile)
       CFLAGS_$@ and AFLAGS_$@ only apply to commands in current kbuild makefile.

      # drivers/scsi/Makefile
      CFLAGS_aha152x.o =   -DAHA152X_STAT -DAUTOCONF
      CFLAGS_gdth.o    =     -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \
            -DGDTH_STATISTICS
      CFLAGS_seagate.o =   -DARBITRATE -DPARITY -DSEAGATE_USE_ASM


3.9  Dependency tracking

Kbuild tracks dependencies on the following:
1) All prerequisite files (both *.c and *.h)
2) CONFIG_ options used in all prerequisite files
3) Command-line used to compile target

Thus, if you change an option to $(CC) all affected files will
be re-compiled.

如果更動了,所有相依的檔案會重新compiler
(也就是不會整個重新都build,有改動才會)



3.10 Special Rules

A typical example is header files generated during the build process.
Another example are the architecture-specific Makefiles which need special rules to prepare boot images etc.


    $(src)
$(src) is a relative path which points to the directory
where the Makefile is located. Always use $(src) when
referring to files located in the src tree.

    $(obj)
$(obj) is a relative path which points to the directory
where the target is saved. Always use $(obj) when
referring to generated files.

Example:
#drivers/scsi/Makefile
$(obj)/53c8xx_d.h: $(src)/53c7,8xx.scr $(src)/script_asm.pl
                         $(CPP) -DCHIP=810 - < $< | ... $(src)/script_asm.pl

    $(kecho)
echoing information to user in a rule is often a good practice
but when execution "make -s" one does not expect to see any output
except for warnings/errors.
To support this kbuild define $(kecho) which will echo out the
text following $(kecho) to stdout except if "make -s" is used.

Example:
#arch/blackfin/boot/Makefile
$(obj)/vmImage: $(obj)/vmlinux.gz
$(call if_changed,uimage)
@$(kecho) 'Kernel: $@ is ready'


3.11 $(CC) support functions

編譯可選用的功能
..
   cc-option-yn
cc-option-yn is used to check if gcc supports a given option
and return 'y' if supported, otherwise 'n'.

Example:
#arch/ppc/Makefile
biarch := $(call cc-option-yn, -m32)
aflags-$(biarch) += -a32
cflags-$(biarch) += -m32
...
...
..
4 Host Program support

Kbuild supports building executables on the host for use during the compilation stage.

ex.  compiler kernel 需要用到的工具

4.1
In some cases there is a need to compile and run a program on the
computer where the build is running.
The following line tells kbuild that the program bin2hex shall be
built on the build host.

Example:
hostprogs-y := bin2hex

Kbuild assumes in the above example that bin2hex is made from a single
c-source file named bin2hex.c located in the same directory as
the Makefile.


4.2

C Example:
#scripts/lxdialog/Makefile
hostprogs-y   := lxdialog
lxdialog-objs := checklist.o lxdialog.o

Objects with extension .o are compiled from the corresponding .c files.
         In the above example, checklist.c is compiled to checklist.o 
         and lxdialog.c is compiled to lxdialog.o.

Finally, the two .o files are linked to the executable, lxdialog.
Note: The syntax <executable>-y is not permitted for host-programs.

       (要產生build時期用的執行檔 lxdialog 必須用hostprogs-y 而非 lxdialog-y)


kbuild offers support for host programs written in C++. This was
introduced solely to support kconfig, and is not recommended
for general use.



--- 4.3 Defining shared libraries

Objects with extension .so are considered shared libraries, and
will be compiled as position independent objects.
Kbuild provides support for shared libraries, but the usage
shall be restricted.


In the following example the libkconfig.so shared library is used
to link the executable conf.

Example:
#scripts/kconfig/Makefile
hostprogs-y     := conf
conf-objs       := conf.o libkconfig.so
libkconfig-objs := expr.o type.o

Shared libraries always require a corresponding -objs line,
        and in the example above the shared library libkconfig is composed by the two objects
        expr.o and type.o.
expr.o and type.o will be built as position independent code and
linked as a shared library libkconfig.so.

       C++ is not supported for shared libraries.
        (compiler工具時也可以使用lib,但使用上必須很小心,例如工具在compiler PC 64bit上使用,而產生的kernel是32 bit system)

C static function/static inline

測試1:
嘗試呼叫 static void say_hello()
main.c
#include <stdlib.h>
#include "hello.h"
int main(){
  say_hello();
return 0;
}


hello.h
#ifndef HELLO_H
#define HELLO_H
static void say_hello();
void hello();

#endif

hello.c
#include <stdio.h>
#include <stdlib.h>

#include "hello.h"
static void say_hello()
{
  printf("hello\n");
}

void hello()
{
 say_hello();

}


Makefile
#
# make file
# JoeChang
PROJECT = sample
LIBS    = 
CFLAGS  = -Wall -O2  -pthread


CC      := g++
CFILES  := $(wildcard *.c)
OBJS    = $(CFILES:.c=.o) 


.PHONY: all clean
all: clean $(PROJECT) 
@echo -e "Done,...but maybe need make clean"
-rm *.o  

$(PROJECT): $(OBJS) 
$(CC) $(CFLAGS) $(LIBS)  $(OBJS) -o  $@

$(OBJS): $(CFILES)
$(CC) $(CFLAGS) $(LIBS)  -c $(CFILES)


clean: 
@echo clean All done
-rm *.o

-rm ${PROJECT}

Result: 
    compiler error 無法呼叫static
    undefined reference to `say_hello()'
  




測試2:
main.c
#include <stdlib.h>
#include "hello.h"
int main(){
     hello();
return 0;
}



hello.h
#ifndef HELLO_H
#define HELLO_H
static void say_hello();
void hello();
#endif

hello.c
#include <stdio.h>
#include <stdlib.h>

#include "hello.h"
static void say_hello()
{
  printf("hello\n");
}

void hello()
{
 say_hello();

}


Makefile
#
# make file
# JoeChang
PROJECT = sample
LIBS    = 
CFLAGS  = -Wall -O2  -pthread


CC      := g++
CFILES  := $(wildcard *.c)
OBJS    = $(CFILES:.c=.o) 


.PHONY: all clean
all: clean $(PROJECT) 
@echo -e "Done,...but maybe need make clean"
-rm *.o  

$(PROJECT): $(OBJS) 
$(CC) $(CFLAGS) $(LIBS)  $(OBJS) -o  $@

$(OBJS): $(CFILES)
$(CC) $(CFLAGS) $(LIBS)  -c $(CFILES)


clean: 
@echo clean All done
-rm *.o

-rm ${PROJECT}

Result:
  compiler warning
  declared 'static' but never defined [-Wunused-function]


  得知: static void say_hello()不該寫再Header file

測試3:
static void say_hello()從head file移除
main.c
#include <stdlib.h>
#include "hello.h"
int main(){
     hello();
return 0;
}


hello.h
#ifndef HELLO_H
#define HELLO_H

void hello();

#endif

hello.c
#include <stdio.h>
#include <stdlib.h>

#include "hello.h"
static void say_hello()
{
  printf("hello\n");
}

void hello()
{
 say_hello();

}


Makefile
#
# make file
# JoeChang
PROJECT = sample
LIBS    = 
CFLAGS  = -Wall -O2  -pthread


CC      := g++
CFILES  := $(wildcard *.c)
OBJS    = $(CFILES:.c=.o) 


.PHONY: all clean
all: clean $(PROJECT) 
@echo -e "Done,...but maybe need make clean"
-rm *.o  

$(PROJECT): $(OBJS) 
$(CC) $(CFLAGS) $(LIBS)  $(OBJS) -o  $@

$(OBJS): $(CFILES)
$(CC) $(CFLAGS) $(LIBS)  -c $(CFILES)


clean: 
@echo clean All done
-rm *.o

-rm ${PROJECT}

Result:
  compiler pass,
  test pass.

  





2016年1月1日 星期五

linux driver sample

main.c main.h sub.c sub.h test.c ==> wdt.ko test
這範例是註冊一個class並由系統提供空的掛載點
如果要修改只需要把紫色部分和control 修改掉即可。
Makefile寫的不是很好..恩..


driver       是在kernel space
一般程式 是在user space
OS開機時候可以設定kernel space star address


Linux driver有分:
-內建在系統中
-開機後啟動(如果牽涉到DMA可能會有機率性的拿不到連續實體記憶體buffer)


driver的好處:
多個user app都想控制同一個硬體

注意:
掛載時候有些範例會用mknod 並且指定掛載點(0-255任選)
這方法可用但是不好,
掛在點如果已經有裝置存在會掛載不上去
因此要改由系統提供沒人用的掛載代號(0-255)


Makefile

#------------#
#   Project  #
#------------#

#project name do not same CFILES file name
PROJECT := wdt
TEST    := test
Help    := help
UNINSTALLFILE:=uninstall

#add your any file
CFILES  := main.c sub1.c



#Detect Dymaic D_MAJOR
D_MAJOR :=$(shell grep $(PROJECT) /proc/devices | awk '{print $$1;}')

#Total Minor 1-4
MINOR_DEV_TOTAL :=1

#---------------#
#Global Variable#
#---------------#
KDIR  := /lib/modules/$(shell uname -r)/build
KVERSION := $(shell uname -r)
PWD      := $(shell pwd)
DEV_PATH :=/dev/$(PROJECT)
LIBS  :=
CFLAGS:=
#---------------#
#   Other File  #
#---------------#
CONFFILE    :=project.h


#---------------------------------------#
#compiler                               #
#---------------------------------------#
#-not change-#
obj-m           := $(PROJECT).o


#-not change-#
$(PROJECT)-objs := $(CFILES:.c=.o)





#----------------------#
#          All         #
#----------------------#
all: $(UNINSTALLFILE).sh $(PROJECT) $(TEST) $(Help)

$(PROJECT):
ifeq ($(USER),root)
 @echo  "#define DEV_PATH   \"$(DEV_PATH)\""          >> $(CONFFILE)
 @echo  "#define DRIVER_NAME \"$(PROJECT)\""          >> $(CONFFILE)
 @echo  "#define MINOR_DEV_TOTAL $(MINOR_DEV_TOTAL)"  >> $(CONFFILE)
 @echo  " "                                           >> $(CONFFILE)
 @$(MAKE) -s -C $(KDIR) M=$(PWD) modules
else
 #echo USER is not root!!
endif




#----------------------#
#  install             #
#----------------------#
install : $(PROJECT).ko $(UNINSTALLFILE).sh
 @cp -f $(UNINSTALLFILE).sh _$(UNINSTALLFILE).sh
ifeq (,$(findstring $(PROJECT),$(shell lsmod | grep $(PROJECT))))
  ifeq ($(wildcard /lib/modules/$(PROJECT)),)
  @mkdir -p /lib/modules/$(PROJECT)
  @cp -f $(PROJECT).ko /lib/modules/$(PROJECT)
  @insmod /lib/modules/$(PROJECT)/$(PROJECT).ko
  endif
  ifeq (,$(findstring $(PROJECT).ko,$(shell cat  /etc/rc.local | grep $(PROJECT).ko)))
  @echo insmod /lib/modules/$(PROJECT)/$(PROJECT).ko >> /etc/rc.local
  endif
else
 @echo Please run ./uninstall to remove driver
endif





#----------------------#
#  uninstall           #
#----------------------#
$(UNINSTALLFILE).sh:
 @echo rm -rf  /lib/modules/$(PROJECT)    >> $(UNINSTALLFILE).sh
 @echo rm -f   /dev/$(PROJECT)0           >> $(UNINSTALLFILE).sh
 @#@echo rm -f   /dev/$(PROJECT)1         >> $(UNINSTALLFILE).sh
 @echo rmmod  $(PROJECT)                  >> $(UNINSTALLFILE).sh


.uninstall:
ifeq ($(wildcard /lib/modules/$(PROJECT)),"/lib/modules/$(PROJECT)")
 @rm -rf  /lib/modules/$(PROJECT)
endif

ifeq (   $(findstring "$(PROJECT)" , $(shell lsmod) ) , $(PROJECT))
 rmmod -vf  $(PROJECT)       
endif


#----------------------#
#       Test           #
#----------------------#
$(TEST): $(TEST).o
 gcc -o $@ $(TEST).o -pthread -Wall -O2


#----------------------#
#       Help           #
#----------------------#
$(Help):
 @echo    Joe.Chang 02/02/2015                         
 @echo //----------------------------------------------//
 @echo "//                   help                       //"
 @echo //----------------------------------------------//
 @echo 1. make all       make Project.ko  and test     
 @echo 2. make install   install driver                 
 @echo 3. ./uninstall.sh only clean run-time status     
 @echo 4. make clean     only clean build file         
 @echo                                                 
 @echo If U get Error:                                 
 @echo A. ./uninstall.sh ,                             
 @echo B. make clean                                   


#---------------------------------------#
#              Clean  Build file        #
#---------------------------------------#
clean:
ifeq ($(wildcard /lib/modules/$(PROJECT)),)
 @$(MAKE) -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
 @rm -f $(CONFFILE) $(TEST) $(UNINSTALLFILE).sh
 @rm -f *.bak
else
 @echo make clean is for clean module buld
 @echo
 @echo "error: Please Run ./uninstall before make clean."
 @echo "(Note: If you lose \"uninstall.sh\" try [./_uninstall.sh])"
endif


macro.h
#ifndef H_MARCO
#define H_MARCO

//Strize
#define _STR(s) #s
#define STR(s) _STR(s)

#define _DEV_CAT #s#%%d
#define DEV_CAT(s) _DEV_CAT(s)
#endif


Driver_API(main.h)
#ifndef H_MAIN
#define H_MAIN

#include <linux/ioctl.h>


//first char descritp your driver
#define MAGIC_CHAR 'w'


/* Set  watchdog timer */
#define IOCTL_WDT_TIMER_SET            _IOW(MAGIC_CHAR,  1, int)


/* Start/Stop Watchdog timer */
#define IOCTL_WDT_START_STOP            _IOW(MAGIC_CHAR, 2, int)




#endif //H_MAIN

Driver_method(main.c)
#include <linux/module.h>
#include <linux/kernel.h>

/*init device*/
#include <linux/kdev_t.h>  /* MKDEV*/
#include <linux/cdev.h>    /* MKDEV*/
#include <linux/device.h>  /* class_create  :auto-mknod*/


/*file system*/
#include <linux/fs.h>      /*struct file_operations imajor*/
#include <linux/sched.h>    /*current*/
#include <asm/current.h>    /*current*/
#include <asm/uaccess.h>   /* copy from user*/



#include "project.h"
#include "main.h"
#include "sub1.h"
#include "marco.h"



#ifndef LINUX_VERSION_CODE
#include <linux/version.h>
#else
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#endif

//--------------------------//
//    MAIN DEFINE           //
//--------------------------//
//register driver
#define DRIVER_AUTHOR        "Joe Chang <joe_chang@Intel.com.tw"
#define DRIVER_DESCRIPTION   "A sample driver"
#define DRIVER_VERSION       1.00

#ifndef THIS_LICENCE
#define THIS_LICENCE     "Dual BSD/GPL"
#endif


#ifndef DRIVER_NAME
#define DRIVER_NAME  "sample"
#endif

#define DRIVER_NAME_BUFFER 32


#ifndef MINOR_DEV_TOTAL
#define MINOR_DEV_TOTAL   1
#endif

#if    MINOR_DEV_TOTAL == 0
#undef MINOR_DEV_TOTAL
#define MINOR_DEV_TOTAL 1
#endif



//--------------------------//
//    User Variable  Define //
//--------------------------//
//static int wdt_timer = 0;



//--------------------------//
//    routine Variable      //
//--------------------------//
/* lock device prevent muti-uers */
static  int lock       = 0;
static  int dev_major  = 0;
static  int dev_minor  = 0;

static unsigned int number_of_devices = MINOR_DEV_TOTAL; //if 3 ,mean /dev/sample0~2
static struct cdev sample_cdev;


static struct class *this_class = NULL;
static dev_t  class_sample_dev[MINOR_DEV_TOTAL];



//--------------------------//
//    ioctrl Variable       //
//--------------------------//
static  int wdt_timer = 0;


//<Intel_START>
//-----------------------------------------------------------------------------------------------//
// FUNCTION   : sample_probe
// INPUT      :
// OUTPUT     :
// DESCRIPTION:
//
//-----------------------------------------------------------------------------------------------//
//<Intel_END>
static int sample_probe(struct inode * inode, struct file * file)
{

printk("%s major%d minor%d(pid%d)\n", __func__ , imajor(inode), iminor(inode)
, current->pid);
// one one process can control this device at same time
if(lock) return -EBUSY;
//lock = 1;


return 0;

}

//<Intel_START>
//-----------------------------------------------------------------------------------------------//
// FUNCTION   : sample_remove
// INPUT      :
// OUTPUT     :
// DESCRIPTION:
//
//-----------------------------------------------------------------------------------------------//
//<Intel_END>
static int sample_remove(struct inode * inode, struct file * file)
{
//Free Device
lock = 0;

return 0;

}

//<Intel_START>
//-----------------------------------------------------------------------------------------------//
// FUNCTION   : sample_ioctl
// INPUT      :
// OUTPUT     :
// DESCRIPTION:
//
//  Joe: driver data is at kernel space space block !!
//
//  A:
//  copy data of "user space memory " to kernel space memory
//  static inline __must_check long __copy_from_user(void *to,const void __user * from, unsigned long n)
//
//  copy_to_user();
//-----------------------------------------------------------------------------------------------//
//<Intel_END>
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) )
static int sample_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
#else
static long sample_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
#endif
{

int value;


if( copy_from_user(&value, (void *)arg, sizeof(value)) )
return -EFAULT;



  switch(cmd)
        {
       
case IOCTL_WDT_TIMER_SET:
                      wdt_timer=value;
                      if ( (wdt_timer < 0 ) || (wdt_timer > 255))
                        {
                          printk(KERN_ERR "wdt_drv error: Invalid time value\n");
                            wdt_timer=0;
                            return -EOPNOTSUPP;
                        }
                     break;

case IOCTL_WDT_START_STOP:
if(value == WDT_START )
nct6776_wdt_start(wdt_timer);
else if(value == WDT_STOP)
nct6776_wdt_stop();
else 
return -EOPNOTSUPP;
break;

default:
                 return -EOPNOTSUPP;
                 break;
        }
     

return 0;
}


//--------------------------------------------//
//    file_operations protocol                //
//--------------------------------------------//
/* http://www.faqs.org/docs/kernel/x571.html */
static const struct file_operations sample_protocol = {
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) )
.ioctl = sample_ioctl,
#else
.unlocked_ioctl = sample_ioctl,
#endif
.open = sample_probe,
.release = sample_remove
};







//--------------------------//
//    remove device         //
//--------------------------//
void
remove_device(void)
{
dev_t remove_dev = MKDEV( dev_major , 0 );

cdev_del(&sample_cdev);
unregister_chrdev_region( remove_dev , number_of_devices );
}


//--------------------------//
//    remove class          //
//--------------------------//
void
remove_class(void)
{
int i;


for( i = 0 ; i < number_of_devices ; i ++)
{
 device_destroy( this_class , class_sample_dev[i] );
}
class_destroy(this_class);

}

//--------------------------//
//    free driver    API    //
//--------------------------//
void sample_exit(void)
{

  remove_class();            
  remove_device();


lock = 0;

printk("%s  Sample Driver -- Unloaded\n", DRIVER_NAME);
printk("=====================================================\n");
}


//--------------------------//
//    init driver           //
//--------------------------//

int
init_register_driver(void)
{
int ret=0,newMajor=0;
dev_t dev = MKDEV(dev_major ,0  );

  printk("number_of_devices %d\n",number_of_devices  );

 
  /*Get Dynamic major number*/
  /*  https://www.kernel.org/doc/htmldocs/kernel-api/API-alloc-chrdev-region.html   */
  ret = alloc_chrdev_region(&dev , 0 ,number_of_devices , DRIVER_NAME );
  if(ret)
  goto error_alloc;

 
  newMajor = MAJOR(dev);
  //Check, is major change?
  if( dev_major != newMajor){
  printk("%s Major %d is changed to %d\n",DRIVER_NAME,dev_major,newMajor );
  dev_major = newMajor;
  }


  /*define file_oprations */
  cdev_init(&sample_cdev,&sample_protocol);
  sample_cdev.owner = THIS_MODULE;
  sample_cdev.ops   = &sample_protocol;

  /*  Register driver in Kernel */
  /*  int cdev_add(struct cdev *cdev ,dev_t dev , unsigned count);  */
  ret = cdev_add(&sample_cdev, MKDEV(dev_major,dev_minor), number_of_devices );
  if(ret)
  goto err_cdev_add;


return 0;


err_cdev_add:
    printk("err_cdev_add\n");
    unregister_chrdev_region(dev,number_of_devices);
      return -1;



error_alloc:
    printk("error_alloc\n");
    return -1;
}


//--------------------------//
//    init driver   FS      //
//--------------------------//

int
init_register_file_system(void)
{
struct device *class_dev;
char   minor_name[DRIVER_NAME_BUFFER];
int    i;


  /*Register Class in filesystem*/
  this_class = class_create( THIS_MODULE,DRIVER_NAME);
  if(IS_ERR(this_class))
  goto error_class;





  /*mount fs dev in filesystem*/
  /* struct device * device_create ( struct class * class,struct device * parent,dev_t devt,void * drvdata,const char * fmt,...) */
  for( i = 0 ; i <  number_of_devices ; i ++)
  {
   class_dev = NULL;
   dev_minor = i;

  strcpy(minor_name ,DRIVER_NAME);
  strcat(minor_name,"%d");
 
  class_sample_dev[dev_minor] = MKDEV( dev_major, dev_minor);
   
//   class_dev = device_create (this_class,NULL,class_sample_dev[dev_minor],NULL, driver_name ,dev_minor);
class_dev = device_create (this_class,NULL,class_sample_dev[dev_minor],NULL, minor_name ,dev_minor);
  if(class_dev == NULL )
  {
  printk(KERN_ERR  "%s driver(major%d minor%d) installed fail.\n",minor_name ,dev_major, dev_minor);
  goto err_cdev_add;
  }
  else
      printk("%s Driver(major%d minor%d) installed at /sys/class/%s/%s%d.\n",DRIVER_NAME, dev_major, dev_minor,DRIVER_NAME ,DRIVER_NAME,dev_minor);
  }
 



return 0;
 
 
error_class:
    printk("error_class\n");
    return -1;
   
err_cdev_add:
    printk(KERN_ALERT "%s driver(major %d) installed fail.\n",DRIVER_NAME ,dev_minor);
    remove_class();
      return -1;
}

//--------------------------//
//    init API              //
//--------------------------//
int sample_init(void)
{

int ret = 0;
 
    printk("=====================================================\n");
    printk("Sample %s Driver: init\n",DRIVER_NAME);

    ret = init_register_driver();
  if(ret < 0 )
  goto init_register_driver_error;

init_register_file_system();
  if(ret < 0 )
  goto init_register_file_system_error;

    printk("%s Driver init pass\n", DRIVER_NAME );
 

return 0;


init_register_driver_error:
printk("Sample %s Driver: init driver fail \n",DRIVER_NAME);
  return ret;
 
init_register_file_system_error:  
remove_device();
remove_class();
printk("Sample %s Driver: init fs fail \n",DRIVER_NAME);
  return ret;
}




//-------------//
//Module define//
//-------------//
/*
 * The following license idents are currently accepted as indicating free
 * software modules
 *
 *      "GPL"                           [GNU Public License v2 or later]
 *      "GPL v2"                        [GNU Public License v2]
 *      "GPL and additional rights"     [GNU Public License v2 rights and more]
 *      "Dual BSD/GPL"                  [GNU Public License v2
 *                                       or BSD license choice]
 *      "Dual MIT/GPL"                  [GNU Public License v2
 *                                       or MIT license choice]
 *      "Dual MPL/GPL"                  [GNU Public License v2
 *                                       or Mozilla license choice]
 *
 * The following other idents are available
 *
 *      "Proprietary"                   [Non free products]
 *
 * There are dual licensed components, but when running with Linux it is the
 * GPL that is relevant so this is a non issue. Similarly LGPL linked with GPL
 * is a GPL combined work.
 *
 * This exists for several reasons
 * 1.   So modinfo can show license info for users wanting to vet their setup
 *      is free
 * 2.   So the community can ignore bug reports including proprietary modules
 * 3.   So vendors can do likewise based on their own policies
 */
MODULE_LICENSE(THIS_LICENCE);
/* Author, ideally of form NAME[, NAME]*[ and NAME] */
MODULE_AUTHOR(DRIVER_AUTHOR);

 /* What your module DESCRIPTION. */
MODULE_DESCRIPTION(DRIVER_DESCRIPTION);


//---------//
//  Module //
//---------//
module_init(sample_init);
module_exit(sample_exit);


Chip_Control_API(sub.h)
#if __linux
#define inportb(x) inb_p(x)
#define outportb(x, y) outb_p(y, x)
#define inportl(x) inl_p(x)
#define inportw(x) inw_p(x)
#define outportl(x, y) outl_p(y, x)
#endif 

/* Start/Stop WDT */
#define WDT_START                       0
#define WDT_STOP                        1




void nct6776_config_enter(void);
void nct6776_config_exit(void);


unsigned char nct6776_read_reg (int LDN, int reg);
void nct6776_write_reg(int LDN, int reg, int value);

void nct6776_wdt_start(int timer);
void nct6776_wdt_stop(void);

Chip_control_method(sub.c)

#if __linux
#define delay(x) usleep(x)
#endif



//#ifdef MODULE
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <linux/delay.h>
#undef delay
#define delay(x) mdelay(x)
#undef fprintf
#define fprintf(S, A)  printk(A)
//#endif //MODULE

//#ifdef KLD_MODULE
//#include <sys/types.h>
//#include <sys/param.h>
//#include <sys/systm.h>
//#include <sys/malloc.h>
//#include <sys/kernel.h>
//#include <sys/bus.h>
//#include <sys/errno.h>
//#include <machine/bus.h>
//#include <machine/resource.h>
//#endif



/* local include file */
#include "sub1.h"





#define INDEX_PORT 0x2E
#define DATA_PORT  0x2F


//<Intel_START>
//-----------------------------------------------------------------------------------------------//
// FUNCTION   : nct6776_config_enter
// INPUT      : 
// OUTPUT     :
// DESCRIPTION: 
//-----------------------------------------------------------------------------------------------//
//<Intel_END>
void 
nct6776_config_enter(
void
){
        outportb(INDEX_PORT, 0x87); // Must Do It Twice
        outportb(INDEX_PORT, 0x87);
        return;
}

//<Intel_START>
//-----------------------------------------------------------------------------------------------//
// FUNCTION   : nct6776_config_exit
// INPUT      : 
// OUTPUT     :
// DESCRIPTION: 
//-----------------------------------------------------------------------------------------------//
//<Intel_END>
void 
nct6776_config_exit(
void
){
        outportb(INDEX_PORT, 0xAA);
        return;
}

//<Intel_START>
//-----------------------------------------------------------------------------------------------//
// FUNCTION   : main
// INPUT      : 
// OUTPUT     :
// DESCRIPTION: 
//-----------------------------------------------------------------------------------------------//
//<Intel_END>
unsigned char 
nct6776_read_reg(
int LDN, 
int reg
){
        unsigned char tmp = 0;


        nct6776_config_enter();
        outportb(INDEX_PORT, 0x07); // LDN Register
        outportb(DATA_PORT, LDN); // Select LDNx
        outportb(INDEX_PORT, reg); // Select Register
        tmp = inportb( DATA_PORT ); // Read Register
        nct6776_config_exit();
        return tmp;
}

//<Intel_START>
//-----------------------------------------------------------------------------------------------//
// FUNCTION   : nct6776_write_reg
// INPUT      : 
// OUTPUT     :
// DESCRIPTION: 
//-----------------------------------------------------------------------------------------------//
//<Intel_END>
void 
nct6776_write_reg(
int LDN, 
int reg, 
int value
){
        nct6776_config_enter();
        outportb(INDEX_PORT, 0x07); // LDN Register
        outportb(DATA_PORT, LDN); // Select LDNx
        outportb(INDEX_PORT, reg); // Select Register
        outportb(DATA_PORT, value); // Write Register
        nct6776_config_exit();
        return;
}

//<Intel_START>
//-----------------------------------------------------------------------------------------------//
// FUNCTION   : nct6776_wdt_start
// INPUT      : 
// OUTPUT     :
// DESCRIPTION: 
//-----------------------------------------------------------------------------------------------//
//<Intel_END>
void 
nct6776_wdt_start(
int timer
){
unsigned char tmp;

nct6776_config_enter();

/* clear status bit */
tmp=nct6776_read_reg(0x08, 0xf7);
tmp &= ~(0x10);
nct6776_write_reg(0x08, 0xf7, tmp);

/* clear timeout value */
nct6776_write_reg(0x08, 0xf6, 0x00);

/* set to count with second */
tmp=nct6776_read_reg(0x08, 0xF5);
tmp &= ~(0x08);
nct6776_write_reg(0x08, 0xF5, tmp);


/* set WDT Reset Event */
tmp=nct6776_read_reg(0x08, 0xF7);
tmp = (0x00);
nct6776_write_reg(0x08, 0xF7, tmp);

/* Set function enable */
tmp=nct6776_read_reg(0x08,0x30);
tmp |= 0x01;
nct6776_write_reg(0x08, 0x30, tmp);

/* fill in timeout value */
nct6776_write_reg(0x08, 0xf6, timer);
nct6776_config_exit();
return;
}

//<Intel_START>
//-----------------------------------------------------------------------------------------------//
// FUNCTION   : nct6776_wdt_stop
// INPUT      : 
// OUTPUT     :
// DESCRIPTION: 
//-----------------------------------------------------------------------------------------------//
//<Intel_END>
void 
nct6776_wdt_stop(
void
){
nct6776_config_enter();

/* stop timer */
nct6776_write_reg(0x08, 0xf6, 0);
nct6776_config_exit();
}







test.c
#include <stdio.h>
#include <unistd.h> /*close*/
#include <fcntl.h> /*close*/

#include <unistd.h> //1s=sleep(1) 1s=usleep(1000000)
// < -- http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread.h.html -- >
#include <pthread.h>     // Muti-thread Library UNIX only


#include <string.h> /*memset*/
#include "project.h"
#include "main.h"
#include "sub1.h"


#ifndef DEV_PATH
#define DEV_PATH "/dev/wdt_drv"
#endif


#ifndef MINOR_DEV_TOTAL
#define MINOR_DEV_TOTAL 1
#endif


#define delay(x) usleep(x)




//<Intel_START>
//-----------------------------------------------------------------------------------------------//
// FUNCTION   : help
// INPUT      :
// OUTPUT     :
// DESCRIPTION:
//-----------------------------------------------------------------------------------------------//
//<Intel_END>
void help(char* argv0)
{
        printf("%s -t xxx     (Set   Watchdog Timer 1-255 seconds)\n", argv0);
        printf("%s -auto    (Auto Start Watchdog Timer)\n"         , argv0);
        printf("%s -start   (Start Watchdog Timer)\n"              , argv0);
        printf("%s -stop    (Stop  Watchdog Timer)\n"              , argv0);
}



//<Intel_START>
//-----------------------------------------------------------------------------------------------//
// Procedure      : Auto_Thread
// input          : Function PTR
// output         :
// Description    :

//-----------------------------------------------------------------------------------------------//
//<Intel_START>          
void
Auto_Thread(
void (*Function)(void *)
){
int        status;
pthread_t  thread1;
  char       gch;
  void      *fptr;

        fptr = Function;

    status = -1;


status = pthread_create(&thread1, NULL, fptr, NULL);
if(status == 1)
{
printf("Create Thread Fail\n");
return;
}
else
printf("Create Thread Success-->  Working in back \n");
printf("Press Q to exit\n");

//Wait User press 'Q'
do{
  gch = getchar();

    if(gch == 'q')
{
printf("Cancel!!");
pthread_cancel(thread1);//The pthread_cancel() function shall request that thread be  canceled
   }
  }while(  (gch != 'q') && (gch != 'Q' ) );

      pthread_join(thread1,NULL);//Wait Thread finish
   

//Wait thread finish
  pthread_join(thread1,NULL);//Wait Thread finish
}



//<Intel_START>
//-----------------------------------------------------------------------------------------------//
// FUNCTION   : start_wdt
// INPUT      :
// OUTPUT     :
// DESCRIPTION:
//-----------------------------------------------------------------------------------------------//
//<Intel_END>
void auto_start_wdt(){
        int devfd;
        int value;
     
iopl(3);
     
     
     
     
        do{
       
         printf("Press Q to exit\n");
        devfd = open(DEV_PATH, O_RDONLY);
        if( devfd != -1)
        {
        printf("Start WDT Timer....");
        value = WDT_START;
              if( ioctl(devfd, IOCTL_WDT_START_STOP, &value) != 0)
                        printf("Fail\n");
              else
                        printf("OK\n");
         }else
          printf("Open Fail\n");
         
        close(devfd);
        usleep(500000);
        }while(1);
     
        iopl(0);      
}

//<Intel_START>
//-----------------------------------------------------------------------------------------------//
// FUNCTION   : main
// INPUT      :
// OUTPUT     :
// DESCRIPTION:
//-----------------------------------------------------------------------------------------------//
//<Intel_END>
int main( int argc, char** argv )
{
        int devfd[MINOR_DEV_TOTAL];
        char files[512];
     
     
        char *dev_name="/dev/sample";
        int value;
int Seladdress;
int i;
     


for( i = 0 ; i < MINOR_DEV_TOTAL ; i++ )
{
memset(files,0,512);
snprintf( files , sizeof(files) ,"%s%d" ,dev_name,i);
  devfd[i] = open(files, O_RDONLY);
  if(devfd[i] == -1 )
  printf("Open \"%s\" Fail\n",files);
  else
  printf("Open \"%s\" OK\n",files);
 
}


sleep(10);


for( i = 0 ; i < MINOR_DEV_TOTAL ; i++ )
{
printf("Device %d Close\n",i);
 close(devfd[i]);
}

/*
        if ( argc < 2) {
                help(argv[0]);
                return -1;
        }


iopl(3);
        devfd = open(DEV_PATH, O_RDONLY);
        if(devfd == -1)
        {
                printf("Can't open %s\n",DEV_PATH);
                iopl(0);
                return -1;
        }
     
     
     
if ( !strcmp(argv[1], "-t"))
{
                int tmp;
                if (argc !=3) {
                        printf("No timer input\n");
                        close(devfd);
                        iopl(0);
                        return -1;
                }
             
                tmp = atoi(argv[2]);
                if ( (tmp < 1) || (tmp > 255)) {
                        printf("Wrong timer value, please input range (1-255)\n");
                        close(devfd);
                        return -1;
                }
             

                printf("Set WDT Timer....");
                if( ioctl(devfd, IOCTL_WDT_TIMER_SET, &tmp) != 0)
                        printf("Fail\n");
                else
                        printf("OK\n");

        }
  else if ( !strcmp(argv[1], "-start")) {
                printf("Start WDT Timer....");
value = WDT_START;
                if( ioctl(devfd, IOCTL_WDT_START_STOP, &value) != 0)
                        printf("Fail\n");
                else
                        printf("OK\n");
        }
        else if ( !strcmp(argv[1], "-auto")) {
        close(devfd);
        printf("Please Setting Time Before Auto Start!!\n");
        Auto_Thread(auto_start_wdt);
        }
  else if ( !strcmp(argv[1], "-stop")) {
                printf("Stop WDT Timer....");
value = WDT_STOP;
                if( ioctl(devfd, IOCTL_WDT_START_STOP, &value) != 0)
                        printf("Fail\n");
                else
                        printf("OK\n");
        }


else {
printf("Unknow Error!!\n");
                help(argv[0]);
}


        close(devfd);
        iopl(0);
        return 0;
*/
}