Ucore------Lab1_Practice1

  1. 操作系统镜像文件 ucore.img 是如何一步一步生成的?(需要比较详细地解释 Makefile 中每一条相关命令和命令参数的含义,以及说明命令导致的结果)

大致流程:

使用make V=命令,由终端的输出结果得知:makefile先调用了gcc,将ucore的源代码编译为目标文件也就是.o文件,再使用ld命令将目标文件链接成可执行程序,最后使用dd命令将bootloader放进一个虚拟硬盘中,生成虚拟硬盘ucore.img.Qemu再在硬盘中的数据的基础上来执行相应的代码。

在这里插入图片描述
在这里插入图片描述

详细地解释 Makefile 中每一条相关命令和命令参数的含义,以及说明命令导致的结果:

makefile的基本命令与参数及其作用:

  • . 表示了所有文件;
  • ? 表示任意单个字符;
  • […] 表示一个字符类;
  • [^…] 表示相反的字符类。
  • ~ 表示当前用户的/home路径,~加用户名可以表示该用户的/home路径。
  • $@ 目标文件的文件名;
  • $% 仅当目标文件为归档成员文件(.lib 或者 .a)时,显示文件名,否则为空;
  • $< 依赖(prerequisite)列表里面的第一个文件名;
  • $? 所有在prerequisite列表里面比当前目标新的文件名,用空格隔开;
  • $^ 所有在prerequisite列表中的文件,用空格隔开; 如果有重复的文件名(包含扩展名),会自动去除重复;
  • + 与 + 与 +^相似,也是prerequisite列表中的文件名用空格隔开,不同的是这里包含了所有重复的文件名;
  • $* 显示目标文件的主干文件名,不包含后缀部分。

此外,上面的每个变量都带有两个不同的变种,用于适应不同种类的make。分别是在后面附加一个“D”或者“F”
-f :执行make的时候,带上-f <文件名>参数,来指定make命令从哪里读取makefile文件;而如果我们不显式指定,则make就会在当前目录下依次查找名字为GNUmakefile, makefile,和 Makefile的文件来作为其makefile文件.

  • :让make忽略该命令的错误,例如,通常在Makefile中使用-include来代替include,忽略由于包含文件不存在或者无法创建时的错误提示,make继续执行。
  • @ :关闭回显。不显示命令,只显示结果.而make参数-s或–slient则是禁止所有执行命令的显示.
  • $(shell pwd) :获取当前目录的绝对路径 例如:-include $(shell pwd)/src/C_SRC
  • ?= :变量在之前没有赋值的情况下才会对这个变量进行赋值.
  • := :直接展开定义变量.
  • = :递归展开,可能陷入无限循环.

由上面的截图我们知道,makefile文件最后调用了dd命令分别将数据,bootblock,kernel文件放入虚拟硬盘中形成ucore.img操作系统镜像文件。
在makefile文件中对应的代码为:

# create ucore.img
UCOREIMG	:= $(call totarget,ucore.img)					//先指定目标文件名为ucore.img

$(UCOREIMG): $(kernel) $(bootblock)							//ucore.img的依赖文件为kernel和bootblock
	$(V)dd if=/dev/zero of=$@ count=10000					//下面是命令,用于将数据,bootblock,kernel放到虚拟硬盘中
	$(V)dd if=$(bootblock) of=$@ conv=notrunc
	$(V)dd if=$(kernel) of=$@ seek=1 conv=notrunc

$(call create_target,ucore.img)										//指定那个名称ucore.img

下面是生成bootblock的代码:

# create bootblock
bootfiles = $(call listf_cc,boot)
$(foreach f,$(bootfiles),$(call cc_compile,$(f),$(CC),$(CFLAGS) -Os -nostdinc))

bootblock = $(call totarget,bootblock)

$(bootblock): $(call toobj,$(bootfiles)) | $(call totarget,sign)
	@echo + ld $@
	$(V)$(LD) $(LDFLAGS) -N -e start -Ttext 0x7C00 $^ -o $(call toobj,bootblock)
	@$(OBJDUMP) -S $(call objfile,bootblock) > $(call asmfile,bootblock)
	@$(OBJDUMP) -t $(call objfile,bootblock) | $(SED) '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $(call symfile,bootblock)
	@$(OBJCOPY) -S -O binary $(call objfile,bootblock) $(call outfile,bootblock)
	@$(call totarget,sign) $(call outfile,bootblock) $(bootblock)

$(call create_target,bootblock)

由上述bootblock生成代码我们知道,bootblock依靠bootasm.o,bootmain.o,sign

# create 'sign' tools
$(call add_files_host,tools/sign.c,sign,sign)
$(call create_target_host,sign,sign)
  • ld -m elf_i386 -nostdlib -N -e start -Ttext 0x7C00
  • obj/boot/bootasm.o obj/boot/bootmain.o -o obj/bootblock.o
  • -m 模拟为i386上的连接器
  • -nostdlib 不使用标准库
  • -N 设置代码段和数据段均可读写
  • -e 指定入口
  • -Ttext 制定代码段开始位置
  • 拷贝二进制代码bootblock.o到bootblock.out
  • objcopy -S -O binary obj/bootblock.o obj/bootblock.out
  • -S 移除所有符号和重定位信息
  • -O 指定输出格式
  • 使用sign工具处理bootblock.out,生成bootblock
  • bin/sign obj/bootblock.out bin/bootblock

生成kernel文件的代码:

# -------------------------------------------------------------------
# kernel

KINCLUDE	+= kern/debug/ \
			   kern/driver/ \
			   kern/trap/ \
			   kern/mm/

KSRCDIR		+= kern/init \
			   kern/libs \
			   kern/debug \
			   kern/driver \
			   kern/trap \
			   kern/mm

KCFLAGS		+= $(addprefix -I,$(KINCLUDE))

$(call add_files_cc,$(call listf_cc,$(KSRCDIR)),kernel,$(KCFLAGS))

KOBJS	= $(call read_packet,kernel libs)

# create kernel target
kernel = $(call totarget,kernel)

$(kernel): tools/kernel.ld

$(kernel): $(KOBJS)
	@echo + ld $@
	$(V)$(LD) $(LDFLAGS) -T tools/kernel.ld -o $@ $(KOBJS)
	@$(OBJDUMP) -S $@ > $(call asmfile,kernel)
	@$(OBJDUMP) -t $@ | $(SED) '1,/SYMBOL TABLE/d; s/ .* / /; /^$$/d' > $(call symfile,kernel)

$(call create_target,kernel)
  1. 一个被系统认为是符合规范的硬盘主引导扇区的特征是什么?
    特征:
  • 只有512字节。
  • 最后一个字节为:0xAA
  • 倒数第二个字节为:0x55
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值