Pokemon Center | 口袋中心 以口袋妖怪为主题并带有其他动漫游戏的讨论

 找回密码
 加入口袋中心
搜索
查看: 3667|回复: 26

【改版进阶教程】使用DevkitARM中的GNU Toolchain改版

[复制链接]

3827

帖子

-4万

现金

388

勋章券

超级版主

Rank: 26Rank: 26Rank: 26Rank: 26Rank: 26Rank: 26

积分
19037
QQ

时光印记Lv.3挥金如土勋章水中王者勋章Lv3Omega红宝石发售确认纪念章Alpha蓝宝石发售确认纪念章金银好CP-Ho-oh/LUGIA【里】金银好CP-Ho-oh/LUGIA【真·正常向】异化型LUGIA【M超梦版】

发表于 2016-9-13 23:24:58 | 显示全部楼层 |阅读模式
本帖最后由 jiangzhengwenjz 于 2016-9-13 23:24 编辑

【改版进阶教程】使用DevkitARM中的GNU Toolchain改版


这个教程可说是进阶教程中的入门级,很多原理性的东西不会涉及,而非主体部分的操作也尽量作简单处理。

先给出几个问题的解答:

1. 为什么要用devkitarm改版?
答:因为这个软件是免费的,也能满足普通改版者的需求。

2. 所有改版者都需要devkitarm吗?
答:并不,使用该开发包需要改版者预先掌握GBA ASM和C基础

3. 我们需要用它做什么?
答:能够编译你C和ASM源文件。

4. 为什么要自寻麻烦,不用IDE?
答:因为好像没有好用的IDE。

下面开始正文了

一、软件的安装:

所有教程里需要的软件在本帖末尾附带的链接中均可直接下载。

先下载devkitProUpdater-1.6.0.exe,并进行安装。完毕后将其安装目录下的devkitarm\bin目录添加到PATH变量(不如就加到系统变量吧)

然后下载make-3.81.exe,并进行安装。完毕后同样将bin目录加到PATH变量。(也可用MinGW中的make.exe,我就是用这个)

此外如果安装devkitpro时出现报错的话,请注意 安装目录\msys\bin是否已经添加到PATH变量,若没有则手动添加,否则程序无法正常运行。

最后,下载armips.exe并将其路径添加到PATH变量。

至此,我们的开发环境已然搭建完成了。

二、测试:

在实际上手编写程序之前,先测试一下开发环境是否正确搭建,是非常有必要的。这时需要随便找一个可以用这些程序来进行编译的工程,比如野生双战工程https://github.com/jiangzhengwenjz/Double_wild_battle

一般而言,在Readme文件中都会有详细的编译方法,对于这个工程也不例外。由于我们只是测试编译,所以没必要修改文件了,直接放入名为bpre0.gba的美版火红1.0 ROM,双击compile.bat就能进行编译。如果看到你的ROM被修改了,或是打开ROM测试一番,有几率遭遇野生双战了,那就说明编译成功了。(当然,要实际使用这个工程请仔细阅读readme,不然某些情况下100%死机)

如果没成功,就检验第一步有什么遗漏。

三、各程序简介:

其实在添加环境变量时就很明显了,devkitpro安装目录下的devkitarm\bin里就是它所附带的GNU Toolchain,里面有非常多的工具,不过常用的并不多,这里只介绍一部分。
  1. arm-none-eabi-as - 依据asm源文件输出中间目标文件
  2. arm-none-eabi-gcc - 依据c源文件输出中间目标文件
  3. arm-none-eabi-ld - 对目标文件进行连接
  4. arm-none-eabi-nm - 列举目标文件中的符号
  5. arm-none-eabi-objcopy - 从目标文件中获取纯数据
复制代码
而armips的功能则较为复杂,它本身是asm的编译器(只不过部分用法和arm-none-eabi-as不同罢了,具体请阅读https://github.com/Kingcom/armips/blob/master/Readme.txt),不过可以直接打开/关闭某个文件,执行写入。此外,它还可以导入目标文件,并使用其中的全局变量。

因此,如何编写程序其实已经很明显了,先通过as或是gcc生成目标文件(一般扩展名.o),然后对生成的目标文件进行连接,最后用armips进行字节变更,并导入用ld连接后的目标文件即可。

但是,由于并没有一个IDE生成makefile,如果一个个文件去编译,连接,在文件较多的情况下,每次都要输入如此众多的命令,显然是不现实的。这也是为何我们要用make的原因。make是一个很强大的程序,默认的文件名为makefile,无扩展名。(或是用-f参数选择文件输入)我们能在其中预先定义好编译的规则,这样,只需要在命令窗口中输入make即可完成整体的编译。windows下在某目录下打开命令窗口的方法是:shift+右键即可看到该选项。

当然,makefile有其专门的语法,不过我们的重点并不在此,只需掌握一些基本的方法即可。

四、实战:
空中楼阁般的谈话很难让人抓住问题的关键,所以干脆来看个例子吧。依然是刚才的野生双战。具体如何书写代码不是本教程的重点,不过看过这个例子应该也就了解得差不多了。

了解makefile语法可以看这篇:http://blog.csdn.net/ruglcc/article/details/7814546/

(不过我个人觉得不需要看就是了,因为我们只需用到基本中的基本,复杂的部分要用到也可以依葫芦画瓢。。。)

如果要用我这个模板的话,你也需建立一个src文件夹,用来存放源文件(当然,也可以有子文件夹)

.gitignore, ReadMe.txt, compile.bat, compile.sh与工程本身无关,大可无视。我们直接来看makefile好了。(只需在cmd中输入make即可编译)
  1. #后的是注释
  2. #在这里我们定义变量,这样写规则时会简单
  3. #这个工程没有C文件,所以不用gcc
  4. #所有的源码都依赖于跳出,无需获得.bin以及各代码具体的地址,故无需objcopy及nm
  5. AS=arm-none-eabi-as
  6. LD=arm-none-eabi-ld
  7. ARS=armips
  8. #这种变量都相当于C中的宏
  9. #gcc的参数可以看我其他工程
  10. ASFLAGS=-mthumb
  11. LDFLAGS=-z muldefs

  12. BLDPATH:=build
  13. #这段不用懂,你可以认为就是设定了src中.asm文件的编译规则吧。
  14. rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))

  15. ASSRC := $(call rwildcard,src/,*.asm)
  16. ASOBJS := $(ASSRC:%.asm=$(BLDPATH)/%.o)

  17. $(BLDPATH)/%.o: %.asm
  18.         $(shell mkdir -p $(dir $@))
  19.         $(AS) $(ASFLAGS) -c $< -o $@
  20. #all实际上是一个伪目标,不过不用.PHONY也无所谓的
  21. #--relocatable是为了从armips中导入链接后的.o文件,也就是暂时不指定链接的地址
  22. #除非用objcopy直接获取bin,这就需要在linker.lsc中指定地址
  23. all: $(ASOBJS)
  24.         $(LD) $(LDFLAGS) -T linker.lsc --relocatable -o  "build\linked.o" $(ASOBJS)
  25.         $(ARS)  insert.s
复制代码
linker.lsc:
(这个文件在链接时使用,来确定数据的排布,如果用objcopy的话,将0x08000000改为写入的地址,才能生成对应的bin)
  1. OUTPUT_ARCH(arm)
  2. MEMORY {

  3.         rom     : ORIGIN = 0x08000000, LENGTH = 32M
  4.         ewram   : ORIGIN = 0x02000000, LENGTH = 4M - 4k
  5. }

  6. SECTIONS {
  7.         .text : {

  8.                 FILL (0xABCD)

  9.                 __text_start = . ;
  10.                 *(.init)
  11.                 *(.text)
  12.                 *(.ctors)
  13.                 *(.dtors)
  14.                 *(.rodata)
  15.                 *(.fini)
  16.                 *(.data)
  17.                 *(COMMON)
  18.                 __text_end  = . ;

  19.                 __bss_start__ = . ;
  20.                 *(.bss)
  21.                 __bss_end__ = . ;
  22.         _end = __bss_end__ ;
  23.         __end__ = __bss_end__ ;
  24.         } >rom = 0xff
  25. }
复制代码
再来看看armips所需的文件吧,也在makefile中要求编译了:
  1. //一切C源码中的变量,和asm中的全局变量都可以直接在这里引用
  2. //.open和.close打开 关闭文件
  3. .gba
  4. .thumb
  5. .open "bpre0.gba", 0x8000000
  6. ;remove the stupid limiter
  7. .org 0x807F760
  8. .byte 0,0
  9. ;misc fixes
  10. .org 0x802D812
  11. .byte 0,0
  12. .org 0x802D858
  13. .byte 0,0
  14. .org 0x802D8A6
  15. .byte 0,0
  16. .org 0x802D8F4
  17. .byte 1,0x1C
  18. .org 0x802DF36
  19. .byte 8,0x1C
  20. .org 0x802DE58
  21. .byte 0,0
  22. .org 0x802DE84
  23. .byte 0,0
  24. .org 0x802DEA4
  25. .byte 0,0
  26. .org 0x802DEC2
  27. .byte 4,0x1C
  28. .org 0x802D874
  29. .word 0x2023D6C
  30. .org 0x802D94C
  31. .word 0x2023D6C
  32. .org 0x802DF64
  33. .word 0x2023D6C
  34. .org 0x802DF04
  35. .word 0x2023D6C
  36. ;flee fix
  37. .org 0x8016824
  38. ldr r0, =double_wild_flee_fix+1
  39. bx r0
  40. .pool
  41. ;audio fix
  42. .org 0x8021D46
  43. .byte 0,0x47
  44. .org 0x8021D94
  45. .word double_wild_audio_fix+1
  46. ;pokemon catch
  47. .org 0x802D44C
  48. .byte 0x30,0x47
  49. .org 0x802D480
  50. .word double_wild_catch_fix+1
  51. ;dex fix
  52. .org 0x802D95C
  53. ldr r0, =double_wild_dex_fix+1
  54. bx r0
  55. .pool
  56. ;dex fix 2
  57. .org 0x802D9DE
  58. .byte 0,0x47
  59. .org 0x802DA00
  60. .word double_wild_dex_fix_2+1
  61. ;ball throw fix
  62. .org 0x80EF5F8
  63. .byte 0x10,0x47
  64. .org 0x80EF680
  65. .word double_wild_ball_throw_fix+1
  66. ;pokeball fix
  67. .org 0x80A1E1C
  68. ldr r1, =double_wild_pokeball_fix+1
  69. bx r1
  70. .pool
  71. ;main func for normal RAND wildbattle
  72. .org 0x8082AF4
  73. ldr r3, =double_wild_main_fix+1
  74. bx r3
  75. .pool
  76. ;my fault: the pure function deactivation
  77. .org 0x8082A0C
  78. .word 0
  79. ;fade fix
  80. .org 0x8011D72
  81. mov r0, #0xA
  82. lsl r0, r0, #0x10
  83. .org 0x8011DFE
  84. mov r0, #0xA
  85. lsl r0, r0, #0x10
  86. ;switch battle script fix
  87. .org 0x81D86AD
  88. .byte 0x28
  89. .word double_wild_switch_bs_fix
  90. ;skip fix
  91. .org 0x801417E
  92. mov pc, r1
  93. lsl r0, r0, #0
  94. lsl r0, r0, #0
  95. lsl r0, r0, #0
  96. .org 0x80141B0
  97. .word skiphack
  98. .org 0x8019688
  99. ldr r0, =skipmsghack
  100. mov r15, r0
  101. .pool
  102. //这里导入之前在makefile中链接好的目标文件
  103. .org 0x8F00000
  104. .importobj "build/linked.o"
  105. .close
复制代码
了解了基本的方法以后,就可以看一个更为复杂的例子了。下载HGSSANIMATION.zip,这是一个只完成了一小部分的HG开头动画(就是GAME FREAK那边),可以从中看一些参数,因为这用到了asm和C的混合编程。用C编程基本和网上入门书籍里面的内容差不多,甚至更简单一些。其中的bpre.ld是用于直接定义symbol的值的,很容易看懂。不过使用前还要再声明一下就是了,无论是常量,还是函数指针。连接时使用它就万事大吉了。

五、杂项:

    我觉得看过整个教程后,很多人会疑惑Hackmew的thumb编译器是怎么弄的呢?实际上也很简单,他的基本思路也就是先使用as生成目标文件,再用objcopy生成纯数据文件(.bin)。不过,只是用这么一个batch的话,当然也就不能处理多文件工程(除非你统统.include或是.incbin - -),同时也不能发挥ld的巨大作用了。若是直接用.org也是无法直接写入ROM的。因此,在面对文件较多或是涉及C语言的工程时,还是应当使用上述的方法,而非用Hackmew的batch。当然,.global, .thumb_func等原先用不上的directive现在也变得很重要了,这点也是很明显的。

    就我个人观点,除了地图等必须可视化操作的数据,大部分的数据都可以用这种方法直接写入ROM,不用找空位,留空,计算空间等,同时也是一键写入,随时可增减、修改源码,也能避免很多低级错误,无疑是十分方便的(本质上,这是编译器帮我们处理了大量的工作)。不过对于很多表格等,也需要自己编写对应的程序来输出源文件便于阅读和修改,这点稍显麻烦。不过无疑用这种方法改版绝对是利大于弊的,能够随意地使用SYMBOL,绝对是无比快意的。

六、资料:

程序参数(大部分时候照抄就可以了,除了一些目录什么的):
https://www.mankier.com/1/gcc
https://www.mankier.com/1/ld
https://www.mankier.com/1/as
https://www.mankier.com/1/nm
https://www.mankier.com/1/objcopy

教程中资料下载:
游客,如果您要查看本帖隐藏内容请回复


全文完
回复

使用道具 举报

259

帖子

92

现金

2

勋章券

摆脱困境的长叹

Rank: 8Rank: 8Rank: 8Rank: 8

积分
543

水中王者勋章Lv1异化型LUGIA【M超梦版】

发表于 2016-9-14 04:33:27 | 显示全部楼层
感谢分享
那啥这软件是干啥用的
回复 支持 反对

使用道具 举报

3827

帖子

-4万

现金

388

勋章券

超级版主

Rank: 26Rank: 26Rank: 26Rank: 26Rank: 26Rank: 26

积分
19037
QQ

时光印记Lv.3挥金如土勋章水中王者勋章Lv3Omega红宝石发售确认纪念章Alpha蓝宝石发售确认纪念章金银好CP-Ho-oh/LUGIA【里】金银好CP-Ho-oh/LUGIA【真·正常向】异化型LUGIA【M超梦版】

 楼主| 发表于 2016-9-14 12:14:50 | 显示全部楼层
歃亟源星 发表于 2016-9-14 04:33
感谢分享
那啥这软件是干啥用的

看贴费电,不懂就不要回复
回复 支持 反对

使用道具 举报

259

帖子

92

现金

2

勋章券

摆脱困境的长叹

Rank: 8Rank: 8Rank: 8Rank: 8

积分
543

水中王者勋章Lv1异化型LUGIA【M超梦版】

发表于 2016-9-14 12:17:03 | 显示全部楼层
jiangzhengwenjz 发表于 2016-9-14 12:14
看贴费电,不懂就不要回复

大大我错了,这个是做改版用的软件么,是个大工程呢
回复 支持 反对

使用道具 举报

3827

帖子

-4万

现金

388

勋章券

超级版主

Rank: 26Rank: 26Rank: 26Rank: 26Rank: 26Rank: 26

积分
19037
QQ

时光印记Lv.3挥金如土勋章水中王者勋章Lv3Omega红宝石发售确认纪念章Alpha蓝宝石发售确认纪念章金银好CP-Ho-oh/LUGIA【里】金银好CP-Ho-oh/LUGIA【真·正常向】异化型LUGIA【M超梦版】

 楼主| 发表于 2016-9-14 12:18:18 | 显示全部楼层
歃亟源星 发表于 2016-9-14 12:17
大大我错了,这个是做改版用的软件么,是个大工程呢

这就是改版的工具。。
回复 支持 反对

使用道具 举报

259

帖子

92

现金

2

勋章券

摆脱困境的长叹

Rank: 8Rank: 8Rank: 8Rank: 8

积分
543

水中王者勋章Lv1异化型LUGIA【M超梦版】

发表于 2016-9-14 12:21:00 | 显示全部楼层
jiangzhengwenjz 发表于 2016-9-14 12:18
这就是改版的工具。。

膜拜大大,膜拜大大,膜拜大大
回复 支持 反对

使用道具 举报

20

帖子

77

现金

0

勋章券

口袋学堂外的努力

Rank: 2Rank: 2

积分
40
发表于 2016-9-14 12:40:24 | 显示全部楼层
然而,有不有32位的armips.exe
回复 支持 反对

使用道具 举报

3827

帖子

-4万

现金

388

勋章券

超级版主

Rank: 26Rank: 26Rank: 26Rank: 26Rank: 26Rank: 26

积分
19037
QQ

时光印记Lv.3挥金如土勋章水中王者勋章Lv3Omega红宝石发售确认纪念章Alpha蓝宝石发售确认纪念章金银好CP-Ho-oh/LUGIA【里】金银好CP-Ho-oh/LUGIA【真·正常向】异化型LUGIA【M超梦版】

 楼主| 发表于 2016-9-14 12:50:36 | 显示全部楼层
Against 发表于 2016-9-14 12:40
然而,有不有32位的armips.exe

不行就用老外那个python模板吧,不过没armips那么方便就是了
回复 支持 反对

使用道具 举报

20

帖子

77

现金

0

勋章券

口袋学堂外的努力

Rank: 2Rank: 2

积分
40
发表于 2016-9-14 12:52:35 | 显示全部楼层
jiangzhengwenjz 发表于 2016-9-14 12:50
不行就用老外那个python模板吧,不过没armips那么方便就是了

所以问题就是,python也用不了
回复 支持 反对

使用道具 举报

20

帖子

77

现金

0

勋章券

口袋学堂外的努力

Rank: 2Rank: 2

积分
40
发表于 2016-9-14 12:52:56 | 显示全部楼层
Against 发表于 2016-9-14 12:52
所以问题就是,python也用不了

吐血
回复 支持 反对

使用道具 举报

20

帖子

77

现金

0

勋章券

口袋学堂外的努力

Rank: 2Rank: 2

积分
40
发表于 2016-9-14 12:53:44 | 显示全部楼层
算了,等大学买新电脑了再说
回复 支持 反对

使用道具 举报

148

帖子

167

现金

2

勋章券

繁华都市的喧闹

Rank: 5Rank: 5Rank: 5

积分
278
发表于 2016-12-29 21:24:58 来自手机 | 显示全部楼层
围观,感觉挺有用的,就是老安装不了
回复 支持 反对

使用道具 举报

89

帖子

210

现金

2

勋章券

繁华都市的喧闹

Rank: 5Rank: 5Rank: 5

积分
237

论坛十周年纪念物时光印记Lv.1


妙蛙花 Lv:34
发表于 2016-12-29 22:53:14 | 显示全部楼层
惊恐无比的眼神.jpg
听泡泡说了过来看看
回复 支持 反对

使用道具 举报

3827

帖子

-4万

现金

388

勋章券

超级版主

Rank: 26Rank: 26Rank: 26Rank: 26Rank: 26Rank: 26

积分
19037
QQ

时光印记Lv.3挥金如土勋章水中王者勋章Lv3Omega红宝石发售确认纪念章Alpha蓝宝石发售确认纪念章金银好CP-Ho-oh/LUGIA【里】金银好CP-Ho-oh/LUGIA【真·正常向】异化型LUGIA【M超梦版】

 楼主| 发表于 2016-12-29 23:01:50 | 显示全部楼层
米米尔 发表于 2016-12-29 22:53
惊恐无比的眼神.jpg
听泡泡说了过来看看

只是一篇偏重应用,什么原理都没讲清的菜文...
如果接下来有闲下来的机会我可能会多发帖,甚至是转载一些国外的经典教程
回复 支持 反对

使用道具 举报

89

帖子

210

现金

2

勋章券

繁华都市的喧闹

Rank: 5Rank: 5Rank: 5

积分
237

论坛十周年纪念物时光印记Lv.1


妙蛙花 Lv:34
发表于 2017-1-3 14:34:44 | 显示全部楼层
jiangzhengwenjz 发表于 2016-12-29 23:01
只是一篇偏重应用,什么原理都没讲清的菜文...
如果接下来有闲下来的机会我可能会多发帖,甚至是转载一 ...

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入口袋中心

本版积分规则

手机版|Archiver|Pokemon Center

GMT+8, 2019-8-25 15:14 , Processed in 0.058835 second(s), 49 queries , Eaccelerator On.

Powered by Discuz! X3

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表