惶恐中放上小弟的第一篇分析做品,水平有限,文筆不濟,但願各位見諒並提出意見和建議html
1、啓動以前程序員
VS的便捷同時也掩蓋了一個操做系統從源代碼轉換到二進制文件的中間流程,因此首先先從源代碼編譯下手,先弄清楚VS是怎麼把C#源代碼編譯成可引導啓動的二進制代碼。數據庫
本人使用的源代碼包爲cosmos-72205.zip工具
對於VS須要額外安裝:VS2010 SDK開發工具
2、MSBuild動畫
編譯過LINUX的朋友應該都熟悉Make文件吧,在這裏面能夠清楚的看到使用編譯器把C源代碼編譯成二進制源代碼的流程,中間幹了什麼均可以看得清清楚楚。但使用VS的朋友通常都是程序寫好以後直接F5就運行了,後面作了什麼咱們根本不知道。對於COSMOS的源代碼,VS只是幫咱們編譯成了IL的代碼,這種代碼沒法在沒有CLR環境中運行,因此VS還須要把IL代碼編譯爲針對CPU的本地代碼。這中間的流程都由MSBuild這個東西控制。對於MSBuild的介紹能夠直接查看MSDN文檔。總的來講這個東西的地位就至關於Make文件的地位吧,指導VS如何生成能夠引導的二進制文件。網站
3、編譯Cosmosui
首先先運行解壓出來的文件夾裏的Build/VSIP/install.bat文件,這個好像是用安裝Cosmos的編譯環境的。安裝完成,直接雙擊Source/cosmos.sln文件(在這以前須要先安裝VS2010 SDK)便可瀏覽所有源代碼文件(激動~~~~選擇COSMOS的主要緣由)。打開以後得先改一下啓動項目,在次修改爲Breakpoints這個項目 。而後就能夠直接F5啓動了。COSMOS編譯完成後會直接使用自帶的Bulid目錄下的虛擬機來加載編譯生成的ISO文件,並運行,運行界面以下:
spa
4、Cosmos的編譯過程操作系統
咱們能夠看到,工程裏面設爲啓動項的不是常規的C#項目,而已Cosmos項目,該項目在運行Build/VSIP/install.bat時安裝到VS2010中,編譯的時候會調用該項目本身的MSBuild文件來控制其編譯過程,能夠在C:\Program Files\MSBuild\Cosmos該目錄下找到一個Cosmos.target文件,用寫字板打開,找到以下內容:
<UsingTask TaskName="Cosmos.Build.MSBuild.IL2CPU" AssemblyFile="$(VSIPDir)\Cosmos.Build.MSBuild.dll" />
<UsingTask TaskName="Cosmos.Build.MSBuild.NAsm" AssemblyFile="$(VSIPDir)\Cosmos.Build.MSBuild.dll" />
<UsingTask TaskName="Cosmos.Build.MSBuild.MakeISO" AssemblyFile="$(VSIPDir)\Cosmos.Build.MSBuild.dll" />
<UsingTask TaskName="Cosmos.Build.MSBuild.Ld" AssemblyFile="$(VSIPDir)\Cosmos.Build.MSBuild.dll" />
<UsingTask TaskName="Cosmos.Build.MSBuild.ReadNAsmMapToCosmosMap" AssemblyFile="$(VSIPDir)\Cosmos.Build.MSBuild.dll" />
<UsingTask TaskName="Cosmos.Build.MSBuild.ExtractMapFromElfFile" AssemblyFile="$(VSIPDir)\Cosmos.Build.MSBuild.dll" />
我的理解,Cosmos項目編譯時應該會加載這些dll進內存,在Cosmos項目源代碼中到對應的項目,能夠發現它們都直接或者間接繼承自AppDomainIsolatedTask類,查看MSDN,這個繼承該類的類都重寫了execute方法,MSBuild在加載這些程序集時應該是會自動運行這些程序集中繼承自AppDomainIsolatedTask的類重寫的execute方法(運行的順序彷佛並非按照上面的書寫順序),那麼接下來咱們只要再分析每個execute方法,就能夠明白這個C#源代碼程序是如何編譯成爲本地CPU二進制格式的文件了(以上各個類運行時須要的參數能夠在該文件的接下來的部分找到,以下:
<IL2CPU DebugMode="$(DebugMode)"
TraceAssemblies="$(TraceAssemblies)"
DebugCom="1"
UseNAsm="true"
References="@(ReferencePath)"
OutputFilename="$(TargetDir)$(MSBuildProjectName).asm"
EnableLogging="true"
EmitDebugSymbols="$(DebugSymbols)"/>
<NAsm InputFile="$(TargetDir)$(MSBuildProjectName).asm"
OutputFile="$(TargetDir)$(MSBuildProjectName).obj"
IsELF="$(IsELF)"
ExePath="$(NasmFile)" />
<Ld CosmosBuildDir="$(CosmosDir)\Build"
WorkingDir="$(TargetDir)"
Arguments="-Ttext 0x500000 -Tdata 0x200000 -e Kernel_Start -o '$(TargetDir)$(MSBuildProjectName).bin' '$(TargetDir)$(MSBuildProjectName).obj'"
Condition="$(IsELF) == 'true'"/>
<Delete Files="$(TargetDir)$(MSBuildProjectName).obj" Condition="$(IsELF) == 'true'"/>
<ExtractMapFromElfFile InputFile="$(TargetDir)$(MSBuildProjectName).bin"
DebugInfoFile="$(TargetDir)$(MSBuildProjectName).cpdb"
WorkingDir="$(TargetDir)"
CosmosBuildDir="$(CosmosDir)\Build"
Condition="$(IsELF) == 'true'"/>
<CreateItem Include="$(TargetDir)$(MSBuildProjectName).bin" Condition="$(IsELF) == 'true'">
<Output TaskParameter="Include"
ItemName="TempFilesToCopy"/>
CreateItem>
<Copy SourceFiles="@(TempFilesToCopy)"
DestinationFiles="@(TempFilesToCopy->'$(TargetDir)\%(Filename).obj')"
Condition="$(IsELF) == 'true'"/>
<Delete Files="$(TargetDir)$(MSBuildProjectName).bin" Condition="$(IsELF) == 'true'"/>
<ReadNAsmMapToCosmosMap InputBaseDir="$(TargetDir)"
DebugInfoFile="$(TargetDir)$(MSBuildProjectName).cpdb"
Condition="$(IsELF) == 'false'"/>
<MakeISO InputFile="$(TargetDir)$(MSBuildProjectName).obj"
OutputFile="$(TargetDir)$(MSBuildProjectName).iso"
CosmosBuildDir="$(CosmosDir)\Build" />)。
4.1先從Cosmos.Build.MSBuild.IL2CPU開始。
Cosmos.Build.MSBuild.IL2CPU繼承自AppDomainIsolatedTask類,並重寫了execute方法,在execute方法中調用實例化的IL2CPUTask的類的execute方法。而IL2CPUTask類的execute方法則負責獲取程序的入口點,讀取全部的程序集文件。對於小弟的這個水平來講,因爲IL2CPU編譯器過於複雜,如下分析請你們以批判的角度來閱讀:讀取程序集文件後,應該是調用IL2CPU編譯器來把IL代碼轉換成本地CPU的彙編代碼文件.asm和支持調試用的符號文件.cpdb。到此Cosmos.Build.MSBuild.IL2CPU的任務就算完成了。接下來的事情交由Cosmos.Build.MSBuild.Nasm處理。
4.2 Cosmos.Build.MSBuild.Nasm
Cosmos.Build.MSBuild.Nasm直接繼承自Cosmos.Build.MSBuild.BaseToolTask,而BaseToolTask又直接繼承自AppDomainIsolatedTask,查看他們的execute方法內的代碼,能夠知道Nasm這個類應該是使用Nasm.exe(一個跨平臺的彙編開發工具)這個工具把上一步轉換出來的.asm文件編譯成elf格式的(關於elf格式能夠參看小弟空間裏的另外一篇文章http://www.cnblogs.com/li0803/archive/2010/11/15/1877961.html)目標文件.obj,到此Cosmos.Build.MSBuild.Nasm這個類的工做也結束了,接下來由Cosmos.Build.MSBuild.MakeISO這個類來處理
4.3 Cosmos.Build.MSBuild.MakeISO
Cosmos.Build.MSBuild.MakeISO與Nasm相似,直接繼承自BaseToolTask,間接繼承自AppDomainIsolatedTask,並重寫了本身的execute方法,做用是使用mkisofs.exe這個工具把上一步生成的.obj文件連接成一個ISO文件,以便虛擬機能夠加載運行。其實到這一步已經獲得了一個能夠運行的COSMOS操做系統文件了,但獲得的只是一個ISO文件,只能再虛擬機種運行,沒法安裝到實際的機子上,也不方便進行調試,因此COSMOS還要MSBuild作了一下的事情來生成一個.bin的二進制文件和一些支持在VS下對操做系統的源代碼進行調試的.cpdb符號表文件。不知道這麼說對不對,你們就僅當參考吧,不對的話也但願你們能夠幫忙指正一下,呵呵:)
4.4 Cosmos.Build.MSBuild.Ld
Cosmos.Build.MSBuild.Ld也與Nasm相似,直接繼承自BaseToolTask,間接繼承自AppDomainIsolatedTask,並重寫了本身的execute方法,做用是把Nasm類中編譯出來的.obj目標文件使用ld.exe工具連接成一個獨立的ELF格式的本地CPU可運行的二進制文件(有關編譯和連接的只是能夠參考《程序員的自我修養》),而後再交由Cosmos.Build.MSBuild.ExtractMapFromElfFile繼續處理
4.5 Cosmos.Build.MSBuild.ExtractMapFromElfFile
Cosmos.Build.MSBuild.ExtractMapFromElfFile一樣是直接繼承自BaseToolTask,間接繼承自AppDomainIsolatedTask,並重寫了本身的execute方法,在execute方法中調用objdump.exe來處理上一步生成的文件。小弟也是第一次接觸objdump.exe這個東西,從源代碼上看應該是分析上一步編譯出來的.bin文件,而後生成支持調試用的.cpdb符號表文件吧,接着再交由Cosmos.Build.MSBuild.ReadNAsmMapToCosmosMap作最後的處理。
4.6 Cosmos.Build.MSBuild.ReadNAsmMapToCosmosMap
Cosmos.Build.MSBuild.ReadNAsmMapToCosmosMap類直接繼承自AppDomainIsolatedTask類,並重寫本身的execute方法,做用是從Nasm任務中生成的.obj文件中讀取出地址符號映射表(什麼東西?不太懂),寫入自帶的firebird數據庫中,便於源代碼跟蹤調試用。
到此,COSMOS的編譯工做就算是所有完成了
做者: Hundre 發表於 2011-02-03 08:40 原文連接
最新新聞:
· Debian 6.0「Squeeze」發佈(2011-02-06 11:17)
· 傳諾基亞將進行管理層重組 多名高管將離職(2011-02-06 11:15)
· 即將舉辦超級碗的Cowboys體育場在Google Earth裏3D化(2011-02-06 11:07)
· Android 3.0 Honeycomb 炫麗蜂巢開機動畫(2011-02-06 10:57)
· Google 發佈 Contracts for Java 開源項目(2011-02-06 10:47)