#
# Makefile for linux.
# If you don't have '-mstring-insns' in your gcc (and nobody but me has :-)
# remove them from the CFLAGS defines.
#
#
#8086匯編編譯器和連接器. -0生成8086目標程序;-a生成與gas和gld部分兼容的代碼
#
AS86 =as -0 -a
CC86 =cc -0
LD86 =ld -0
#
#GNU匯編編譯器和連接器
#
AS =gas
LD =gld
#
#GNU連接器gld運行時用到的選項
#-s 輸出文件中省略所有的符號信息
#-x 刪除所有的局部符號
#-M 在標准輸出設備(顯示器)上打印連接映象(link map).
#連接映象:由連接程序產生的一種內存地址映象,其中列出了程序裝入到內存中的位置信息,具體有如下信息:
#目標文件及符號信息映射到內存中的位置
#公共符號如何放置
#連接中包含的所有文件成員及其引用的符號
#
LDFLAGS =-s -x -M
#
#gcc是GNU C程序編譯器,對於UNIX類的腳本程序而言,
#在引用定義的標識符時,需在前面加上$符號並用括號括住標識符
#
CC =gcc
#
#GCC的選項.
#-Wall 打印所有的警告信息
#-O 對代碼進行優化
#-fstrength-reduce 優化循環語句
#
CFLAGS =-Wall -O -fstrength-reduce -fomit-frame-pointer -fcombine-regs
#
#CPP是gcc的預處理程序
#-nostdinc -Iinclude 不要搜索標准的頭文件目錄中的文件,
#而是使用-I選項指定的目錄或者是在當前的目錄裡搜索頭文件
#
CPP =gcc -E -nostdinc -Iinclude
#
# kernel目錄,mm目錄,fs目錄所產生的目標代碼文件。
# 為了方便引用,在這裡將它們用ARCHIVES(歸檔文件)標識符表示
#
ARCHIVES=kernel/kernel.o mm/mm.o fs/fs.o
#
# 由lib/目錄中生成的通用庫文件
#
LIBS =lib/lib.a
#
# make隱式後綴規則
# 指示make利用下面的命令將所有的.c文件編譯生成.s匯編程序
# ':'表示下面是該規則的命令
# 規則:指使gcc采用前面CFLAGS所指定的選項以及僅使用include/目錄中的頭文件,
# 在適當的編譯後不進行匯編就停止(-S),從而產生與輸入的各個C文件對應的匯編語言形式的代碼文件。
# 默認情況下所產生的匯編程序文件是原C文件名去掉.c而加上.s後綴。
# -o表示其後是輸出文件的形式。
# 其中$*.s(或$@)是自動目標變量,$<代表第一個先決條件,這裡即是符合條件*.c的文件。
#
.c.s:
$(CC) $(CFLAGS) \
-nostdinc -Iinclude -S -o $*.s $<
#
# 將所有.s匯編程序文件編譯成.o目標文件。下一條是實現該操作的具體命令
# 使用gas編譯器將匯編程序編譯成.o目標文件。-c表示只編譯或匯編,但不進行連接操作
#
.s.o:
$(AS) -c -o $*.o $<
#
# 使用gcc將c語言編譯成目標文件但不連接
#
.c.o:
$(CC) $(CFLAGS) \
-nostdinc -Iinclude -c -o $*.o $<
#
# all表示創建Makefile所知的最頂層目標。這裡即是image文件
#
all: Image
#
# 第一行說明:目標文件(Image文件)是由分號後面的3個元素產生
# 下面兩行是執行的命令
# 第一行表示使用tools目錄下的build工具程序將boot,system文件組裝成內核映象文件Image
# 第二行的sysn同步命令是迫使緩沖塊數據立即寫盤並更新超級塊
#
Image: boot/boot tools/system tools/build
tools/build boot/boot tools/system > Image
sync
#chmem -- 修改系統內存數據
tools/build: tools/build.c
$(CC) $(CFLAGS) \
-o tools/build tools/build.c
chmem +65000 tools/build
#
# 利用上面的.s.o規則生成head.o文件
#
boot/head.o: boot/head.s
#
# 最後的>System.map表示gld需要將連接映象重定向存放在System.map文件中
#
tools/system: boot/head.o init/main.o \
$(ARCHIVES) $(LIBS)
$(LD) $(LDFLAGS) boot/head.o init/main.o \
$(ARCHIVES) \
$(LIBS) \
-o tools/system > System.map
#
# 內核目標模塊kernel.o
#
kernel/kernel.o:
(cd kernel; make)
#
# 內核管理模塊mm.o
#
mm/mm.o:
(cd mm; make)
#
# 文件系統目標模塊fs.o
#
fs/fs.o:
(cd fs; make)
#
# 庫函數lib.a
#
lib/lib.a:
(cd lib; make)
#
# 在boot.s程序開口添加一行有關system文件長度信息
# 首先生成含有 "SYSSIZE = 文件實際長度"一行信息的tmp.s文件,然後將boot.s文件添加在其後。
# 取得system長度的方法是:
# 利用ls命令對system文件進行長列表顯示
# 用grep命令取得列表上文件字節數字段信息,並定向保存在tmp.s臨時文件中
# cut命令用於剪切字符串
# tr用於去除行尾的回車符
# (實際長度 + 15)/16用於獲得'節'表示的長度信息,1節=16字節
# 用8086匯編和連接器對setup.s文件進行編譯生成setup文件
# -s表示要取出目標文件中的符號信息
#
boot/boot: boot/boot.s tools/system
(echo -n "SYSSIZE = (";ls -l tools/system | grep system \
| cut -c25-31 | tr '\012' ' '; echo "+ 15 ) / 16") > tmp.s
cat boot/boot.s >> tmp.s
$(AS86) -o boot/boot.o tmp.s
rm -f tmp.s
$(LD86) -s -o boot/boot boot/boot.o
#
# 當執行"make clean"時,就會執行以下命令,去除所有編譯連接生成的文件
# "rm"是文件刪除命令,選項-f含義是忽略不存在的文件,並且不顯示刪除信息
# (cd mm;make clean)表示進入mm/目錄,執行該目錄Makefile文件中的clean規則
#
clean:
rm -f Image System.map tmp_make boot/boot core
rm -f init/*.o boot/*.o tools/system tools/build
(cd mm;make clean)
(cd fs;make clean)
(cd kernel;make clean)
(cd lib;make clean)
#
# 該規則首先執行上面的clean規則,然後對linux/目錄進行壓縮,生成backup.Z壓縮文件。
# "cd .."表示退到linux/的上一級(父)目錄
# "tar cf - linux"表示對linux/目錄執行tar歸檔程序,-cf表示需要創建新的歸檔文件
# "| compress -"表示將tar程序的執行通過管道操作('|')傳遞給壓縮程序compress,並將壓縮程序的輸
#出存成backup.Z文件
# sysn同步命令迫使緩沖塊數據立即寫盤並更新超級塊
#
backup: clean
(cd .. ; tar cf - linux | compress16 - > backup.Z)
sync
#
# 該規則用於各文件的依賴關系。創建這些依賴關系是為了給make用來確定是否需要重建一個目標對象
# 比如當某個文件頭被改動過後,make就通過生成的依賴關系,重新編譯與該頭文件有關的所有*.c文件。
# 具體方法如下:
# 使用字符串編輯程序sed對Makefile文件(這裡即是自己)進行處理,
# 輸出為刪除Makefile文件中"### Dependencies"行後面的所有行,並生成tmp_make臨時文件
# 然後對init/目錄下的每一個C文件(其實只有一個C文件main.c)執行gcc預處理操作
# -M標志告訴預處理程序輸出描述每個目標文件相關性的規則,並且這些規則符合make語法
# 對於每一個源文件,預處理程序輸出一個make規則,其結果形式是相應源程序文件的目標文件名加上其依賴關系--該源文件中包含的所有頭文件列表
# "$$i"實際上是$($i)的意思,"$i"是前面shell變量的值
# 然後把預處理結果都加到臨時文件tmp_make中,然後將該臨時文件復制成新的makefile文件
#
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)
(cd kernel; make dep)
(cd mm; make dep)
### 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/asm/system.h include/asm/io.h include/stddef.h \
include/stdarg.h include/fcntl.h