用来生成二进制内核的Makefile样例
来源:互联网 发布:ant 指定java版本 编辑:程序博客网 时间:2024/05/16 12:08
弄出了下面这个Makefile,在偶的Linux试了一切正常:
LD = ld # GNU的gld作为连接器.
CC = gcc # 使用GNU Compiler作为C编译器.
OBJCOPY = objcopy -O binary -R .note -R .comment -S
# -O binary 输出为二进制格式.
# -R .note -R .comment 删除目标文件中的.note和.comment段.
# -S 删除所有符号信息.
ASFLAGS = -Iinclude # -Iinclude 仅在include目录中寻找包含文件.
LDFLAGS = -s -x -M # -s 省略符号信息. -x 删除局部符号. -M 导出连接映像(Link map)到标准输出.
CFLAGS = -Wall -O2 -fomit-frame-pointer # -Wall 显示所有警告. -O2 二级优化.
# -fomit-frame-pointer 优化函数的框架指针(Frame pointer).
CFLAGS_KERNEL = -c -nostdinc -Iinclude # -c 仅编译生成目标文件而不连接.
# -nostdinc -Iinclude 仅在include目录中寻找包含文件.
.PHONY: all clean dep
all : Image
Image : boot/bootsect boot/setup vmlinux tools/build
$(OBJCOPY) vmlinux vmlinux.out # 使用objcopy将ELF内核vmlinux解包成为二进制机器码vmlinux.out.
tools/build boot/bootsect boot/setup vmlinux.out > $@ # 使用build工具合成最终内核镜像Image.
rm -f vmlinux.out # 删除临时文件vmlinux.out
kernel/head.o : kernel/head.asm
$(AS) $(ASFLAGS) -felf -o $@ $< # 汇编boot/head.asm生成boot/head.o目标文件.
# -felf 汇编boot/head.asm生成boot/head的ELF目标文件.
init/main.o : init/main.c
$(CC) $(CFLAGS) $(CFLAGS_KERNEL) -o $@ $< # 编译init/main.c生成init/main.o目标文件.
tools/build : tools/build.c
$(CC) $(CFLAGS) -o $@ $< # 编译tools/build.c生成内核合成工具build.
boot/setup : boot/setup.asm
$(AS) $(ASFLAGS) -fbin -o $@ $< # 汇编boot/setup.asm生成boot/setup二进制机器码.
# -fbin 对于nasm来说是指定输出二进制机器码而不是目标文件.
boot/bootsect : boot/bootsect.asm
$(AS) $(ASFLAGS) -fbin -o $@ $< # 汇编boot/bootsect.asm生成boot/bootsect二进制机器码.
vmlinux : kernel/head.o init/main.o # 连接所有内核模块到一个单一的ELF文件vmlinux中.
$(LD) $(LDFLAGS) kernel/head.o init/main.o -o $@ > System.map
# 重定向连接映像到System.map文件.
CLEAN_FILES = Image System.map boot/bootsect boot/setup tools/build
boot/*.o init/*.o kernel/*.o vmlinux # 这里是所有要清除的文件列表.
clean :
rm -f $(CLEAN_FILES) # clean命令清除所有编译生成的文件.
dep :
# 目前还没有.
在blog上排版有点乱,各位看客(真的存在么?~~;-)不要介意。
需要说明的是上面这个东西不能直接用,因为Makefile是不允许把注释和指令写到同一行的,所以要让上面的Makefile能用,最简单的方法就是删除所有注释。
目前这个系统还没什么内容,主要就下面几个文件:
boot/bootsect.asm 磁盘引导扇区
boot/setup.asm 内核加载模块(就是Loader)
kernel/head.asm 内核头部
init/main.c 内核主体
tools/build.c 合成工具
了解Linux内核结构的人一看就知道,该代码结构和Linux一模一样,甚至文件名都几乎一致。没关系,这样看起来确实更清晰,对了解linux内核结构也很有帮助。
Makefile的格式什么的我就不说了,偶也很少用- -。这个Makefile也是属于赶鸭子上架,硬凑凑出来的。
另外要说这个Makefile是参照0.11和2.4.33.4的Makefile写的,里面的符号名,文件名等等都来自Linux内核,在研究2.4.33.4的Makefile的过程中也学到不少,同时也发现一些有趣的东西。
vmlinux这个文件名你一定很眼熟,没错!编Linux的内核的时候它也出现过,它就是内核的ELF形式,用objcopy脱掉它的MJ就是二进制内核。
我这里并没有像Linux一样先把bootsect和setup模块编成ELF再全部连接后脱成bin,而是直接把它们做成bin,通过build这个工具把内核模块“连接”(叫粘接可能更形象些= =)起来。至于为什么,可能只是因为好玩吧,可能以后会改掉。
正如我以前所说,可以用nasm的incbin来替代build,我这里没有这么做,因为一自己写比较有趣,二incbin不能判断文件的大小,如果模块大小超过上限也不会报错,调试的时候反而可能会遇到麻烦。
下面我想重点说说编译和连接的全过程。
首先分别用nasm汇编boot/bootsect.asm和boot/setup.asm,生成二进制代码文件boot/bootsect和boot/setup,然后编译boot/head.asm和init/main.c,分别生成两个ELF文件boot/head.o和init/main.o。随后CALL来ld(GNU的连接器,原名gld),把所有内核的.o连接在一起(一定要注意连接文件的顺序!),连接生成了我们前面说过的那个叫做vmlinux的ELF文件。(注意,与linux的不同,这vmlinux并没有包含bootsect和setup模块,它其实就是0.11中的system模块)
关键就是objcopy这个东东,它的作用就是能把目标文件中的代码提出来,变成纯二进制的机器码文件。我们依照Makefile把vmlinux脱成vmlinux.out,再用我自己的build工具把boot/bootsect、boot/setup和vmlinux.out粘合在一起,生成最终的Image!这个Image就是内核文件了,把它当作磁盘镜像放到VM上面可以直接跑!!当然你要用VPC或者boch就自己把它的大小补到1.44M吧,这个问题前面也说过了就不罗嗦了。
P.S.一下,诸位大概都知道linux的内核文件叫zImage或者bzImage,z似乎指的是压缩?具体我还没研究过,所以就沿用0.11的镜像名字——Image
这样看来,混合编程写内核其实也是一件很容易的事情了,二进制内核文件也根本没有想象中得那么复杂。如果你愿意,你可以用c++来写,反正生成的都是ELF,不过效率嘛。。。
这个Makefile还远未完成(主要是内核还远未完成- -),以后有机会我就会扩充它的!
- 用来生成二进制内核的Makefile样例
- 用来构建内核模块的 Makefile
- Linux内核Makefile编译生成内核目标文件的过程
- Linux内核Makefile编译生成内核目标文件的过程
- Linux内核Makefile编译生成内核目标文件的过程
- 嵌入式中的Makefile是用来干什么的?
- 【Makefile】: linux内核的makefile
- Linux内核的Makefile
- 内核的Makefile
- linux内核的makefile
- 内核的Makefile
- 内核驱动的Makefile
- 内核模块的Makefile
- Asp用来生成json数据的类
- makefile的自动生成
- 生成.so的makefile
- 关于Makefile的生成
- 关于Makefile的生成
- 35岁前成功的12条黄金法则
- 文档库:下列文件已被管理员锁定
- 今天决定开始准备 信息系统项目管理师 的考试
- 问题与风险
- Have Fun In Happy Valley
- 用来生成二进制内核的Makefile样例
- 实习见闻之三
- 打造UltralEdit-32为C/C++编译器
- Ajax
- 水晶报表注册码
- VS.net2003+水晶报表10.0安装与部署
- 水晶报表网络资源
- 嵌入式面试考题
- 2007年互联网发展趋势预测:RSS将成为主流