$(OUT)/bootblock: bootloader/bootasm.S bootloader/bootmain.c
@mkdir -p $(OUT)
$(CC) -fno-builtin -fno-pic -m32 -nostdinc -fno-stack-protector -Iinclude \
-Os -o $(OUT)/bootmain.o -c bootloader/bootmain.c
$(CC) -fno-builtin -fno-pic -m32 -nostdinc -Iarch/x86_64/include -Iinclude \
-o $(OUT)/bootasm.o -c bootloader/bootasm.S
*$(LD) -m elf_i386 -nodefaultlibs --omagic -e start -Ttext 0x7C00 \
-o $(OUT)/bootblock.o $(OUT)/bootasm.o $(OUT)/bootmain.o*
**$(OBJDUMP) -S $(OUT)/bootblock.o > $(OUT)/bootblock.asm
$(OBJCOPY) -S -O binary -j .text $(OUT)/bootblock.o $(OUT)/bootblock
../tools/sign.pl $(OUT)/bootblock**
clean:
rm -rf $(OUT) $(FS_DIR) $(UOBJ_DIR) $(KOBJ_DIR) $(ARCHOBJ_DIR) $(DOBJ_DIR)
rm -f kernel/vectors.S yaos.img yaosmemfs.img .gdbinit
rm -rf $(MODULEC_OBJECTS)
rm -rf $(LIBS_OBJECTS)
ifndef CPUS
CPUS := $(shell grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu)
endif
QEMUOPTS =-enable-kvm -cpu host,+x2apic -vga vmware -display vnc=10.67.107.131:1111 \
-hdb yaos.img -smp $(CPUS) -m 512 $(QEMUEXTRA)
yaos.img: $(OUT)/bootblock
dd if=/dev/zero of=yaos.img count=10000
dd if=$(OUT)/bootblock of=yaos.img conv=notrunc
qemu: yaos.img
@echo Ctrl+a h for help
$(QEMU) -serial mon:stdio -nographic $(QEMUOPTS)
ld 命令
用法:ld [选项] 文件…
-b: 指定目标代码输入文件的格式
-Bstatic: 只使用静态库
-Bdynamic: 只使用动态库
-Bsymbolic: 把引用捆绑到共享库中的全局符号
-c: 从指定的命令文件读取命令
–cref: 创建跨引用表
-d: 设置空格给通用符号,即使指定了可重定位输出
-defsym: 在输出文件中创建指定的全局符号
-demangle: 在错误消息中还原符号名称
-e: 使用指定的符号作为程序的初始执行点
-E: 对于ELF格式文件,把所有符号添加到动态符号表
-f: 对于ELF格式共享对象,设置 DT_AUXILIARY 名称
-F: 对于ELF格式共享对象,设置 DT_FILTER 名称
-format: 指定目标代码输入文件的格式 (和 -b 相同)
-g: 被忽略。用于提供和其他工具的兼容性
-h: 对于ELF格式共享对象,设置 DT_SONAME 名称
-i: 执行增量连接
-l: 把指定的存档文件添加到要连接的文件清单
-L: 把指定的路径添加添加到搜索库的目录清单
-M: 显示连接映射,用于诊断目的
-Map: 创建指定的文件来包含连接映射
-m: 模拟指定的连接器
-N: 指定读取/写入文本和数据段
-n: 设置文本段为只读
-noinhibit-exec: 生成输出文件,即使出现非致命连接错误
-no-keep-memory: 为内存使用优化连接
-no-warn-mismatch: 允许连接不匹配的目标文件
-O: 生成优化了的输出文件
-o: 指定输出文件的名称
-oformat: 指定输出文件的二进制格式
-R: 从指定的文件读取符号名称和地址
-r: 生成可重定位的输出(称为部分连接)
-rpath: 把指定的目录添加到运行时库搜索路径
-rpath-link: 指定搜索运行时共享库的目录
-S: 忽略来自输出文件的调试器符号信息
-s: 忽略来自输出文件的所有符号信息
-shared: 创建共享库
-sort-common: 在输出文件中不按照长度对符号进行排序
-split-by-reloc: 按照指定的长度在输出文件中创建额外的段
-split-by-file: 为每个目标文件在输出文件中创建额外的段
–section-start: 在输出文件中指定的地址定位指定的段
-T: 指定命令文件 (和 -c 相同)
-Ttext: 使用指定的地址作为文本段的起始点
-Tdata: 使用指定的地址作为数据段的起始点
-Tbss: 使用指定的地址作为bss段的起始点
-t: 在处理输入文件时显示它们的名称
-u: 强制指定符号在输出文件中作为未定义符号
-warn-common: 当一个通用符号和另一个通用符号结合时发出警告
-warn-constructors: 如果没有使用任何全局构造器,则发出警告
-warn-once: 对于每个未定义的符号只发出一次警告
-warn-section-align: 如果为了对齐而改动了输出段地址,则发出警告
–whole-archive: 对于指定的存档文件,在存档中包含所有文件
-X: 删除所有本地临时符号
-x: 删除所有本地符号
objcopy
源文件/目标文件,如果不指定目标文件那么objcopy将会创建一个临时文件,并且将其命名为源文件。
命令项
-I bfdname
–input-target=bfdname
指定输入文件的bfdname,可取值elf32-little,elf32-big等。-O bfdname
–output-target=bfdname
指定输出文件的bfdname-F bfdname
–target=bfdname
指定输入、输出文件的bfdname,目标文件格式,只用于在目标和源之间传输数据,不转 换。-j sectionname
–only-section=sectionname
只将由sectionname指定的section拷贝到输出文件,可以多次指定,并且注意如果使用 不当会导致输出文件不可用。-R sectionname
–remove-section=sectionname
从输出文件中去除掉由sectionname指定的section,可以多次指定,并且注意如果使用 不当会导致输出文件不可用。-S
–strip-all
不从源文件拷贝符号信息和relocation信息。-g
–strip-debug
不从源文件拷贝调试符号信息和相关的段。对使用-g编译生成的可执行文件执行之后, 生成的结果几乎和不用-g进行编译生成可执行文件一样。–strip-unneeded
去掉所重定位处理不需要的符号。-K symbolname
–keep-symbol=symbolname
strip的时候,保留由symbolname指定的符号信息。可以指定多次。-N symbolname
–strip-symbol=symbolname
不拷贝由symbolname指定的符号信息,可以多次指定。-G symbolname
–keep-global-symbol=symbolname
只保留symbolname为全局的,让其他的都是文件局部的变量这样外部不可见,这个选项 可以多次指定。-L symbolname
–localize-symbol=symbolname
将变量symbolname变成文件局部的变量。可以多次指定。-W symbolname
–weaken-symbol=symbolname
弱化变量。–globalize-symbol=symbolname
让变量symbolname变成全局范围,这样它可以在定义它的文件外部可见。可以多次指定。-w
–wildcard
允许对其他命令行项中的symbolnames使用正则表达式。问号(?),星号(),反斜线() ,和中括号([])操作可以用在标号名称的任何位置。如果标号的第一个字符是感叹号(!),那 么表示相反的含义,例如:
-w -W !foo -W fo
表示objcopy将要弱化所有以"fo"开头的标号,但是除了标号"foo"。-x
–discard-all
不从源文件中拷贝非全局变量。-X
–discard-locals
不拷贝编译生成的局部变量(一般以L或者…开头)。-b byte
–byte=byte
只保留输入文件的每个第byte个字节(不会影响头部数据)。byte的范围可以是0到 interleave-1。这里,interleave通过-i选项指定,默认为4。将文件创建成程序rom的时候
,这个命令很有用。它经常用于srec输出目标。-i interleave
–interleave=interleave
每隔interleave字节拷贝1 byte。通过-b选项指定选择哪个字节,默认为4。如果不指定 -b那么objcopy会忽略这个选项。–gap-fill val
在section之间的空隙中填充val,–set-start val
设定新文件的起始地址为val,并不是所有格式的目标文件都支持设置起始地址。–change-start incr
–adjust-start incr
通过增加incr量来调整起始地址,并不是所有格式的目标文件都支持设置起始地址。–change-address incr
–adjust-vma incr
通过增加incr量调整所有sections的VMA(virtual memory address)和LMA(linear memory address),以及起始地址。–change-section-address section{=,+,-}val
–adjust-section-vma section{=,+,-}val
调整指定section的VMA/LMA地址。–set-section-flags section=flag
指定指定section的flag,flag的取值可以alloc,contents, load, noload, readonly, code, data, rom, share, debug。我们可以设置一个没有内容的节的flag,但是清除一个有
内容的节的flag是没有意义的–应当把相应的节移除。并不是所有的flags对于所有的目标文 件都有意义。–add-section sectionname=filename
在拷贝文件的时候,添加一个名为sectionname的section,该section的内容为filename 的内容,大小为文件大小。这个选项只在那些可以支持任意名称section的文件好用。–rename-section oldname=newname[,flags]
更改section的名
将一个section的名字从oldname更改为newname,同时也可以指定更改其flags。这个在 执行linker脚本进行重命名的时候,并且输出文件还是一个目标文件并不成为可执行的连接 文件,这个时候很有优势。
这个项在输入文件是binary的时候很有用,因为这经常会创建一个名称为.data的 section,例如,你想创建一个名称为.rodata的包含二进制数据的section,这时候,你可以使用如下命令:
objcopy -I binary -O <output_format> -B
–rename-section .data=.rodata,alloc,load,readonly,data,contents
<input_binary_file> <output_object_file>–add-gnu-debuglink=path-to-file
创建一个.gnu_debuglink节,这个节包含一个特定路径的文件引用,并且把它添加到输 出文件中。–only-keep-debug
对文件进行strip,移走所有不会被–strip-debug移走的section,并且保持调试相关的 section原封不动。