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
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
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
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
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)
=== 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/Makefile
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 需要用到的工具
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()
測試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
嘗試呼叫 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()'
#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]
測試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.
將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.
訂閱:
文章 (Atom)