【娇娘内核】完整解密

来源:互联网 发布:网络平台计划书 编辑:程序博客网 时间:2024/04/24 21:15

这个很好,一直想了解的,转之。原帖,感谢“华敏乐”

-------------------------------------------------

前言:
DSTT是一种对应NDS的游戏扩展设备,在我国全国同类设备相比拥有绝对市场占有优势,以便宜简单易用为主要特点得到广大用户欢迎。但是,其也自生有着一些列的缺点,如:文件载入速度慢、更新系统文件需要用户独立完成、功能单一,兼容性不佳等等。于是我便应此决定对其内核部分(操作系统)进行改造和重开发,以实现它原本不支持的功能,与此同时解决原先所拥有的缺点。经过我的设计组近二十多个版本的改良后,我们的内核系统目前已经在网络上已经拥有了广泛的用户,并受到了大家的热烈欢迎和一致好评。

原本官方系统所支持的功能如下:支持NDS游戏运行、支持自制软件(由网友自行开发的软件)、可以提供金手指功能(内存修改器)等功能。在官方有基础上,我们对其经过改良之后,现在所支持的功能和缺点的修正:强化了DSTT对于自制软件的兼容性、增加对漫画文件(IPK)的支持、在当前系统下TF卡中文件可以随意删除、增加了对GBC、GB、MD、FC、SFC、NEO游戏软件的直接支持、支持软件关机、解决官方内核LOADING死机问题、曾加了对多媒体格式的支持(MP3,MP4,JPEG,WMA等三十余种)、程序载入速度大幅加快等多种功能上的改进。

二、开发环境简介以及具体需求

对于NDS程序的开发这里需要一个特殊的编译环境(用于对ARM系列CPU编程)。在NDS的Homebrew(自制软件)领域中,首先要认识的是libnds 、 devkitPro与PAlib这三项开发NDS程序的编译环境:
libnds ,是由几位热爱NDS 程序的开发者,经由反向工程所制作出来的一套非官方版本的函数库。PAlib ,以libnds 为基础所建构起来的高阶函数库,能够免除掉许多关于内存的操作与复杂的低阶程序,相当便于NDS 程序开发入门者使用。devkitPro,开发各种Console 平台程序的工具组,其中包含了开发NDS 与GBA 用的devkitARM ,开发PSP 用的devkitPSP ,还有开发Gamecube 用的devkitPPC 。 
在这里我选择了devkitPro作为开发环境,其编码方式为我们做熟悉的C语言,同时C语言也是嵌入式系统开发的利器。除此之外需要先下载并且安装几项必备的软件项目:
l Visual C++ Express 2005 (或Professional 以上版本):Windows 平台上的程序开发必备IDE,相信不用多做介绍。
l devkitPro Windows Installer :这是安装devkitPro 工具组用的Updater,确认要安装的部分之后,它会直接连上网络下载所需的最新组件。
l Emulators:各种PC 平台上模拟真实NDS 执行环境的模拟器,能够让程序设计者很便利地检视并测试程序的执行成果,这些模拟器包括有No$GBA 、 Dualis 、 iDeaS 、 DeSmuMe等等。
l Visual Basic:使用VB编译WINDOWS下简单的应用程序真的十分方便,用于“自动更新”这类应用程序开发。
l MoonShell:也就是标题中提到的MS,本身只是NDS的一款多媒体程序,用于音乐播放等多媒体功能,由于其自身一系列的优秀特性,我将把它改造成内核的主体程序。
l NSIS:NSIS(Nullsoft Scriptable Installation System)是一款安装程序制作软件。通过制作NSI脚本,用于制作Windows下应用程序的安装包程序。

三、具体开发过程
该节主要由以下几个部分组成:
1. 程序流程图 
2. 原内核原理和相关分析——原理分析 
3. 对MoonShell进行分析与改造——分析与改造 
4. 对YSMENU进行分析和设置——分析与设置 
5. 制作插件和编写相关主要程序——程序设计 
6. 将程序进行连接与调试——连接调试 
7. 部分关键源代码公开


.程序流程图
为了文章阅读方便我设计了一个简单的程序运行流程图。从图中我们可以很清楚地看到启动一个NDS程序的具体过程。一共需要2个主要步骤和多个细微的过程。接下来内容中,我将对程序的流程、程序设计的过程、程序间的连接进行详细的解释。


(注:此图用于帮助理解NDS程序文件打开的过程,不是全部内核功能的解释。)


2. 原内核原理和相关分析(TTMenu)

原内核由TTMENU.DAT与TTMenu文件夹组成,在TTMenu文件夹中存放了许多用于内核调用的文件。下面列举几个十分重要的文件。
1. Savlib.dat是为加快内核存档速度而外置的数据库。
2. Infolib.dat是为加快内核读取速度而外置的数据库。当内核运行的游戏被数据库包含,内核将调出该数据,免去加载游戏的过程。
3. Userchet.dat是金手指文件用作对程序内存做修改。
4. skin文件夹是由程序的皮肤文件(图片)组成的。

由于篇幅问题不对所有文件一一举例说明了。


3. 对MoonShell进行的分析与改造

l 对MoonShell进行的分析
在上一节中我提到,MoonShell(以下简称MS)本身只是NDS的一款多媒体程序,用于音乐播放等多媒体功能,由于其自身一系列的优秀特性,我将把它改造成内核的主体程序。接下来我先来谈谈对其的文件组成、工作原理以及改造的方法。
MS通常安置于磁盘根目录,由一个名为moonshl2.nds(注:NDS平台的可执行程序后缀名是NDS)的文件和同名文件夹组成。其中moonshl2.nds为主程序文件,用来引导和管理moonshl2文件夹下的文件。下图为moonshl2文件夹中包含的所有文件和文件夹。



通常MS所管理的文件都位于/Moonshl2文件夹下,接下来我将对该文件夹下重要的文件和文件夹做一下详细的介绍:
launch文件夹,用于存放常用程序,可以在MS中直接打开这些程序。
resetmse 文件夹,用于软件复位插件的设置。
language 文件夹,里面是系统的语言文件。
此外,我们还需要主要关注的是extlink.Dat文件和extlink文件夹(如上图)。MS可以通过这个文件为用户提供了类似于Windows下“打开方式”的功能。也就是说,当你在MS下执行各种文件时,他会通过对所执行的文件的扩展名进行识别,依据相应的扩展名调用对应的程序打开文件。而这里只需要将对应的程序放置于extlink文件夹下,并且按照“***.NDS”的方式命名即可。例如:将用于NDS的MP3的播放程序,命名为MP3.NDS并放置于只个文件夹下。当你下次在MS中执行以MP3为扩展名的文件时,MS将打开播放程序,并且还可以通过对播放程序的修改达以到自动播放的效果。
等。
其实还有许多的文件,限于篇幅我就不一一介绍了。


l 对MoonShell进行的改造
现在开始我来介绍如何对MS进行改造。NDS自制程序是需要储存在TF(Mini SD)卡中的,MS也不例外。它由多个文件组成,要让它为内核的主体必须修改其文件读取路径,否侧程序将在TF卡的根目录留下大量文件,这是广大用户所不希望见到的。又因为TTMenu会自动搜索TF卡中以“*.NDS”结尾的程序。当在MS中安装大量插件时,TTMenu也会搜索到这些插件,导致选择界面会变得十分混乱。在研究过程中我发现TTMenu不会搜索3层以上的目录结构,所以可以通过对MS的改造实现对插件程序的隐藏(插件可以自动调用,不需要显示)。

由于NDS程序编译过程的特性,使得编译后的程序不会对具体ASCII码类的数据进行加密,而带文件的系统的自制软件 在设计过程中会指定所要读取文件的路径,而在编译好的程序中,这些路径通常是明码保存,这就为我们改变路径提供了条件。(这一部分以对MS2.05的修改为例子,之前方法与之不同)

首先,需要一个16进制编辑器,我这里使用的是CrystalTile2,打开CrystalTile2(以下简称CT2),载入moonshl2_DirectBoot.nds(程序主文件,右图),并切换到16进制编辑器.

MS中主要读取的文件夹是Moonshl2 所以我们以moon为关键字来搜索。如右图,我搜索的关键字是“moon”(小写的,如下图)注意右侧文字“Please refer [/moonshl2/logbuf.txt]”这里是程序发生错误时,读取的字符串地址。将其修改为[/TTMenu/M/logbuf.txt],其中TTMenu/M是对应新文件夹的位置。要注意的是修改的位置字符长度不可比原先的长,不然会破坏程序文件整体长度,使得程序运行出错。接下来不断搜索关键字“moon”,直到全部修改完毕。



第二步,搜索关键字“MOON”,这次是大写的。可以看到如下结果:“/MOONSHL2/%S.”(如右图)这里(红字部分)便是MS运行是调取文件的路径之一,用同样的方法修改。接下来不断搜该索关键字,直到全部修改完毕。


现在完成了主文件的修改。在修改的过程中我发现,主文件只是一个调用程序,其主要功能部分并没有包含其中。于是我开始对MS所有包含的所有文件进行分析,最后目标锁定了一个名叫overlay.dll的文件。
首先对它进行与主文件(moonshl2_DirectBoot.nds)几乎相同的改造:先分别搜索的关键字 “moon”与“MOON”,然后修改数据读取位置,直到没有出现重复的路径,这时就修改完成了。

不过再完成对这些位置的修改之后,我发现一直没有修改过一个叫“/moonshl2”的字符串,所以还需要查找。不然程序运行时会报错(除非你还保留着根目录的moonshl2文件夹),那么这个路径到底在哪呢?当时也我也很困扰,接下来搜索“ 6D006F006F ”,这时看到了搜索结果“/ m o o n s h l 2 ”。
至于为何要搜索6D006F006F,其实m的ASCII码是“6D”,同理o的是ASCII码“6F”, 当然中间不是空格,而是空(NULL),其ASCII码是“00”(注意不是,空格的ASCII码是“20”)以此类推。具我推断这和UNICODE字符集(扩展ASCII)有关。 所以不能搜索“m o o ”。具体方法如下图:



4.对YSMENU进行分析和设置

YSmenu是一个由日本的程序员YASU制作的引导程序,比官方内核在文件引导方面具有更高的文件载入稳定性,可以一定意义上防止载入程序时发生死机的错误。又因为它可以通过合理的设置完成一些特殊的功能(如上文提到的自动引导)。考虑到这两点我将它作为对游戏程序引导的介质。

他有着一系列独有的优势功能。比如可以任意删除文件、备份文件、查看文本文档以及可以通过自带的YSMENU.INI文件实现一系列的扩展功能等。

YSMenu.ini是YSmenu.nds的配置文件,这个文件的修改和其参数的设置相当重要。下面我来详细解释一下,其内容和功能。限于篇幅这里之展示主要字段的设置参数,还有大约50条左右的皮肤和语言设置就不做详细介绍了。我还会从中选择几个重要的字段为大家做一下解释。


“BRIGHT”字段记录的是:NDS主机在使用YS时系统背光亮度的高低。NDS主机一共有4级亮度(仅限于NDSL,其中最新的NDSI有5段亮度),在这里0表示最低亮度,3表示最高,-1这个值表示保持系统当前的状态不做修改。
“DEFAULT_DMA=true” 字段是用于设置是否开启TF卡的DMA工作方式的状态设置字。打开时可以提高程序运行的速度和效率,关闭时可以程序提高兼容性。默认是关闭状态。
“AUTO_BOOT”是这里最重要的字段,可以在这里设置一个程序的地址,用于启动YSmenu的自动运行功能。
例如:当在之一字段设置“AUTO_BOOT = /A/tt.nds”,那么当YSMnenu在启动时就会自动引导“A”文件夹下的“tt.nds”自动运行。 在接下来“编写相关程序“的章节我将详细介绍:如何利用YS自动运行的功能,实现直接在MS下引导NDS程序。
至于YSMENU.INI的其他字段一般保持原样,不需要做特别修改。

5.制作插件和编写相关主要程序

为了使多个程序之间无缝连接,以及为用户提供更多功能和使用上的便利。我们还需要编写一系列相关程序。除了主题部分YS与MS之外还需要编写多个相关程序和修改多个已有的程序。在下一节会公布出该部分对应的程序源代码。

l 多重引导程序
由于用户的需求不同,(比如:有的用户偏爱多媒体功能,有的用户喜欢玩游戏,还有的用户喜欢原有内核的感觉)导致大家往往喜欢开机时可以进入不同的界面。于是我们制作了2中开机多重引导程序。一种是通过开机按下对应的按键来选择进入的界面,一种提供了一个用于选择的界面。
“按键引导”的原理是:用户开机时按下相应的按键作为触发信号,来引导系统进入不同的界面。程序本身为了简洁高效,没有制作提示界面。比如当你按下NDS上的按键时,程序就会调用一个名叫“/TTMenu/BOOT.DAT”的文件,该文件记录的内容描述如下:


可以十分直观的看出该文件的结构组成。当用户按下的是A键,会进入游戏设置引导界面(YSMenu),当用户按下的是B键,会进入原版内核界面(TTMenu),如果不做操作(或者其他操作),将进入Moonshell多媒体软件。其中文件中的“PATH”字段表示相对的引导方式的主程序的绝对路径,而“Bootmethod”字段是保留字段不展开阐述。

l 有选择界面的引导程序:

有一些用户不喜欢“按键引导”这样的引导方式,他们更喜欢直接的选择界面于是便有了下面这个程序。(下图)

他的基本功能与之前的“按键引导”程序相同,也是通过不同的用户选择而进入不同的用户界面。不过他多了一些简单实用的功能。图中的上半部分是调用BIOS中的时钟实现的。下图中,音乐的图标是进入Moonshell,游戏图标是进入Ysmenu(或者TTmenu可选择)。左下角的时钟是用来设置当前时刻,右下角图标是用来设置触摸板的精准度。可以使用方向键选择这些图标或者使用直接触摸这些图片来运行其相应的功能。


l NDS程序引导插件

在“对MoonShell进行的分析与改造”一节中我曾经提到,MS通过extlink.Dat这个文件为用户提供了类似于Windows下“打开方式”的功能。也就是说,当你在MS下执行各种程序时他会通过对所执行的文件的扩展名进行识别,依据相应的扩展名调用对应的程序打开文件。而这里只需要将对应的程序放置于extlink文件夹下,并且按照“***.NDS”的方式命名即可。

MS本身是不支持直接运行大型NDS(大于4M)程序的。那么如果需要用MS引导大型nds程序,就需要编写一个引导程序。用其改写YSmenu的配置文件,并启动YSmenu使得其调用自动运行功能来完成对“*.NDS”文件的间接运行。

上图中所显示的“nds.YSloaderForMS2.nds”便是为MS2量身打造的一个NDS程序引导插件,旁边的就是与其配套的设置文件config.ini。程序基本原理如下:当运行以NDS作为扩展名的程序时,MS会将会往extlink.Dat写入所运行的文件的位置。然后,该插件将会调用extlink.Dat中的数据“所运行的文件的位置”并写入YSmenu的设置文件YSmenu.ini中的“AUTO_BOOT”(自动启动)字段,并将YS调入内存。之后往CPU的PC(指令指针)写入YSMenu的内存地址所在的开始位置,完成各个寄存器的初始化用于启动YSmenu(这里是对ARM的CPU进行编程无发使用高级调用,所以只可以对底层进行操作)。当YSMenu启动后自身会调用其设置文件YSmenu.ini,当发现“AUTO_BOOT”(自动启动)字段存在(非空)时便引导了所运行的NDS程序。而用户则会感觉到是MS直接运行了该程序,不会感觉到其中复杂的调用过程。

NDS程序引导插件的配置文件config.ini具体配置如下:


这个文件内容比较简单易懂,我来对“autoboot”字段进行解释。该字段有两个可以设置的值0和1,为0时将不对YSmenu的“AUTO_BOOT”(自动启动)字段进行修改也就关闭了自动启动,为1时将可以正常运行NDS程序。

l 系统主题皮肤更换程序
众所周知,一个操作系统的用户界面十分重要。良好的用户界面不但可以可用户一个好印象,还可以体现程序设计人员的人性化的设计理念。每一种系统的用户体验界面往往是通过一系列图片和插件的皮肤包组成的。当然MS,YSmenu以及TTmenu也不例外,他们分别拥有自己的皮肤包。MS的皮肤是用压缩的方式封包的,可以在MS下直接运行安装。而TTMenu和YSMenu则需要通过连接电脑通过Windows来管理。操作十分繁琐,而且耽误时间。于是我们开发了一款专门为本内核设计的皮肤更换程序:SkinSelecter(TT/YS)。该程序可以在NDS下直接更换TT和YS的皮肤,免去了使用windows操作的麻烦。
该程序操作起来十分方便,首先将完整的DSTT皮肤存放在/TTMenu/skin/下。然后在NDS中运行该程序,会有一个皮肤选择界面,上下的案件可以选择一个你喜欢的皮肤,最后按下A键即可更换皮肤。


l 相关插件制作和设置
之前有多次提到MS通过“extlink.Dat”这个文件为用户提供了类似于Windows下“打开方式”的功能。那么它是如何提供的呢?其实MS的为我们提供了一个名叫“extlink_filestruct.h”的程序头文件作为应用程序的接口。作为一个程序人员,只需要把你曾经为NDS编写的各类扩展程序稍加修改就可以作为MS的插件使用了。其原理是修改原先程序的文件载入部分,将其替换为“extlink_filestruct.h”中所提供的输入、输出函数然后重新编译即可。
我们对现有的拥有源代码的部分程序进行了修改和重新编译生成了一部分可供MS使用的插件。如:FC与NEO的模拟器程序、IPK格式图片浏览程序、还有重要的NDS程序引导插件,都是按照这种方法获得的。


网络上还有一些由各国程序员自行制作的,针对MS开发的一些插件。但是我们不能直接拿来使用,因为我们内核中的MS是修改过的,读取路进与原版不同,直接使用会提示程序出错(运行时会提示找不到extlink.Dat文件,其原因是它的文件位置被修改了)。所以我们修要对这些插件进行修改。

下面以ExpLoader.NDS为例,介绍一下相关插件的修改。ExpLoader.nds是一款Slot2(接口2)的引导程序,用于运行GBA程序。已知该程序用到的文件存放在下“/moonshl2/extlink.Dat”,这里我们把它修改到“/TTMenu/M/”下。使之对应目录“/TTMenu/M/extlink.Dat” 。
具体步骤如下:

用CT2(16位编辑器)打开自制软件的NDS文件,并切换到16进制模式。搜索字符串“moon”或者“MOON”逐个排除,确定到此(右图)。这里是该程序的配置文件的地址,将其修改为“/TTMenu/M/extlink/GBA_ExpLoader_MSHL2.ini”。到此,并没有找到之前提到的地址“/moonshl2/extlink.Dat”,所以还需要继续查找修改。


再次搜索找到了我所需要的地址(右图)。修改为“/TTMenu/M/extlink.Dat”。现在对NDS程序的修改完成了,不过还没有全部完成,当程序放入NDS中运行中一般还是会报错的,因为程序自身有一定的自我校验来确定程序的完整性和正确性。



这里还需要对校验码进行修改,此处的校验码不同于MS的GUID校验,这里是十分常见的CRC32校验。CT2(16位编辑器)的本身就已经提供了修改CRC32校验码的功能,免去了我们寻找工具的麻烦。在“工具”菜单下找到右图所示的功能模块。点击之后,验证校验码会提示错误,选“是”自动修改就可以了。
要注意的是:第一,不要随更改地址长度,尽量用短的文件名。因为文件长度的改变会导致原本数据文件的位置可能变成了程序指令,而且文件校验位也随之修改了,会导致程序没办法正常运行。第二,还有就是注意区分大小写。


由于修改和制作的部分有很多,不方便一一详尽列出。这里按照“文件夹”的顺序将修改的部分进行分类归纳:

l /TTMENU 文件夹下的修改:
1.infolib.dat (独立制作)
2.savlib.dat (独立制作)
3.ttdldi.dat (独立制作)
4.usrcheat.dat (独立制作)
5.YSMenu1.bmp,YSMenu2.bmp (制作了YS背景皮肤)
6.BackToMs.nds (用于多系统切换)
7.YSMENU.INI (做了修改,简化加美化)
8. boot.dat (按键启动设置)
9. load.dat (就是YSmenu.NDS本身)
10.YSMenu.nds (用于多系统切换,用引导插件修改所得)
11.DSTT_Update.exe (更新助手程序)

l /TTMENU/M 文件夹下(用于存放MS)的修改:
1.删除了RELOAD.DAT (不需要此文件)
2.hidepath.ini (用来隐藏不可见的文件夹和文件)

l /TTmenu/M/extlink 文件夹下(扩展插件)的修改:
1.gba.ExpLoader.nds (修改了读取路径路径以及校验码)
2.ipk.nds (重新制作并编译并且汉化 PS:原先是日文)
3.nds.YSloaderForMS2.nds (独立制作)
4.NEO.NeoDs.nds (重新制作并编译并且汉化)
5.nes.nesDS.NDS (重新制作并编译)
6.sfc.SNEmulDS.nds (修改了文件路径以及校验码)
7.smc.SNEmulDS.nds (为解决扩展名问题 PS:既有SFC又有SMC)
8.GBA_ExpLoader_MSHL2.ini (修改了文件路径)
9.snemul.cfg (修改了文件路径)
10.config.ini (修改了文件路径)

l /TTmenu/M/launch 文件夹下的修改
1.SystemSetUp.nds (进入NDS的设置界面的软件)
2.YSMENU.nds (用于多系统切换,用引导插件修改所得)
3.TTMenu.nds (用于多系统切换)

l /TTmenu/M/resetmse 文件夹下的修改
1.TTIO.nds (在MS下可以实现软件关机)

l /TTmenu/M/language 文件夹下的修改
1.messages.936 (汉化了界面,修改了选项)



刚才在修改的过程中我们发现还有一个设置文件,现在将它打开(右图)。他的内容十分简单就是两条相关文件的路径。做出和上面方法相同的修改即可。
最后,将修改好的程序和它的配置文件一起放在/TTMenu/M/extlink/下就完成了路径的修改。对于其他的插件只要做出几乎相同的修改就可以了,限于篇幅就不一一展开了。而其他非原创程序就不在此详细介绍了,在下一个章节程序的连接与调试会有涉及的。

6.将程序进行连接与调试

由于程序整体很大很繁杂,相关功能又多,对所有程序的连接是一个艰巨的挑战。不但需要有良好的耐心,还需要有细致缜密的思维。在此,引用之前的程序流程图以供参考。

1. 将MS中的“moonshl2”文件夹下所有文件、文件夹放置到“/TTMenu/M”下。把主文件“moonshl2_DirectBoot.nds”更名为“moonshell.nds”放到/TTMenu文件夹中。
2. 把所有制作好的插件程序放到“/TTMenu/M/extlink”下,并且按照“***.NDS”的方式命名即可。(例如:将用于NDS的MP3的播放程序,命名为“MP3.NDS”并放置于只个文件夹下)。还有一些用于用户界面切换的程序(上一节最后有提到)需要分别放到“/TTmenu/M/launch”、 “/TTmenu/M”中。再把软件关机程序放在“/TTmenu/M/resetmse” 文件夹下更名为TTIO.NDS。最后将汉化好了的系统语言文件放在“/TTmenu/M/language” 文件夹下。
3. “更新助手”程序和他的配置文件需要放在“/TTmenu”下;把YSMenu.nds更名为“load.dat”安置在同一个目录中。
4. 现在,所有的文件基本上都放对位置了。接下来就是编写NSIS(Nullsoft Scriptable Installation System)安装程序的脚本了。打开NISI,导入已经编写好了的脚本文件(下一节有提供源代码),设置好安装文件的图标就可以编译了。不一会,就生成了安装程序。

到此,程序的连接部分就完成了。之后就是功能的测试了。在测试的过程中需要对安装程序、TT内核、YS引导程序、MS所有功能、相关插件、界面是否正确显示等全部进行详细的测试。该部分为实际操作,就无法在文章以文字的形式中展开叙述了。
下一小节将对文章中所提的程序,进行源代码的公开。

7.部分关键源代码公开
由于代码量很大,故没有办法为代码做出详细注释。以下为程序部分代码,由于代码量很大未对诸如“头文件”的部分进行展开叙述。请君谅解。

1.按键引导程序部分代码:(所使用编译器为devkitPro V1.5.0)

#include <nds.h>//此头文件为编译环境自带文件,为很多参数做好了定义。#include <fat.h>//同为自带文件,以下皆是。#include <sys/stat.h>#include <stdio.h>#include <string.h>#include "../../ipcex.h"#include "nds_loader_arm9.h"#include "minIni.h"#define POWER_CR (*(vuint16*)0x04000304) //由于是对CPU直接操作,以上部分为对接口的初始化定义const char configini[] = "/__ak2/boot.dat";extern "C" bool ret_menu9_Gen(char *); extern "C" void ret_menu9_GENs(void); //--------------------------------------------------------void SoftReset(char* bootname){ERESET RESET=RESET_NULL;if (ret_menu9_Gen(bootname) == true) {iprintf("\x1b[10;8Hbooting %s\n",bootname);} else {iprintf("\x1b[10;6Hnot found %s\n",bootname);while(1);}RESET=RESET_MENU_GEN;IPCEX->RESET=RESET;ret_menu9_GENs();while (1) {swiWaitForVBlank();}}void stop (void) {while (1) {swiWaitForVBlank();}}int main(void) {REG_IME=0;POWER_CR = POWER_ALL_2D;// POWER_CR &= ~POWER_SWAP_LCDS;POWER_CR |= POWER_SWAP_LCDS;irqInit();videoSetMode(0);videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);vramSetBankH(VRAM_H_SUB_BG);SUB_BG0_CR = BG_MAP_BASE(15);BG_PALETTE_SUB[0]=0; BG_PALETTE_SUB[255]=0xffff;consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(15), (u16*)CHAR_BASE_BLOCK_SUB(0), 16);if(fatInitDefault() == false) {iprintf ("fatInitDefault Fail");}char inifile[100];int test=0;//int first=0;char bootname[100],bootname1[100],bootname2[100];//first = ini_getl("system", "firstboot", 0, configini);scanKeys();if((keysDown() & KEY_A)){test = ini_getl("KEYA", "bootmethod", 1, configini);ini_gets("KEYA","path","DSFTP.NDS",bootname,100, configini);if (test==0){SoftReset (bootname);}else if (test==1){runNdsFile(bootname);}iprintf ("inifile error!");stop ();}else if((keysDown() & KEY_R)){test = ini_getl("KEYR", "bootmethod", 1, configini);ini_gets("KEYR","path","MOONSHL2.NDS",bootname,100, configini);if (test==0){SoftReset (bootname);}else if (test==1){runNdsFile(bootname);}iprintf ("inifile error!");stop ();}else if((keysDown() & KEY_SELECT)){ini_gets("default","path","/__ak2/akaio.nds",bootname1,100, configini);ini_gets("KEYR","path","/__ak2/ak2.nds",bootname2,100, configini);ini_puts("KEYR","path", bootname1, configini);ini_puts("default","path", bootname2, configini);iprintf("defule boot set:%s\n",bootname2);SoftReset (bootname2);stop ();}//runNdsFile ("test.nds");test = ini_getl("default", "bootmethod", 1, configini);ini_gets("default","path","AKAIO.NDS",bootname,100, configini);if (test==0){SoftReset (bootname);}else if (test==1){runNdsFile(bootname);}iprintf ("inifile error!");stop ();}

2.NDS程序引导插件(所使用编译器为devkitPro V1.5.0)

#include <nds.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <fat.h>#define FAT_FT_END (0)#define FAT_FT_FILE (1)#define FAT_FT_DIR (2)bool ret_menu9_Gen(char *menu_nam){u32 hed[16];u8 *ldrBuf;FILE *ldr;u32 siz;//if(fatInitDefault() == false) {//return false;//}ldr = fopen(menu_nam, "rb");if(ldr == NULL) return false;fread((u8*)hed, 16*4, 1, ldr);siz = 512 + hed[11] + hed[15];ldrBuf = (u8*)malloc(siz);if(ldrBuf == NULL) {fclose(ldr);return false;}fseek(ldr, 0, SEEK_SET);fread(ldrBuf, 512, 1, ldr);fseek(ldr, hed[8], SEEK_SET);fread(ldrBuf + 512, hed[11], 1, ldr);fseek(ldr, hed[12], SEEK_SET);fread(ldrBuf + 512 + hed[11], hed[15], 1, ldr);fclose(ldr);(*(vu32*)0x027FFDF4) = (u32)ldrBuf;return true;}

3.安装程序脚本 (此程序使用NSIS编译。程序比较长,故有所省略。)


未转完全,全部请看开始提及的原帖地址。



原创粉丝点击