關於我自己

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.