HylicOS --- 工程结构记录

Makefile思路

Hylicos使用makefile构建工程,模仿linux层级编译的方法。
首先来看一下目录

.
├── Makefile
├── README.txt
├── build
│   ├── HylicOS_MAP.map    
│   ├── hylic_build_link.mk
│   ├── hylic_cmd.mk       
│   ├── hylic_cmd.mki      
│   ├── hylic_hal.mk       
│   ├── hylic_hal.mki      
│   ├── hylic_mem_link.lds 
│   ├── hylic_objs.mk      
│   ├── hylic_objs.mki     
│   ├── hylic_rule.mk
│   ├── hylic_rule.mki
│   ├── hylichal_start.i
│   ├── hylichal_start.o
│   ├── hylichal_start.s
│   ├── hylickrnl.bin
│   ├── hylickrnl.elf
│   ├── init.o
│   ├── init.s
│   ├── lmkfbuild
│   └── pretreatment.mkf
├── drivers
├── exckrnl
│   └── dnw2
├── kernel
├── hal
│   ├── hylichal_start.c
│   └── init.S
├── hylicinitldr
├── include
│   ├── config.h
│   ├── halinc
│   │   ├── halheads.h
│   │   ├── haltypes.h
│   │   ├── platform.h
│   │   └── platform_t.h
│   ├── hylictypes.h
│   ├── hylictypesrl.h
│   └── script
│       └── buildfile.h
├── release
├── script
│   ├── hylic_build_link.S
│   ├── hylic_cmd.S
│   ├── hylic_hal.S
│   ├── hylic_krl.S
│   ├── hylic_lib.S
│   ├── hylic_mem_link.S
│   ├── hylic_objs.S
│   ├── hylic_rule.S
│   └── hylic_task.S
└── task

根目录下有

  • build文件夹
  • hal文件夹
  • include文件夹
  • kernel文件夹
  • drivers文件夹
  • lib文件夹
  • script文件夹
  • 顶层makefile文件

逐一介绍他们的作用

顶层makefile

顶层的makefile作为工程编译的起点,它的职责是先对./script/文件夹中的.S 文件 做预编译 编为.mk和.lds文件(这一步由它调用build目录下的pretreatment.mkf文件完成)并放入到./build/文件夹下,接着逐一执行.mk文件(后缀.mk和.mkh 也是makefile文件 )

如果将所有的编译规则,编译目标,编译命令都放在一个makefile中,这样做会导致makefile很长很臃肿。我们将这个大makefile分为几个部分,各司其职:
编译目标部分(objs.mk) ,编译规则部分(rule.mk),负责链接部分(build_link.mk),编译命令部分(cmd.mk),
以及负责各个内核模块的部分(hal.mk负责硬件抽象层的编译,krl.mk负责内核层编译,drv.mk负责驱动层的编译
lib.mk负责对库的编译,这些模块的源码就在根目录下hal/ kernel/ drivers/ lib/ script/目录下保存着,负责各模块的源码会到各自的目录下获取源码进行编译)

./script/下的.S文件 预编译 生成出 ./build/下的 .mk .lds的对应关系:

./script/./build/
cmd.Scmd.mk
rule.Srule.mk
objs.Sobjs.mk
build_link.Sbuild_link.mk
mem_link.Smem_link.lds
hal.Shal.mk
krl.Skrl.mk
drv.Sdrv.mk
lib.Slib.mk
task.Stask.mk

表格中所有的.mk和.lds的作用前面已经说过,最后要说的是:
cmd.mk,rule.mk ,objs.mk 包含了编译命令,编译规则,编译目标,是最先被预编译的,并且后面会被其他makefile文件include,后面将会看到。

顶层makefile内容:
可以看到第一个执行的是$(MAKE) $(PREMENTMFLGS),它会到./build目录下执行pretreatment.mkf文件
(该文件就是负责执行预编译的makefile,后面详细说)

make命令 -C 进入到指定目录读取 -f 指定执行的makefile文件

MAKEFLAGS =-sR

MKDIR = mkdir
RMDIR = rmdir
CP = cp
CD = cd
DD = dd
RM = rm
MAKE = make
MKIMAGE =mkimage
SUPERUSER =sudo 
DKAPP =./dnw2 
DKAPFLAGES = hylickrnl.bin
PREMENTMFLGS = -C $(BUILD_PATH) -f pretreatment.mkf
ARMHALYMFLGS = -C $(BUILD_PATH) -f hylic_hal.mk
ARMKRNLMFLGS = -C $(BUILD_PATH) -f hylickrl.mk
ARMDRIVMFLGS = -C $(BUILD_PATH) -f hylicdrv.mk
ARMLIBSMFLGS = -C $(BUILD_PATH) -f hyliclib.mk
ARMTASKMFLGS = -C $(BUILD_PATH) -f hylictask.mk
ARMLINKMFLGS = -C $(BUILD_PATH) -f hylic_build_link.mk
DSTPATH 	= ../exckrnl
RELEDSTPATH = ../release
SRCFILE 	= hylickrnl.bin hylickrnl.elf
BUILD_PATH  = ./build
EXKNL_PATH 	= ./exckrnl
BOOTEXCIMG 	= hylic.bin
DSKIMG 		=flash.img
.PHONY : build print clean all cpkrnl knlexc writekrl downkrnl

build: clean print all

all:

	$(MAKE) $(PREMENTMFLGS)
	$(MAKE) $(ARMHALYMFLGS)
	$(MAKE) $(ARMLINKMFLGS)
	# $(MAKE) $(ARMKRNLMFLGS)
	# $(MAKE) $(ARMDRIVMFLGS)
	# $(MAKE) $(ARMLIBSMFLGS)
	# $(MAKE) $(ARMTASKMFLGS)
	@echo '[OK] Build Successfully!!!'

clean:
	$(CD) $(BUILD_PATH); $(RM) -f *.mkh *.lds *.o *.bin *.i *.elf *.krnl *.s *.map *.lib *.btoj *.vdi *vmdk
	$(CD) $(EXKNL_PATH); $(RM) -f *.mkh *.lds *.o *.bin *.i *.elf *.krnl *.s *.map *.lib *.btoj *.vdi *vmdk
	@echo '[C] Clear All Material'

print:
	@echo '================ Compiler Is Working ================='

knlexc: cpkrnl downkrnl

cpkrnl:
	$(CD) $(BUILD_PATH) && $(CP) $(CPFLAGES) $(SRCFILE) $(DSTPATH) 

build 目录下的pretreatment.mkf

这个文件主要是负责对/script/下 .S文件的预编译。其中PREMENTMK_OBJS和PREMENTMKI_OBJS指示了哪些文件需要被预编译。执行完pretreatment后,build目录下会多出很多东西,前面那个表格里的所有.mk .lds都拥有了,就可以逐步执行后面对各个模块的编译了。
值得注意的是,在我们对.S文件进行预编译时,由于GCC的历史机制会将.S文件中“linux”这个单词替换为“1”
这就导致我们对cmd.S预编译到cmd.mk时会遇到下面这种沙雕的情况:

CC = arm-linux-gcc  -->  CC = arm-1 -gcc

这会导致其他mk文件include这个cmd.mk文件时 都会用arm-1 -gcc去编译,make时就会报错找不到arm-1 -gcc这个鬼东西。
我查找了解决方案,发现在编译时应该添加 -pedantic 选项告诉GCC不要做这种替换。但是后来发现这个选项只对.c文件的预编译有效,对.S文件的预编译无效。

在我挣扎无果后,已经对这个机制投降了,我选择在预编译后手动去到.mk文件中修改这个“1”为“linux”
如果我们的makefile会在make时 自动执行make clean然后才开始编译,那我上面做的这个修改就被覆盖了,重新被gcc编译为“1”了。所以我们的makefile要设定为make clean时不将cmd.mk和rule.mk这类makefile清除。

MAKEFLAGS = -s
CCSTR		= 	'CC -[M] generating makefile... '$<
PRINTCSTR 	=	@echo $(CCSTR) 

CCSTRLMK	= 	'LMKFBUID -[M] generating makefile... '$<
PRINTCSTRLMK 	=	@echo $(CCSTRLMK) 

CC		= gcc
CPPFLGSLDS	= $(HEADFILE_PATH) -E -P 

KERNELCE_PATH = ../script/
HEADFILE_PATH = -I ../include/script/ -I ../include/ -I ../include/bastypeinc -I ../include/halinc

CCBUILDPATH	= $(KERNELCE_PATH)
LMKFBUID 	= ./lmkfbuild

PREMENTMKI_OBJS = hylic_objs.mki hylic_mem_link.lds   hylic_cmd.mki hylic_rule.mki hylic_hal.mki 
PREMENTMK_OBJS  = hylic_objs.mk  hylic_build_link.mk  hylic_cmd.mk  hylic_rule.mk  hylic_hal.mk  

.PHONY : all everything everymk build_kernel
all: build_kernel

build_kernel:everything everymk

everything : $(PREMENTMKI_OBJS) 

everymk : $(PREMENTMK_OBJS)


%.lds : $(CCBUILDPATH)%.S
	$(CC) $(CPPFLGSLDS) -o $@ $<
	$(PRINTCSTR)

%.mkh : $(CCBUILDPATH)%.S
	$(CC) $(CPPFLGSLDS) -o $@ $<
	$(PRINTCSTR)

%.mki : $(CCBUILDPATH)%.S
	$(CC) $(CPPFLGSLDS) -o $@ $<
	$(PRINTCSTR)

%.mk : %.mki
	$(LMKFBUID) -i $< -o $@
	$(PRINTCSTRLMK)

根据顶层makefile,执行完pretreatment.mkf后就要开始对各个模块进行编译了

hal.mk

可以看到hal.mk会include先前生成的cmd.mk 和 objs.mk

# HylicOS hal layout compiler makefile source
MAKEFLAGS = -s
KERNELCE_PATH = ../hal/
HEADFILE_PATH = -I ../include -I ../include/bastypeinc -I ../include/halinc -I ../include/knlinc -I ../include/libinc -I ../include/drvinc
CCBUILDPATH = $(KERNELCE_PATH)
include hylic_cmd.mk
include hylic_objs.mk
.PHONY : all everything build_kernel
all: build_kernel
build_kernel:everything
everything :$(BUILD_MK_HALY_OBJS)
include hylic_rule.mk

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值