《操作系统真象还原》第八章内存管理 优化makefile和分页机制再理解

1,Makefile的优化

        书里面对C文件到O文件的编译处理的不是很好,每次新增文件都需要自己手动加入。

主要涉及到一些字符处理函数:

        1,patsubst

                $(patsubst <pattern>,<replacement>,<text>) 

                功能:查找<text>中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)是否符
合模式<pattern>,如果匹配的话,则以<replacement>替换。这里,<pattern>可以包括通
配符“%”,表示任意长度的字串。如果<replacement>中也包含“%”,那么,<replacement>
中的这个“%”将是<pattern>中的那个“%”所代表的字串。(可以用“\”来转义,以“\%”
来表示真实含义的“%”字符)  
返回:函数返回被替换过后的字符串。

        用这个函数实现将所有.h文件加上-I 参数。

        CFLAGS+=$(patsubst %,-I %,$(INC_DIR)) 

        比如main.h 变成了 -I main.h 

        2,$(wildcard $(dir)/*.h)

              由于在变量的定义和函数引用时,通配符将失效。所以使用wildcard函数,它会展开 PATTERN中的所有文件列表。这里是展开dir路径下全部的H文件。

        

        3,$(foreach <var>,<list>,<text>)

              把参数<list>中的单词逐一取出放到参数<var>所指定的变量中,然后再执行<text>所包含的表达式。每一次<text>会返回一个字符串,循环过程中,<text>返回的每个字符串会以空格分隔,最后当整个循环结束时,<text>所返回的全部字符串
所组成的整个字符串(以空格分隔)将会是 foreach 函数的返回值。  

               INCLUDE=$(foreach dir,$(INC_DIR),$(wildcard $(dir)/*.h) )

               先从INC_DIR将头文件夹目录取到dir变量 ,wildcard又会将该目录下的所以h文件都遍历完。整个字符串又返回给INCLUDE .最后多轮循环,INCLUDE变包含了全部的H文件

        4,改进的地方

                        OBJS:该变量就是指示单个目标文件.O;这里使用了模式匹配函数patsubst,将点C文件匹配出对应的点O文件。从而找到依赖条件。

由于在链接文件时mian函数作为入口函数被链接在0xc0001500虚拟地址上。所以我们必须将main.o作为最终目标的,首要依赖条件。以便mian.o链接到正确位置。

所以我们要在OBJS变量中实现将main.o分离出来。因为便有了变量MAIN,和OBJS_EX

                

BUILD_DIR = ./build

SRC_DIR=./device ./kernel ./lib ./lib/kernel

INC_DIR=./device ./kernel ./lib ./lib/kernel

ENTRY_POINT = 0xc0001500
AS = nasm
CC = gcc
LD = ld
#替换原工程中的LIB 
CFLAGS+=$(patsubst %,-I %,$(INC_DIR)) 
#LIB = -I lib/ -I lib/kernel   -I kernel/ -I device/
ASFLAGS = -f elf

CFLAGS += -Wall -m32 -fno-stack-protector  -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes

LDFLAGS = -m elf_i386 -Ttext $(ENTRY_POINT) -e main -Map $(BUILD_DIR)/kernel.map
#OBJS = $(BUILD_DIR)/main.o $(BUILD_DIR)/init.o $(BUILD_DIR)/interrupt.o \
      $(BUILD_DIR)/timer.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/print.o \
      $(BUILD_DIR)/debug.o $(BUILD_DIR)/memory.o $(BUILD_DIR)/bitmap.o \
      $(BUILD_DIR)/string.o

#	获取全部头文件
INCLUDE=$(foreach dir,$(INC_DIR),$(wildcard $(dir)/*.h) )
#   获取全部C文件
SOURCES=$(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c) )

#	将C文件替换为O文件
OBJS=$(patsubst %.c,$(BUILD_DIR)/%.o,$(notdir $(SOURCES)))
MAIN=$(findstring $(BUILD_DIR)/main.o,$(OBJS))
OBJS_EX=$(filter-out $(MAIN),$(OBJS))
#	默认路径下的文件搜索 否则在编译o文件时找不到对应的C文件
VPATH=$(SRC_DIR)
# 链接 最终目标
$(BUILD_DIR)/kernel.bin:$(MAIN) $(OBJS_EX)  $(BUILD_DIR)/kernel.o $(BUILD_DIR)/print.o 
	$(LD) $(LDFLAGS) $^ -o $@
# C代码编译
$(BUILD_DIR)/%.o:%.c $(INCLUDE) | mk_dir
	
	$(CC) -c $< -o $@ $(CFLAGS) 


# 编译汇编
$(BUILD_DIR)/kernel.o: kernel/kernel.S
	$(AS) $(ASFLAGS) $< -o $@

$(BUILD_DIR)/print.o: lib/kernel/print.S
	$(AS) $(ASFLAGS) $< -o $@



.PHONY: mk_dir hd clean all

mk_dir:
	mkdir -p $(BUILD_DIR)
hd:
	dd if=/home/xxx/program/os_study/project_my/c8/c/build/kernel.bin of=/home/xiot/program/os_study/bochs/hd60M.img bs=512 count=200 seek=9 conv=notrunc

clean:
	rm -rf  $(BUILD_DIR)

build:$(BUILD_DIR)/kernel.bin

all: mk_dir build hd

debug: 
	
	@echo $(OBJS)
	@echo $(MAIN)
	@echo $(OBJS_EX)

 使用方式

        在SRC_DIR INC_DIR 分别加入自己工程中的文件夹 

        make clean #删除build文件夹以及子文件

        make all  # 完成编译生成kernel.bin   同时hd的目标也会被执行,将kernel.bin写入硬盘中。

        注意:hd目标的命令用的是绝对地址。请核对你自己路径地址

2,分页机制的再理解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值