Cosmos/source/Cosmos.Build.Windows/Builder.cs
mterwoord_cp 166318031b
2008-01-11 18:40:20 +00:00

126 lines
5.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.Threading;
namespace Cosmos.Build.Windows {
public class Builder {
protected string mBuildPath;
protected string mToolsPath;
protected string mISOPath;
protected string mPXEPath;
protected string mAsmPath;
public static string GetBuildPath() {
try {
var xKey = Registry.CurrentUser.OpenSubKey(@"Software\Cosmos");
var xResult = (string)xKey.GetValue("Build Path");
if (String.IsNullOrEmpty(xResult)) {
throw new Exception();
}
if (!xResult.EndsWith(@"\")) {
xResult = xResult + @"\";
}
return xResult;
} catch (Exception E) {
throw new Exception("Error while getting Cosmos Build Path!", E);
}
}
public Builder() {
mBuildPath = GetBuildPath();
mToolsPath = mBuildPath + @"Tools\";
mISOPath = mBuildPath + @"ISO\";
mPXEPath = mBuildPath + @"PXE\";
mAsmPath = mToolsPath + @"asm\";
}
protected void RemoveFile(string aPathname) {
if (File.Exists(aPathname)) {
File.Delete(aPathname);
}
}
protected void MakeISO() {
RemoveFile(mBuildPath + "cosmos.iso");
RemoveFile(mISOPath + "output.bin");
File.Copy(mBuildPath + "output.bin", mISOPath + "output.bin");
// From TFS its read only, mkisofs doesnt like that
File.SetAttributes(mISOPath + "isolinux.bin", FileAttributes.Normal);
Global.Call(mToolsPath + @"mkisofs.exe", @"-R -b isolinux.bin -no-emul-boot -boot-load-size 4 -boot-info-table -o ..\Cosmos.iso .", mISOPath);
}
public void Compile() {
if (!Directory.Exists(mAsmPath)) {
Directory.CreateDirectory(mAsmPath);
}
var xTarget = System.Reflection.Assembly.GetEntryAssembly();
IL2CPU.Program.Main(new string[] {@"-in:" + xTarget.Location
, "-plug:" + mToolsPath + @"Cosmos.Kernel.Plugs\Cosmos.Kernel.Plugs.dll"
, "-platform:nativex86", "-asm:" + mAsmPath}
);
RemoveFile(mBuildPath + "output.obj");
Global.Call(mToolsPath + @"nasm\nasm.exe", String.Format("-g -f elf -F stabs -o \"{0}\" \"{1}\"", mBuildPath + "output.obj", mAsmPath + "main.asm"), mBuildPath);
RemoveFile(mBuildPath + "output.bin");
Global.Call(mToolsPath + @"cygwin\ld.exe", String.Format("-Ttext 0x500000 -Tdata 0x200000 -e Kernel_Start -o \"{0}\" \"{1}\"", "output.bin", "output.obj"), mBuildPath);
RemoveFile(mBuildPath + "output.obj");
}
public void BuildKernel() {
}
public enum Target { ISO, PXE, QEMU, QEMU_GDB };
public void Build() {
var xOptions = new BuildOptionsWindow();
xOptions.ShowDialog();
}
public void Build(Target aType) {
Compile();
switch (aType) {
case Target.ISO:
MakeISO();
break;
case Target.PXE:
RemoveFile(mPXEPath + @"Boot\output.bin");
File.Move(mBuildPath + "output.bin", mPXEPath + @"Boot\output.bin");
// *Must* set working dir so tftpd32 will set itself to proper dir
Global.Call(mPXEPath + "tftpd32.exe", "", mPXEPath, false, false);
break;
case Target.QEMU:
MakeISO();
RemoveFile(mBuildPath + "serial-debug.txt");
Global.Call(mToolsPath + @"qemu\qemu.exe"
, "-L . -cdrom \"" + mBuildPath + "Cosmos.iso\" -boot d -serial \"file:" + mBuildPath + "serial-debug.txt" + "\" -kernel-kqemu", mToolsPath + @"qemu\"
, false, true);
break;
case Target.QEMU_GDB:
MakeISO();
RemoveFile(mBuildPath + "serial-debug.txt");
Global.Call(mToolsPath + @"qemu\qemu.exe"
, "-L . -cdrom \"" + mBuildPath + "Cosmos.iso\" -boot d -serial \"file:" + mBuildPath + "serial-debug.txt" + "\" -S -s", mToolsPath + @"qemu\"
, false, true);
//TODO: If the host is really busy, sometimes GDB can run before QEMU finishes loading.
//in this case, GDB says "program not running". Not sure how to fix this properly.
Global.Call(mToolsPath + "gdb.exe"
, mBuildPath + @"output.bin" + " --eval-command=\"target remote:1234\" --eval-command=\"b _CODE_REQUESTED_BREAK_\" --eval-command=\"c\""
, mToolsPath + @"qemu\", false, false);
break;
}
Console.WriteLine("Press enter to continue.");
Console.ReadLine();
}
}
}