Linux內核0.11 makefile文件說明

#
# if you want the ram-disk device, define this to be the
# size in blocks.
# 若是要使用 RAM 就定義塊的大小(註釋掉了),這是一個編譯時參數,若是定義了在下面會用到。
RAMDISK = #-DRAMDISK=512

AS86	=as86 -0 -a  #8006彙編的編譯器和鏈接器。後面參數分別是:
LD86	=ld86 -0 	 # -0 生成8086目標程序, -a 生成與gas 和 gld部分兼容的代碼。

AS	=gas  #GNU 彙編器和鏈接器。
LD	=gld
LDFLAGS	=-s -x -M  # gld 參數,-s 輸出文件中省略全部符號信息, -x 刪除全部局部符號, -m 在標準輸出設備上打印鏈接映像
                   #鏈接映像是指由鏈接程序程序產生的一種內存地址映像,列出了程序段裝到內存中的位置信息。具體指:
                   #1.目標文件及符號信息映射到內存中的位置
                   #2.公告符號如何放置
                   #3.鏈接中包含的全部文件及其引用的符號

# gcc GNU編譯器,引用定義的符號時,須要在前面加上$符號,並用括號把定義的標識符括起來。 
CC	=gcc $(RAMDISK)

# -Wall 打印全部警告信息, -O 對代碼進行優化   "-f標誌" 指定與機器無關的編譯標誌
# 1. -fstrength-reduce   用於優化循環語句
# 2. -fomit-frame-pointer  指明對無需幀指針(Frame pointer)的函數不要把幀指針保留在寄存器中,能夠避免對幀指針的操做和維護。
# 3. -fcombine-regs 指明編譯器在組合編譯階段把複製一個寄存器到另外一個寄存器的指令組合在一塊兒。
# 4. -mstring-insns linus 在學習gcc時爲gcc增長的選項,用於 gcc-1.40 在複製結構等操做時使用386cpu的字符串指令,能夠去掉。

CFLAGS	=-Wall -O -fstrength-reduce -fomit-frame-pointer \
-fcombine-regs -mstring-insns

# -nostdinc -Iinclude 不要搜索標準頭文件目錄中的文件,即不用 /usr/include/目錄下的頭文件,
# 而是使用 "-I" 選項指定的目錄或者是在當前目錄裏搜索頭文件。
CPP	=cpp -nostdinc -Iinclude

#
# ROOT_DEV specifies the default root-device when making the image.
# This can be either FLOPPY, /dev/xxxx or empty, in which case the
# default of /dev/hd6 is used by 'build'.
#  
# ROOT_DEV 指定在建立內核映像文件時所使用的默認根文件系統所在的設備,能夠是軟盤、
# /dev/xxx 或者空, 空着時使用默認值 /dev/hd6
#
ROOT_DEV=/dev/hd6


# kernel目錄, mm目錄,和fs目錄所產生的目標代碼文件,爲了方便引用,用ARCHIVES(歸檔文件)標識符標書
ARCHIVES=kernel/kernel.o mm/mm.o fs/fs.o

# 塊和字符設備庫文件。 '.a'表示該文件是個歸檔文件,即包含許多可執行二進制代碼
#子程序集合的庫文件,一般由 GNU的 ar程序生成, ar 是GNU的二進制文件處理程序,用於建立、修改以及從歸檔文件中抽取文件。
DRIVERS =kernel/blk_drv/blk_drv.a kernel/chr_drv/chr_drv.a

MATH	=kernel/math/math.a  # 數學運算庫文件
LIBS	=lib/lib.a  # 由 lib/目錄中文件所編譯生成的庫文件。


#1. make 老式的隱式後綴規則,指示make利用下面的命令將所欲的'.c'文件編譯生成'.s'彙編程序。
#2. 使用 include/ 目錄下的頭文件, 
#3. -S 表示只進行編譯,產生與各個C文件對應的彙編文件。默認狀況下編譯產生的文件名是源文件去掉'.c'後再加上'.s'後綴。
#4. -o 後面是輸出的文件的格式,其中'$*.s'(或'$@')是自動目標變量。
#5. '$<' 表明第一個先決條件,這裏即符合條件的'*.c' 文件

#下面有三個規則:
#1.若目標文件是'.s'文件,源文件是'.c'文件,則使用第一個規則。
#2.若目標文件是'.o'文件,源文件是'.s'文件,則使用第二個規則。
#3.若目標文件是'.o'文件,源文件是'.c'文件,則使用第三個規則。

.c.s:
	$(CC) $(CFLAGS) \
	-nostdinc -Iinclude -S -o $*.s $<
.s.o:
	$(AS) -c -o $*.o $<
.c.o:
	$(CC) $(CFLAGS) \
	-nostdinc -Iinclude -c -o $*.o $<

# all 表示makefile所知的最頂層目標,這裏是Image文件,這裏是引導啓動盤映像文件bootimage。
all:	Image

# 冒號後面的文件是生成 Image 文件依賴的4個文件,下一行是生成Image的執行命令
Image: boot/bootsect boot/setup tools/system tools/build
	tools/build boot/bootsect boot/setup tools/system $(ROOT_DEV) > Image #生成Image文件的命令
	sync  #使用同步命令迫使緩衝塊數據當即寫盤並更新超級塊。

# disk 目標文件由 Image產生。dd命令:複製一個文件,根據選項進行轉換的格式化。
# bs= 表示第一次讀/寫的字節數。 if= 表示輸入的文件。 of= 表示輸出到文件。
disk: Image
	dd bs=8192 if=Image of=/dev/PS0  #使用dd命令把Image文件寫入/dev/PS0(第一個軟盤驅動器)

# 編譯生成 tools/build 文件
tools/build: tools/build.c
	$(CC) $(CFLAGS) \
	-o tools/build tools/build.c

# 利用上面給出的 .s.o 規則生成 head.o文件
boot/head.o: boot/head.s

# 編譯生成 tools/system文件
tools/system:	boot/head.o init/main.o \
		$(ARCHIVES) $(DRIVERS) $(MATH) $(LIBS)
	$(LD) $(LDFLAGS) boot/head.o init/main.o \
	$(ARCHIVES) \
	$(DRIVERS) \
	$(MATH) \
	$(LIBS) \
	-o tools/system > System.map

# 生成數學協處理文件,math.a,進入 kernel/math 目錄,運行該目錄下的makefile。下面的幾條命令相似這樣。
kernel/math/math.a:
	(cd kernel/math; make)

#生成塊設備庫文件 blk_drv.a,其中含有可重定位目標文件。
kernel/blk_drv/blk_drv.a:
	(cd kernel/blk_drv; make)

#生成字符設備函數文件 chr_drv.a
kernel/chr_drv/chr_drv.a:
	(cd kernel/chr_drv; make)

#生成內核目標模塊 kernel.o
kernel/kernel.o:
	(cd kernel; make)

#生成內存管理模塊 mm.o
mm/mm.o:
	(cd mm; make)

#生成文件系統目標模塊fs.o
fs/fs.o:
	(cd fs; make)

#生成庫函數liba.a
lib/lib.a:
	(cd lib; make)

boot/setup: boot/setup.s                     #這裏三行使用8086彙編器和鏈接器對
	$(AS86) -o boot/setup.o boot/setup.s     #setup.s 文件進行編譯生成setup文件
	$(LD86) -s -o boot/setup boot/setup.o    # -s 表示去除目標文件中的符號信息

# 同上,生成 bootsect 磁盤引導塊
boot/bootsect:	boot/bootsect.s
	$(AS86) -o boot/bootsect.o boot/bootsect.s
	$(LD86) -s -o boot/bootsect boot/bootsect.o

# 在bootsect.s文本程序開始處添加一行有關system模塊文件長度信息,在把system模塊
# 加載到內存期間用於指明系統模塊的長度。方法是是利用命令獲取 system模塊的大小,並保存
# 在tmp.s 文件中。cut命令用於剪切字符串,tr用於去掉行尾的回車符。(實際長度+15)/16 用於
# 得到"節"表示的長度信息, 1節 = 16 字節。 這是舊版本(0.01-0.10)在使用,新版本已經不用
# 新版本直接在文件中指明瞭 system的大小。
tmp.s:	boot/bootsect.s tools/system
	(echo -n "SYSSIZE = (";ls -l tools/system | grep system \
		| cut -c25-31 | tr '\012' ' '; echo "+ 15 ) / 16") > tmp.s
	cat boot/bootsect.s >> tmp.s

# 執行 make clean 時執如下命令,刪除編譯連接生成的文件
# rm 是文件刪除命令, -f 表示忽略不存在的文件,而且不顯示刪除信息。
clean:
	rm -f Image System.map tmp_make core boot/bootsect boot/setup
	rm -f init/*.o tools/system tools/build boot/*.o
	(cd mm;make clean)  #進入 mm/目錄,執行該目錄下的makefile文件中的clean規則,下面相似。
	(cd fs;make clean)
	(cd kernel;make clean)
	(cd lib;make clean)

#該規則先執行上面的clean規則,而後對 linux/目錄進行壓縮,生成 backup.Z 壓縮文件。
# cd.. 退到Linux的上一級目錄,tar cf - linux 表示對tar 目錄 進行壓縮。
# |compress 表示將壓縮文件經過管道操做傳遞給壓縮程序 compres ,並將程序的輸出存成 backup.Z文件。
backup: clean
	(cd .. ; tar cf - linux | compress - > backup.Z)
	sync    #使用同步命令迫使緩衝塊數據當即寫盤並更新超級塊。


# 該目標或規則用於產生各個文件之間的依賴關係,建立這些依賴關係是爲了讓make 目錄用來肯定是否須要重建一個目標對象。
# 如某個頭文件被改動後,make就能經過生成的依賴關係,從新編譯與該頭文件相關的全部*.c文件。
# 處理過程以下:
# 使用sed字符串編輯程序對makefile進行處理,輸出爲makefile中刪除了'### Dependencies'後面的全部行,
# 並生成一個臨時文件 tmp_make,而後對指定目錄(init/)的每一C文件執行gcc預處理操做。
# -M 告訴預處理程序cpp輸出描述目標文件相關性的規則,而且這些規則符合make語法,對每個源文件,預處理程序
# 會輸出一個規則,其結果形式就是相應源文件的目標文件加上其依賴關係,即該源文件中包含的全部頭文件列表。
# 而後把預處理結果都添加到臨時文件 tmp_make 中,最後再把這個臨時文件複製成新的Makefile文件。
# "$$i" 其實是'$($i)'
dep:
	sed '/\#\#\# Dependencies/q' < Makefile > tmp_make
	(for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done) >> tmp_make
	cp tmp_make Makefile
	(cd fs; make dep)    #對fs目錄下的makefile也作一樣處理,下面相似。
	(cd kernel; make dep)
	(cd mm; make dep)

# main.o 的依賴文件
### Dependencies:
init/main.o : init/main.c include/unistd.h include/sys/stat.h \
  include/sys/types.h include/sys/times.h include/sys/utsname.h \
  include/utime.h include/time.h include/linux/tty.h include/termios.h \
  include/linux/sched.h include/linux/head.h include/linux/fs.h \
  include/linux/mm.h include/signal.h include/asm/system.h include/asm/io.h \
  include/stddef.h include/stdarg.h include/fcntl.h
相關文章
相關標籤/搜索