1.代码环境
代码的编写使用 vscode 编辑器 ,使用gcc 交叉编译工具链进行编译,运行在qemu 模拟器上,代码debug调试 使用 gdb 。 整体环境部署在docker 环境中。
2. 仿照Linux 创建目录
在上一篇文章中,labs 目录下 创建一个 lab1目录。 本节的实验代码全部书写在lab1中。 lab1目录的创建参考如下结构。
其中蓝色字体为目录 , 我们的代码编译需要使用 make 进行控制 自动化进行编译。因此我们创建了若干Makefile 进行编译控制代码的书写。
关于Makefile 文件的书写规则,可以参考
陈浩 【左耳朵耗子】《跟我一起写Makefile》
3. 编写Makefile控制编译运行与clean
kernel 目录中的Makefile 只需要控制head.S 的编译,arm64目录下的 Makefile 控制子目录Makefile 和 它当前同级目录下文件的编译(当前arm64目录下的Makefile 暂时没有同级文件)。 这样通过层层管理,最后可以很方便的通过一个make 命令 控制整个工程的编译。
3.1 书写顶层Makefile
我们书写Makefile 文件从 顶层的 Makefile 文件开始 即lab/Makefile
首先需要定义模式器qemu 的路径和各种gcc工具的路径 代码如下:
export
QEMU := /home/qemu-4.0.0/aarch64-softmmu/qemu-system-aarch64
CROSS := /home/gcc-arm64-toolchains/bin/aarch64-none-linux-gnu-
nm = $(CROSS)nm
OBJDUMP = $(CROSS)obj
OBJCOPY = $(CROSS)obj
LD = $(CROSS)ld
CC = $(CROSS)gcc
AS = $(CROSS)as
ARCH = arm64
$(变量名) 为Makefile 中引用变量的方式
- nm 用于生成符号表
- OBJCOPY 用于生成镜像文件Image
- CC 为编译器 这里就是 gcc 负责将.c文件编译成.S 汇编文件
- AS 是汇编器 负责将.S 汇编文件 汇编成 .o文件 (二进制文件)
- ld 是链接器 负责将工程下的 .o 文件 链接到一起 生产成 ELF 可执行文件 其中链接规则书写在vmlinux.lds.S中
然后我们定义编译器gcc 在执行编译过程中的一些参数
#
CFLAGS := -c -g -ffreestanding -O2 -Wall -Wextra -nostdlib -nostdinc
CFLAGS += -I $(shell pwd)/include -I $(shell pwd)/arch/arm64/include
编译器部分参数解释:
-c 执行到编译 输出目标文件 不进行链接 -I 指定头文件所在文件夹
-ffreestanding 告诉编译器标准库可能不存在 并且函数可能不是从main 开始
链接器参数:
LDFLAGS := -O2 -nostdlib # 进行优化 没有标准库
LDS := ./arch/arm64/kernel/vmlinux.lds.S # 链接脚本所在的位置
一般我们在使用gcc 时, 编译套件调用了默认的链接脚本文件。 这里为了认识更加深刻,我们自己动手写自己的链接脚本。链接脚本主要负责向链接器说明, 程序在内存中布局。
关于链接脚本的语法 可以参考我给出的这本小册子:
LDS链接脚本基础 百度云 密码:35w7
更多关于 程序的链接 装载方面的知识可参考:
程序员的自我修养 装载 链接 和