用VS2008如何调试模拟器中的WINCE6.0的DLL或者LIB链接库?

用VS2008如何调试模拟器中的WINCE6.0的DLL或者LIB链接库?,第1张

:

方式一:

点击”开始”菜单, 指向 “Microsoft Platform SDK” >“Open Build Environment Windows” >“Set Windows XP 64 Build Environment”, 然后点击”Set Windows XP 64 Build Environment (Debug)”, 这时, 一个控制台窗口将显示, 一行文本显示像” the build environment set for a 64-bit”.

方式二:

在命令提示符下,

1. 点击”开始”菜单, 然后点击”运行”

2. 键入”command.exe”(没有引号), 然后, 点击”确定”

3. 变化当前目录到C:\Program Files\Microsoft SDK(你的SDK安装目录), 然后键入”SetEnv.bat /XP64”(没有引号)

现在, 开始启动Visual C++ 6.0并用我们刚才配置好的创建环境

1. 在同一个命令窗口中(也就是你刚才设置64位环境的命令行窗口), 打开Visual Studio.

2. 键入 “Msdev /useenv”(没有引号). 请注意, 不要打开一个新的命令行窗口, 再去打开Msdev.exe, 现在Visual C++ 6.0 IDE已经显示, 并且include, library及executable目录均被设置为64位的创建环境(注:查看这些配置, 点击Tools >Options >Directories, 在”Show directories for: “下拉列表中查看相应目录配置).

另外, 如果Msdev.exe不在当前路径下(通常是系统环境变量没有相应指示), 变化目录到你所安装Visual Studio的目录下, 例如: \Microsoft Visual Studio\Common\Msdev98\Bin, 然后, 再键入Msdev.exe.

译注: 在前面的设置64位创建环境变量 , 已经将IDE的executable执行目录调整到SDK的相应目录下面, 也就是说, 作为可执行程序: 编译器和链接器是在SDK目录中, 而不再是默认的\Microsoft Visual Studio\Common\Msdev98\Bin

添加一个64位Debug配置

1. 在Visual C++ IDE中, 打开一个已经在的32位工程(例如: MyApplication)

2. 在”Build”菜单上, 点击”Configurations”.

3. 在”Configurations”对话框上, 点击”Add”.

4. 在”Add Project Configuration”对话框上, 设置”Configuration”到Debug64, 然后, 在”Copy Settings from”列表框中点击”MyApplication – Win32 Debug”

5. 点击”OK”完成设置, 点击”Close”关闭.

设置激活配置为64位

1. 在”Build”菜单上, 点击”Set Active Configuration”.

2. 点击”MyApplication – Win32 Debug64”, 然后, 点击”OK”.

修改编译器和链接器的参数配置

由于64位的编译器和链接器的参数配置和32位的有些不一样, 我们需要修改部分选项, 下面是这些配置步骤:

1. 在”Project”菜单中,点击”Settings”.

2. 在”Project Settings”对话框中, 点击”General”标签. 在”Output directories”, 在”Intermediate files” 和”Output files”输入框中, 键入”Debug64”(没有引号)

3. 在”C/C++”标签上, 在”Debug info”下拉列表中, 选择”Program database(参数选项对应是 /Zi)

4. 在”Link”标签上, 在”Project options”的输入框中, 变化”/machine:I386”(没有引号)到”/machine:IA64”(没有引号)

译注: 正确设置应是: /machine:AMD64

5. 在”View”菜单上, 点击”Workspace”.

6. 然后, 移除帮助文件MyApplication.hpj

7. 如果你的应用程序是基于MFC的, 你必须添加一个MFC路径以避免链接错误:LNK1004 on the Mfc42d.lib, 请按下面步骤 *** 作:

a. 在”Tools”菜单上, 点击”Options”.

b. 在”Directories”标签上, 在”Show directories”下拉列表中, 选择”Library Files”, 现在添加你的平台库所在路径: ”\Microsoft SDK\lib\IA64\mfc”(没有引号)

译注补充: 在”C/C++”标签上, 在”Preprocessor definitions”输入框中将WIN32改成WIN64

创建并调试这个工程

现在Build这个工程, 生成64位应用程序, 这个应用程序被部署在一个IA64计算机上.

要在Visual C++ 6.0中运行这个.exe文件, 按下面步骤:

注意: 你不能够在Visual C++ 6.0 IDE中调试这个.exe文件.

a. 在你的IA64计算机上, 创建一个文件夹: C:\VC6MSVCMON

从X86(32位)计算机上拷贝这些文件到这个新创建的文件夹中:

Msvcmon.exe

Dm.dll

Msdis110.dll

Tln0t.dll

上面这些文件应在你的Visual C++ 6.0安装目录下:

\Visual Studio\Common\MSDev98\Bin

b. 在拷贝完这些文件后, 在IA64计算机上运行Msvcmon.exe, 然后, 点击”Connect”.

c. 在X86(32位)计算机上, 打开Visual C++ 6.0 IDE, 在”Build”菜单上, 点击”Debugger Remote Connection”.

d. 在”Remote Connection”对话框中, 点击”Network TCP/IP”, 然后, 点击”Settings”.

e. 在”Target computer name of address”输入框中, 键入IA64计算机的名称. 点击”ok”两次, 关闭对话框.

f. 在Visual Studio C++ IDE中, 在”Project”菜单上, 点击”Settings”, 在左侧面板, 展开”MyApplication”, 然后, 点击”Debug”标签. 你将注意到”Executable for debug session”输入框包含了MyApplication.exe的路径, 看起来是C:\<X86Path>\MyApplication.exe.

g. 在”Remote executable path and file name”输入框中, 键入”MyApplication.exe”(没有双引号)所在的全路径, 这个路径看起来像: \\<X86ComputerName>\C$\<x86Path>\MyApplication.exe(没有引号).点击”OK”关闭该窗口.

h. 按下CTRL+F5或在”Build”菜单上点击”Execute MyApplication.exe”, 开始运行这个.exe文件, 这个.exe文件现在是运行在IA64计算机上.

注意:如果MyApplication是一个MFC应用程序并且这个工程用到了MFC相关的.dll文件, 请确信在IA64计算机上, 那些.dll文件从\Microsoft SDK\NoRedist\Win64文件夹中已被拷贝到\System32文件夹中.

译注:\Microsoft SDK\NoRedist\Win64存放的是debug和release版本的MFC, ATL相关dll(64位), 实际上你也可以拷贝这些dll文件到你的可执行.exe文件所在同一目录中.

这些dll文件是:

Mfc42d.dll

Mfco42d.dll

Msvcrtd.dll

译注补充: 编译/链接中经常遇到的问题:

链接出错, 通常是RTC, cookie错误, 参见下面链接设置:

链接中如出现 Error Spawing bscmake.exe

去掉勾选编译参数(Project settings >c/c++): Generate Browse Info

如果仍不成功, 请仔细检查在菜单项”Tools” >“Options” , 定位在”Directories”标签, 选择”Executable Files”, 在下面的目录列表中, 将<SDK安装目录>\bin路径放在第一项.(这个目录中的64位编译器和链接器程序将重载旧的32位设置).

如果你是动态库和主应用程序链接, 必须保持用的是相同运行时库, 例如: 全部都是Multi-Threads DLL(点击”Project” >“Settings”, 选择”C/C++”标签, 在”Category”下拉列表中选择”Code Generation”, 在下面”Use runtime library”下拉列表中选择).

用Visual C++ .NET IDE创建一个64位应用程序

警告: 在已安装Visual Studio .NET的计算机上, 请不要同时安装64位版本的WinDbg调试器工具, 请读平台SDK的Readme.doc(位置在: C:\Program Files\Microsoft SDK\Bin\Win64\Readme.doc).

设置64位创建环境变量, 用下面任何一种方式都行:

参照前文相同部分.

开始启动Visual C++ .NET, 并用刚才我们创建好的64位环境

1. 在64位SDK环境设置的命令行窗口中,打开Visual Studio .NET.

2. 键入”devenv /useenv”(没有引号), 然后, 点击”OK”. 现在include, library, executable目录被设置成为64位SDK所在目录.

注意: 如果Devent.exe不在当前路径(通常是在系统环境变量Path中未指定Visual Studio .NET安装目录), 请改变文件夹路径到<Visual Studio .NET安装目录>\Microsoft Visual Studio .NET\Common7\IDE, 然后再运行上述命令.

警告:在你运行这个命令后, Visual Studio .NET IDE就被设置成为64位的开发环境, 如果你想清除这个环境, 在打开一个新的Visual Studio .NET IDE之前, 删除在C:\Documents and Settings\<Username>\Local Settings\Application Data\Microsoft\VisualStudio\7.0 下的Vccomponents.dat文件.

添加一个64位调试配置

1. 打开一个已存在的32位工程(例如, MyApplication).

2. 在”Build”菜单上, 点击”Configuration Manager”.

3. 在”Active Solution Configurations”列表中, 点击”New”.

4. 在”New Solution Configurations”对话框中, 在”Solution Configuration Name”下面选择”Debug64”(不包含引号), 并且在”Copy Settings From”下面选择”Debug”.

5. 点击”OK”.

6. 在”Configuration Manager”对话框中, 在”Active Solution Configuration”列表中, 点击选择”Debug64”, 然后点击”OK”.

修改编译器和链接器设置

由于64位的编译器和链接器的参数配置和32位的有些不一样, 我们需要修改部分选项, 下面是这些配置步骤:

1. 在”Solution”(中文:解决方案)浏览窗口中, 右键”Project”, 然后, 点击”Properties”.

2. 在”C/C++”节点, 选择”General”. 设置”Debug Information Format”到”Program Database”(对应的编译选项是/Zi).

3. 在”C/C++”节点中, 选择”Code generation”. 设置”Buffer Security Check”到”No”(对应的编译选项是/GS).

4. 在”Linker”节点, 选择”Command Line”.在”Additional Options”下面, 添加”/MACHINE:IA64”(没有引号).

5. 如果你的应用程序是基于MFC的,你必须添加MFC路径以避免收到链接错误:LNK1104 on the Mfc42d.lib file.

添加MFC路径, 按下面步骤:

a. 在”Tools”菜单上, 点击”Options”.

b. 在”Projects”下面, 选择”VC++ Directories”. 在”Show directories”列表中, 选择”Library Files”.如果库路径没有列出, 添加这个库路径"\Microsoft SDK\lib\IA64\mfc"(没有引号).

注意:如果MyApplication是一个MFC应用程序并且这个工程用到了MFC相关的.dll文件, 请确信在IA64计算机上, 那些.dll文件从\Microsoft SDK\NoRedist\Win64文件夹中已被拷贝到\System32文件夹中.

这些dll文件是:

Mfc42d.dll

Mfco42d.dll

Msvcrtd.dll

完成这些后, 就可以build 64位可执行程序了.

调试工程参照Visual C++ 6.0 IDE部分.

更多参考在:

64-Bit Programming with Visual C++

64位程序移植问题设置64位创建环境变量, 用下面任何一种方式都行:

方式一:

点击”开始”菜单, 指向 “Microsoft Platform SDK” >“Open Build Environment Windows” >“Set Windows XP 64 Build Environment”, 然后点击”Set Windows XP 64 Build Environment (Debug)”, 这时, 一个控制台窗口将显示, 一行文本显示像” the build environment set for a 64-bit”.

方式二:

在命令提示符下,

1. 点击”开始”菜单, 然后点击”运行”

2. 键入”command.exe”(没有引号), 然后, 点击”确定”

3. 变化当前目录到C:\Program Files\Microsoft SDK(你的SDK安装目录), 然后键入”SetEnv.bat /XP64”(没有引号)

现在, 开始启动Visual C++ 6.0并用我们刚才配置好的创建环境

1. 在同一个命令窗口中(也就是你刚才设置64位环境的命令行窗口), 打开Visual Studio.

2. 键入 “Msdev /useenv”(没有引号). 请注意, 不要打开一个新的命令行窗口, 再去打开Msdev.exe, 现在Visual C++ 6.0 IDE已经显示, 并且include, library及executable目录均被设置为64位的创建环境(注:查看这些配置, 点击Tools >Options >Directories, 在”Show directories for: “下拉列表中查看相应目录配置).

另外, 如果Msdev.exe不在当前路径下(通常是系统环境变量没有相应指示), 变化目录到你所安装Visual Studio的目录下, 例如: \Microsoft Visual Studio\Common\Msdev98\Bin, 然后, 再键入Msdev.exe.

译注: 在前面的设置64位创建环境变量 , 已经将IDE的executable执行目录调整到SDK的相应目录下面, 也就是说, 作为可执行程序: 编译器和链接器是在SDK目录中, 而不再是默认的\Microsoft Visual Studio\Common\Msdev98\Bin

添加一个64位Debug配置

1. 在Visual C++ IDE中, 打开一个已经在的32位工程(例如: MyApplication)

2. 在”Build”菜单上, 点击”Configurations”.

3. 在”Configurations”对话框上, 点击”Add”.

4. 在”Add Project Configuration”对话框上, 设置”Configuration”到Debug64, 然后, 在”Copy Settings from”列表框中点击”MyApplication – Win32 Debug”

5. 点击”OK”完成设置, 点击”Close”关闭.

设置激活配置为64位

1. 在”Build”菜单上, 点击”Set Active Configuration”.

2. 点击”MyApplication – Win32 Debug64”, 然后, 点击”OK”.

修改编译器和链接器的参数配置

由于64位的编译器和链接器的参数配置和32位的有些不一样, 我们需要修改部分选项, 下面是这些配置步骤:

1. 在”Project”菜单中,点击”Settings”.

2. 在”Project Settings”对话框中, 点击”General”标签. 在”Output directories”, 在”Intermediate files” 和”Output files”输入框中, 键入”Debug64”(没有引号)

3. 在”C/C++”标签上, 在”Debug info”下拉列表中, 选择”Program database(参数选项对应是 /Zi)

4. 在”Link”标签上, 在”Project options”的输入框中, 变化”/machine:I386”(没有引号)到”/machine:IA64”(没有引号)

译注: 正确设置应是: /machine:AMD64

5. 在”View”菜单上, 点击”Workspace”.

6. 然后, 移除帮助文件MyApplication.hpj

7. 如果你的应用程序是基于MFC的, 你必须添加一个MFC路径以避免链接错误:LNK1004 on the Mfc42d.lib, 请按下面步骤 *** 作:

a. 在”Tools”菜单上, 点击”Options”.

b. 在”Directories”标签上, 在”Show directories”下拉列表中, 选择”Library Files”, 现在添加你的平台库所在路径: ”\Microsoft SDK\lib\IA64\mfc”(没有引号)

译注补充: 在”C/C++”标签上, 在”Preprocessor definitions”输入框中将WIN32改成WIN64

创建并调试这个工程

现在Build这个工程, 生成64位应用程序, 这个应用程序被部署在一个IA64计算机上.

要在Visual C++ 6.0中运行这个.exe文件, 按下面步骤:

注意: 你不能够在Visual C++ 6.0 IDE中调试这个.exe文件.

a. 在你的IA64计算机上, 创建一个文件夹: C:\VC6MSVCMON

从X86(32位)计算机上拷贝这些文件到这个新创建的文件夹中:

Msvcmon.exe

Dm.dll

Msdis110.dll

Tln0t.dll

上面这些文件应在你的Visual C++ 6.0安装目录下:

\Visual Studio\Common\MSDev98\Bin

b. 在拷贝完这些文件后, 在IA64计算机上运行Msvcmon.exe, 然后, 点击”Connect”.

c. 在X86(32位)计算机上, 打开Visual C++ 6.0 IDE, 在”Build”菜单上, 点击”Debugger Remote Connection”.

d. 在”Remote Connection”对话框中, 点击”Network TCP/IP”, 然后, 点击”Settings”.

e. 在”Target computer name of address”输入框中, 键入IA64计算机的名称. 点击”ok”两次, 关闭对话框.

f. 在Visual Studio C++ IDE中, 在”Project”菜单上, 点击”Settings”, 在左侧面板, 展开”MyApplication”, 然后, 点击”Debug”标签. 你将注意到”Executable for debug session”输入框包含了MyApplication.exe的路径, 看起来是C:\<X86Path>\MyApplication.exe.

g. 在”Remote executable path and file name”输入框中, 键入”MyApplication.exe”(没有双引号)所在的全路径, 这个路径看起来像: \\<X86ComputerName>\C$\<x86Path>\MyApplication.exe(没有引号).点击”OK”关闭该窗口.

h. 按下CTRL+F5或在”Build”菜单上点击”Execute MyApplication.exe”, 开始运行这个.exe文件, 这个.exe文件现在是运行在IA64计算机上.

注意:如果MyApplication是一个MFC应用程序并且这个工程用到了MFC相关的.dll文件, 请确信在IA64计算机上, 那些.dll文件从\Microsoft SDK\NoRedist\Win64文件夹中已被拷贝到\System32文件夹中.

译注:\Microsoft SDK\NoRedist\Win64存放的是debug和release版本的MFC, ATL相关dll(64位), 实际上你也可以拷贝这些dll文件到你的可执行.exe文件所在同一目录中.

这些dll文件是:

Mfc42d.dll

Mfco42d.dll

Msvcrtd.dll

译注补充: 编译/链接中经常遇到的问题:

链接出错, 通常是RTC, cookie错误, 参见下面链接设置:

链接中如出现 Error Spawing bscmake.exe

去掉勾选编译参数(Project settings >c/c++): Generate Browse Info

如果仍不成功, 请仔细检查在菜单项”Tools” >“Options” , 定位在”Directories”标签, 选择”Executable Files”, 在下面的目录列表中, 将<SDK安装目录>\bin路径放在第一项.(这个目录中的64位编译器和链接器程序将重载旧的32位设置).

如果你是动态库和主应用程序链接, 必须保持用的是相同运行时库, 例如: 全部都是Multi-Threads DLL(点击”Project” >“Settings”, 选择”C/C++”标签, 在”Category”下拉列表中选择”Code Generation”, 在下面”Use runtime library”下拉列表中选择).

用Visual C++ .NET IDE创建一个64位应用程序

警告: 在已安装Visual Studio .NET的计算机上, 请不要同时安装64位版本的WinDbg调试器工具, 请读平台SDK的Readme.doc(位置在: C:\Program Files\Microsoft SDK\Bin\Win64\Readme.doc).

设置64位创建环境变量, 用下面任何一种方式都行:

参照前文相同部分.

开始启动Visual C++ .NET, 并用刚才我们创建好的64位环境

1. 在64位SDK环境设置的命令行窗口中,打开Visual Studio .NET.

2. 键入”devenv /useenv”(没有引号), 然后, 点击”OK”. 现在include, library, executable目录被设置成为64位SDK所在目录.

注意: 如果Devent.exe不在当前路径(通常是在系统环境变量Path中未指定Visual Studio .NET安装目录), 请改变文件夹路径到<Visual Studio .NET安装目录>\Microsoft Visual Studio .NET\Common7\IDE, 然后再运行上述命令.

警告:在你运行这个命令后, Visual Studio .NET IDE就被设置成为64位的开发环境, 如果你想清除这个环境, 在打开一个新的Visual Studio .NET IDE之前, 删除在C:\Documents and Settings\<Username>\Local Settings\Application Data\Microsoft\VisualStudio\7.0 下的Vccomponents.dat文件.

添加一个64位调试配置

1. 打开一个已存在的32位工程(例如, MyApplication).

2. 在”Build”菜单上, 点击”Configuration Manager”.

3. 在”Active Solution Configurations”列表中, 点击”New”.

4. 在”New Solution Configurations”对话框中, 在”Solution Configuration Name”下面选择”Debug64”(不包含引号), 并且在”Copy Settings From”下面选择”Debug”.

5. 点击”OK”.

6. 在”Configuration Manager”对话框中, 在”Active Solution Configuration”列表中, 点击选择”Debug64”, 然后点击”OK”.

修改编译器和链接器设置

由于64位的编译器和链接器的参数配置和32位的有些不一样, 我们需要修改部分选项, 下面是这些配置步骤:

1. 在”Solution”(中文:解决方案)浏览窗口中, 右键”Project”, 然后, 点击”Properties”.

2. 在”C/C++”节点, 选择”General”. 设置”Debug Information Format”到”Program Database”(对应的编译选项是/Zi).

3. 在”C/C++”节点中, 选择”Code generation”. 设置”Buffer Security Check”到”No”(对应的编译选项是/GS).

4. 在”Linker”节点, 选择”Command Line”.在”Additional Options”下面, 添加”/MACHINE:IA64”(没有引号).

5. 如果你的应用程序是基于MFC的,你必须添加MFC路径以避免收到链接错误:LNK1104 on the Mfc42d.lib file.

添加MFC路径, 按下面步骤:

a. 在”Tools”菜单上, 点击”Options”.

b. 在”Projects”下面, 选择”VC++ Directories”. 在”Show directories”列表中, 选择”Library Files”.如果库路径没有列出, 添加这个库路径"\Microsoft SDK\lib\IA64\mfc"(没有引号).

注意:如果MyApplication是一个MFC应用程序并且这个工程用到了MFC相关的.dll文件, 请确信在IA64计算机上, 那些.dll文件从\Microsoft SDK\NoRedist\Win64文件夹中已被拷贝到\System32文件夹中.

这些dll文件是:

Mfc42d.dll

Mfco42d.dll

Msvcrtd.dll

完成这些后, 就可以build 64位可执行程序了.

调试工程参照Visual C++ 6.0 IDE部分.

更多参考在:

64-Bit Programming with Visual C++

64位程序移植问题

Windows CE6.0启动过程分析

在Windows CE 6.0中,内核(Kenerl)和OEM代码被分成oal.exe、kernel.dll和kitl.dll三个部分,其中启动代码(startup)和 OAL层的实现部分不再与内核链接生成NK.exe,取而代之的是启动代码(startup)和硬件相关且独立于内核的OAL层的实现部分编译成 oal.exe,而与内核相关且独立于硬件的OAL层代码包含在kernel.dll中;内核无关传输层(KITL)的支持代码从OAL层分离出来编译成 kitl.dll。

从表面上看,好像只是代码重新组合了一下,从帮助 文档中BSP的移植过程看好像也是这么一回事,实际上,整个Windows CE 6.0内核布局发生了很大的改变。Windows CE 6.0的启动过程也是如此,如果你想按照Windows CE 5.0的启动顺序去分析Windows CE 6.0的启动顺序,可能会走到一个死胡同。主要是因为Windows CE 6.0在启动过程中调用了kernel.dll和kitl.dll两个动态链接库的原因,而且Windows CE6.0不再编译生成KernKitlProf.exe内核文件。

从Windows CE 6.0的帮助文档可以看出,WinCE6.0的启动只与oal.exe和kernel.dll有关,至于kitl.dll,只有将 *** 作系统编译成具有 KITL功能时才用到。分析Windows CE 6.0的启动过程实际上找到编译oal.exe和kernel.dll的源码位置。

首先看一下将WinCE6.0编译成诸如 WinCE5.0所说的基本内核情况,即kern.exe。对于oal.exe源码位置比较容易找到,因为oal.exe是启动代码与硬件相关的OAL层 实现文件编译而成,所以只需在BSP的OAL目录中便能找到。而对于kernel.dll,在BSP目录结构中,基本上无法找到kernel.dll的编 译文件,所以必须从其他方面着手。

下面为WinCE 6.0的编译日志输出文件:makeimg.out在文件复制过程的一部分:

Copying E:\WINCE600\OSDesigns\xsbase270\xsbase270\RelDir\XSBase270_ARMV4I_Release\oal.exe to E:\WINCE600\OSDesigns\xsbase270\xsbase270\RelDir\XSBase270_ARMV4I_Release\nk.exe for debugger Copying E:\WINCE600\OSDesigns\xsbase270\xsbase270\RelDir\XSBase270_ARMV4I_Release\kern.dll to E:\WINCE600\OSDesigns\xsbase270\xsbase270\RelDir\XSBase270_ARMV4I_Release\kernel.dll for debugger

从日志输出文件可以看出,在文件复制过程 中,WinCE6.0编译器将oal.exe更名为nk.exe,而将kern.dll文件更名为kernel.dll,也就是说,kern.dll文件 的实现部分就是kernel.dll的实现体。根据前面的分析,oal.exe是与硬件相关独立于内核的OAL层的实现部分,而kernel.dll为内 核相关独立于硬件的OAL层的实现部分。同样可以从最后整合后的二进制配置文件ce.bib文件中看出端倪。

@CESYSGEN IF CE_MODULES_NK

nk.exe E:\WINCE600\OSDesigns\xsbase270\xsbase270\RelDir\XSBase270_ARMV4I_Release\oal.exe NK SHZ

kitl.dll E:\WINCE600\OSDesigns\xsbase270\xsbase270\RelDir\XSBase270_ARMV4I_Release\kitl.dll NK SHZ

kernel.dll E:\WINCE600\OSDesigns\xsbase270\xsbase270\RelDir\XSBase270_ARMV4I_Release\kern.dll NK SHZ

@CESYSGEN ENDIF

而kern.dll动态库在整个Windows CE6.0中没有显式编译过程,即没有一个sources文件有kern.dll的编译过程,所以只能从 *** 作系统的编译文件Makefile中寻找其编译 过程。下面看一下$(_PUBLICROOT)\common\CESYSGEN\makefile中的部分内容:

nk::$(NK_COMPONENTS) $(NK_REPLACE_COMPONENTS)

@copy $(SG_INPUT_LIB)\oemstub.pdb $(SG_OUTPUT_OAKLIB)

@copy $(SG_INPUT_LIB)\oemstub.lib $(SG_OUTPUT_OAKLIB)

set TARGETTYPE=DYNLINK

set TARGETNAME=kern

set RELEASETYPE=OAK

set DLLENTRY=NKStartup

set DEFFILE=NO_DEF_FILE

set TARGETLIBS=

set SOURCELIBS=%%NKLIBS%% $(SG_INPUT_LIB)\nkmain.lib $(SG_INPUT_LIB)\fulllibc.lib

$(MAKECMD) /NOLOGO NOLIBC=1 kern.dll

从上述代码中可以发现,原来kern.dll动态库是从oemstub.lib编译而来,而且与nkmain.lib有关。

在理顺了上述文件的相互之间的关系之后,再来分析Windows CE 6.0的启动过程可能就比较容易啦。

在理清了上述文件的关系之后,便可以分析任意一款基于ARM微处理器的Windows CE 6.0的启动过程,现在以深圳亿道电子技术有限公司开发的基于PXA270 ARM开发平台为例,分析Windows CE 6.0 *** 作系统启动过程。

1、Startup函数

从Windows CE 6.0的帮助文档可以看出,WinCE6.0的启动只与oal.exe和kernel.dll有关,至于kitl.dll,只有将 *** 作系统编译成具有 KITL功能时才用到。分析Windows CE 6.0的启动过程实际上找到编译oal.exe和kernel.dll的源码位置。

oal.exe的通过Startup函数完成硬件 的初始化。Startup.s代码与该硬件平台的Bootloader启动代码共用,其中PreInit函数主要完成将ARM处理器工作模式切换到管理员 模式、同时关闭MMU,并检测系统启动原因,如果是热启动、即在该函数调用之前已经启动了Bootloader程序,相当基本硬件初始化已经完成,则直接 跳转到OALStartUp函数中;否则需要进行硬件中断屏蔽、内存、系统时钟频率、电源管理等硬件的基本初始化过程。(具体过程见代码的分析)

$(_PLATFORMROOT)\xsbase270\src\common\Startup\Startup.s

LEAF_ENTRY StartUp

bl PreInit

tst r10, #RCSR_HARD_RESET

beq OALStartUp

tst r10, #RCSR_GPIO_RESET

bne Continue_StartUp

bl xlli_mem_init 初始化内存控制器

ldr r0, =xlli_PMRCREGS_PHYSICAL_BASE

ldr r0, [r0, #xlli_PSPR_offset]

mov r1, r10

bl XllpPmValidateResumeFromSleep

cmp r0, #0

bne Failed_Sleep_Resume

Sleep_Reset

ldr r0, =xlli_PMRCREGS_PHYSICAL_BASE

ldr r0, [r0, #xlli_PSPR_offset]

mov r1, r10

b XllpPmGoToContextRestoration

Failed_Sleep_Resume

ldr r1, =xlli_RCSR_SMR

bic r10, r10, r1

Continue_StartUp

bl xlli_intr_init初始化中断控制器

bl EnableClks使能内核时钟(内存/OS定时器/FFART时钟之需)

bl OALXScaleSetFrequencies 设置系统频率

bl xlli_mem_Topt

bl xlli_mem_restart 复位内存,使其处于工作模式

bl xlli_ost_init 初始化 *** 作系统定时器

bl xlli_pwrmgr_init 初始化电源管理

bl xlli_IMpwr_init 初始化内部存储器

b

ENTRY_END

2、OALStartUp函数:

在系统硬件初始化完毕之后,Startup调用 OALStartUp函数,OALStartUp函数主要完成将OEMAddressTable表传递给内核;然后调用KernelStart函数跳转到 内核OEMAddressTable表的主要作用表的每一个入口都定义了一个内存中的物理位置、内存的大小以及映射这物理地址的静态虚拟地址;

◆静态虚拟内存地址被定义在缓冲存储器的范围之内;

◆内核可以创建非缓冲的内存地址指向到相同的物理地址;

◆对于同一物理地址,既有一个缓冲的虚拟内存地址,也有一个非缓冲的虚拟内存地址;

◆OEMAddressTable最后必须以0结尾;

◆对于MIPS和SHx类型的CPU,物理地址与虚拟地址的映射由CPU完成,无需创建OEMAddressTable

$(_PLATFORMROOT)\xsbase270\src\Inc\ Oemaddrtab_cfg.inc):

$(_PLATFORMROOT)\xsbase270\src\oal\OalLib\Startup.s

3、KernelStart函数主要作用:

◆完成OEMAddressTable表中的物理地址到虚拟地址和虚拟地址到物理地址之间的映射;

◆对存储器页表和内核参数区存储空间(RAM或DRAM)进行清零处理。

◆读出CPU的ID号,内核需要根据该ID决定ARM的MMU处理,因为ARMV6和ARMV6之前的ARM处理器的MMU处理过程有所区别;

◆设置并开启MMU和Cache,因为在Startup函数关闭MMU和Cache;

◆设置ARM处理器工作模式的SP指针,ARM处理器共用7种不同的工作模式 (USER、FIQ、IRQ、Supervisor、Abort、Undefined、System),除用户模式(USER)和系统模式 (System)之外,其他5种工作模式都有具有特定的SP指针寄存器(ARM处理器称其为影子寄存器);

◆读取内核启动所需要的KDataStruct结构体;

◆调用ARMInit函数重新定位Windows CE内核参数pTOC和初始化OEMInitGlobals全局变量;

◆利用mov pc, r12指令跳转到kernel.dll的入口位置,即NKStartup函数中。

$(_PRIVATEROOT)WINCEOS\COREOS\NK\LDR\ARM\armstart.s

4、ARMInit函数:

在ARMInit之前,系统仍无法使用全局变量, 因为系统的全局还在ROM区域,对于 *** 作系统而言,出于安全考虑,只有XIP程序才有读取ROM区域数据的权利,对于大部分Windows CE *** 作系统,只有将数据拷贝到RAM区域后才能进行读写,ARMInit函数中通过调用KernelRelocate函数对pTOC全局变量重新定位,定位 之后,对内核启动所需要的KDataStruct结构体进行初始化,其中OEMInitGlobals便是交换oal.exe和kernel.dll之间 的全局指针,ARMInit函数返回kernel.dll的入口位置。并在KernelStart函数最后利用mov pc, r12指令跳转到kernel.dll的入口位置,即NKStartup函数中。

$(_PRIVATEROOT)WINCEOS\COREOS\NK\LDR\ARM\arminit.c

5、NKStartup函数:

硬件平台初始化完成后,oal.exe的启动任务基本完成,余下的启动工作由内核相关且独立于内核的OAL层实现体kernel.dll接管。kernel.dll主要作用:

◆从结构体参数KDataStruct * pKData提取内核启动时所必须的全局变量,同时初始化内核全局变量;

◆定位对Windows CE 6.0特有的OEMGLOBAL结构体的初始化函数OEMInitGlobals地址,该结构体构建了内核和OAL层之间进行通信的桥梁。在 OEMGLOBAL结构体定义了OAL层所必须的函数,该结构体在oemglobal.c文件中被初始化,并被编译在OEMMain.lib和 OEMMain_StaticKITL.lib两个库中,如果OAL链接这两个库,则必须要有该结构体中函数实现体;

◆通过调用ARMSetup设置物理地址和非缓冲的虚拟内存地址的映射、ARM中断向量以及内核模式所需要的堆栈。

◆调用OEMInitDebugSerial函数初始化调试串口;

◆调用OEMInit进行平台初始化;

需要注意的时,NKStartup函数调用OEMInitDebugSerial和 OEMInit函数的过程与Windows CE 6.0之前的版本完全不同,这是因为在Windows CE 6.0以前的版本中,由于内核(kernel)、OAL和KITL编译在一个可执行的文件中,它们之间的共享变量只需简单利用extern关键字申明便可 相互之间进行访问,而在Windows CE 6.0中,由于内核(kernel)、OAL和KITL被编译成不同的可执行文件,变量之间的相互访问无法使用extern关键字实现共享,即内核无法使 用extern DWORD varX方法访问OAL层的变量varX,当然OAL层的实现体同样无法通过同样的方式访问内核变量。为实现内核和OAL访问共享信息,Windows CE 6.0定义了OEMGLOBAL和GLOBAL两个结构体。

在 Windows CE 6.0的内核启动时,OS找到OAL的入口位置,然后调用入口函数与全局块进行指针交换,这样内核才能使用OAL层中的信息,同样OAL层才能访问内核(kernel)导出的函数。

所以上述两个函数的调用实际上通过OEMGLOBAL结构体实现的。实际调用位置为$(_PRIVATEROOT)\winceos\coreos \nk\oemstub\oemstub.c中的OEMInitDebugSerial和OEMInit,这两个函数中通过OEMGLOBAL结构体指针 访问OAL层中的OEMInitDebugSerial和OEMInit。

首先看一下将WinCE6.0编译成诸如WinCE5.0所说的基本内核情况,即kern.exe。对于oal.exe源码位置比较容易找到,因为 oal.exe是启动代码与硬件相关的OAL层实现文件编译而成,所以只需在BSP的OAL目录中便能找到。而对于kernel.dll,在BSP目录结 构中,基本上无法找到kernel.dll的编译文件,所以必须从其他方面着手。

调用KernelFindMemory()函数分割RAM区域,在Windows CE *** 作系统中,RAM空间主要分为存储内存和程序内存,存储内存主要为文件的存储空间,包括内核文件和复制到系统中所有目标文件,程序内存为运行程序时所需要的存储空间。

◆KernelStart ()启动内核。

$(_PRIVATEROOT)\WINCEOS\COREOS\NK\KERNEL\ARM\mdarm.c

void NKStartup (struct KDataStruct * pKData)

{

。。。。

}

6、KernelSstart函数:

这里的KernelStart函数与前面的KernelStart函数的属于两个完全不 同的函数,NKStartup函数中调用的KernelStart函数为$(_PRIVATEROOT)\WINCEOS\COREOS\NK \KERNEL\ARM\armtrap.s文件中的KernelStart函数,主要完成调用内核初始化函数KernelInit,并跳转到 *** 作系统的 第一个启动的任务。

LEAF_ENTRY KernelStart

ldr r4, =KData (r4) = ptr to KDataStruct

ldr r0, =APIRet

str r0, [r4, #pAPIReturn] set API return address

mov r1, #SVC_MODE

msr cpsr_c, r1 switch to Supervisor Mode w/IRQs enabled

CALL KernelInit initialize scheduler, etc.

mov r0, #0 no current thread

mov r1, #ID_RESCHEDULE

b FirstSchedule

ENTRY_END

7、KernelInit函数:

Windows CE 6.0的内核初始化函数同其他版本的内核初始化函数基本相近,主要完成在启动第一个线程前对内核进行初始化,主要包括API函数集初始化、堆的初始化、初始化内存池、进程初始化、线程初始化和文件映射初始化等 *** 作。

void KernelInit (void)

。。。{

}

8、FirstSchedule:

FirstSchedule函数为Windows CE *** 作系统启动过程中最后无条件跳转的一个函数,windows CE进行第一个调度,实际为一个空闲线程,因为windows CE系统还没有完成启动,只有当windows CE完全启动并进入稳定状态,然后启动文件系统filesys.dll,设备管理device.dll,窗体图像子系统gews.dll和shell程序 explore.exe。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9906423.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-03
下一篇 2023-05-03

发表评论

登录后才能评论

评论列表(0条)

保存