/// <summary>
        /// Reads the master boot block.
        /// </summary>
        /// <returns></returns>
        public bool Read()
        {
            valid = false;

            MasterBootBlock mbr = new MasterBootBlock(diskDevice);

            if (!mbr.Valid)
                return false;

            if ((mbr.Partitions[0].PartitionType != PartitionType.GPT) ||
                (mbr.Partitions[1].PartitionType != PartitionType.Empty) ||
                (mbr.Partitions[2].PartitionType != PartitionType.Empty) ||
                (mbr.Partitions[3].PartitionType != PartitionType.Empty) ||
                (!mbr.Partitions[0].Bootable) || (mbr.Partitions[0].StartLBA != 1))
                return false;

            BinaryFormat gpt = new BinaryFormat(diskDevice.ReadBlock(1, 1));

            if ((gpt.GetByte(0) != 45) && (gpt.GetByte(1) != 46) && (gpt.GetByte(2) != 49) && (gpt.GetByte(3) != 20) &&
                (gpt.GetByte(4) != 50) && (gpt.GetByte(5) != 41) && (gpt.GetByte(6) != 52) && (gpt.GetByte(7) != 54))
                return false;

            if ((gpt.GetUInt(GPT.Revision) != GPTConstant.SupportedRevision) ||
                (gpt.GetUInt(GPT.HeaderSize) != GPTConstant.HeaderSize) ||
                (gpt.GetUInt(GPT.Reserved) != 0) ||
                (gpt.GetUInt(GPT.PartitionStartingLBA) != 2)
                )
                return false;

            valid = true;

            return valid;
        }
        /// <summary>
        /// Creates the partition devices.
        /// </summary>
        public void CreatePartitionDevices()
        {
            // FIXME: Do not create multiple partition devices if this method executed more than once

            // Find all online disk devices
            foreach (var device in deviceManager.GetDevices(new IsDiskDevice(), new IsOnline()))
            {
                var diskDevice = device as IDiskDevice;

                var mbr = new MasterBootBlock(diskDevice);

                if (!mbr.Valid)
                {
                    return;
                }

                for (uint i = 0; i < MasterBootBlock.MaxMBRPartitions; i++)
                {
                    if (mbr.Partitions[i].PartitionType != PartitionType.Empty)
                    {
                        deviceManager.Add(new PartitionDevice(diskDevice, mbr.Partitions[i], false));
                    }
                }
            }
        }
        /// <summary>
        /// Reads the master boot block.
        /// </summary>
        /// <returns></returns>
        public bool Read()
        {
            valid = false;

            MasterBootBlock mbr = new MasterBootBlock(diskDevice);

            if (!mbr.Valid)
            {
                return(false);
            }

            if ((mbr.Partitions[0].PartitionType != PartitionType.GPT) ||
                (mbr.Partitions[1].PartitionType != PartitionType.Empty) ||
                (mbr.Partitions[2].PartitionType != PartitionType.Empty) ||
                (mbr.Partitions[3].PartitionType != PartitionType.Empty) ||
                (!mbr.Partitions[0].Bootable) || (mbr.Partitions[0].StartLBA != 1))
            {
                return(false);
            }

            BinaryFormat gpt = new BinaryFormat(diskDevice.ReadBlock(1, 1));

            if ((gpt.GetByte(0) != 45) && (gpt.GetByte(1) != 46) && (gpt.GetByte(2) != 49) && (gpt.GetByte(3) != 20) &&
                (gpt.GetByte(4) != 50) && (gpt.GetByte(5) != 41) && (gpt.GetByte(6) != 52) && (gpt.GetByte(7) != 54))
            {
                return(false);
            }

            if ((gpt.GetUInt(GPT.Revision) != GPTConstant.SupportedRevision) ||
                (gpt.GetUInt(GPT.HeaderSize) != GPTConstant.HeaderSize) ||
                (gpt.GetUInt(GPT.Reserved) != 0) ||
                (gpt.GetUInt(GPT.PartitionStartingLBA) != 2)
                )
            {
                return(false);
            }

            valid = true;

            return(valid);
        }
示例#4
0
        /// <summary>
        /// Creates the partition devices.
        /// </summary>
        public void CreatePartitionDevices()
        {
            // FIXME: Do not create multiple partition devices if this method executed more than once

            // Find all online disk devices
            foreach (var device in deviceManager.GetDevices(new IsDiskDevice(), new IsOnline()))
            {
                var diskDevice = device as IDiskDevice;

                var mbr = new MasterBootBlock(diskDevice);

                if (!mbr.Valid)
                    return;

                for (uint i = 0; i < MasterBootBlock.MaxMBRPartitions; i++)
                {
                    if (mbr.Partitions[i].PartitionType != PartitionType.Empty)
                    {
                        deviceManager.Add(new PartitionDevice(diskDevice, mbr.Partitions[i], false));
                    }
                }
            }
        }
示例#5
0
        /// <summary>
        /// Creates the specified options.
        /// </summary>
        /// <param name="options">The options.</param>
        public static void Create(BootImageOptions options)
        {
            if (File.Exists(options.DiskImageFileName))
            {
                File.Delete(options.DiskImageFileName);
            }

            uint blockCount = options.BlockCount;

            if (blockCount == 0)
            {
                blockCount = 8400 + 1;
                foreach (var file in options.IncludeFiles)
                {
                    blockCount += ((uint)file.Content.Length / SectorSize) + 1;
                }
            }

            var diskGeometry = new DiskGeometry();
            diskGeometry.GuessGeometry(blockCount);

            // Create disk image file
            var diskDevice = new BlockFileStream(options.DiskImageFileName);

            if (options.ImageFormat == ImageFormat.VDI)
            {
                // Create header
                var header = VDI.CreateHeader(
                    blockCount,
                    options.MediaGuid.ToByteArray(),
                    options.MediaLastSnapGuid.ToByteArray(),
                    diskGeometry
                );

                diskDevice.WriteBlock(0, 1, header);

                var map = VDI.CreateImageMap(blockCount);

                diskDevice.WriteBlock(1, (uint)(map.Length / SectorSize), map);

                diskDevice.BlockOffset = 1 + (uint)(map.Length / 512);
            }

            // Expand disk image
            diskDevice.WriteBlock(blockCount - 1, 1, new byte[SectorSize]);

            // Create partition device
            PartitionDevice partitionDevice;

            if (options.MBROption)
            {
                // Create master boot block record
                var mbr = new MasterBootBlock(diskDevice);

                // Setup partition entry
                mbr.DiskSignature = 0x12345678;
                mbr.Partitions[0].Bootable = true;
                mbr.Partitions[0].StartLBA = diskGeometry.SectorsPerTrack;
                mbr.Partitions[0].TotalBlocks = blockCount - mbr.Partitions[0].StartLBA;

                switch (options.FileSystem)
                {
                    case FileSystem.FAT12: mbr.Partitions[0].PartitionType = PartitionType.FAT12; break;
                    case FileSystem.FAT16: mbr.Partitions[0].PartitionType = PartitionType.FAT16; break;
                    case FileSystem.FAT32: mbr.Partitions[0].PartitionType = PartitionType.FAT32; break;
                    default: break;
                }

                mbr.Code = options.MBRCode;

                mbr.Write();

                partitionDevice = new PartitionDevice(diskDevice, mbr.Partitions[0], false);
            }
            else
            {
                partitionDevice = new PartitionDevice(diskDevice, false);
            }

            // Set FAT settings
            var fatSettings = new FatSettings();

            switch (options.FileSystem)
            {
                case FileSystem.FAT12: fatSettings.FATType = FatType.FAT12; break;
                case FileSystem.FAT16: fatSettings.FATType = FatType.FAT16; break;
                case FileSystem.FAT32: fatSettings.FATType = FatType.FAT32; break;
                default: break;
            }

            fatSettings.FloppyMedia = false;
            fatSettings.VolumeLabel = options.VolumeLabel;
            fatSettings.SerialID = new byte[4] { 0x01, 0x02, 0x03, 0x04 };
            fatSettings.SectorsPerTrack = diskGeometry.SectorsPerTrack;
            fatSettings.NumberOfHeads = diskGeometry.Heads;
            fatSettings.HiddenSectors = diskGeometry.SectorsPerTrack;
            fatSettings.OSBootCode = options.FatBootCode;

            // Create FAT file system
            var fat = new FatFileSystem(partitionDevice);

            if (!fat.Format(fatSettings))
            {
                throw new Exception("ERROR: Invalid FAT settings");
            }

            fat.SetVolumeName(options.VolumeLabel);

            foreach (var includeFile in options.IncludeFiles)
            {
                var fileAttributes = new FatFileAttributes();
                if (includeFile.Archive) fileAttributes |= FatFileAttributes.Archive;
                if (includeFile.ReadOnly) fileAttributes |= FatFileAttributes.ReadOnly;
                if (includeFile.Hidden) fileAttributes |= FatFileAttributes.Hidden;
                if (includeFile.System) fileAttributes |= FatFileAttributes.System;

                string newname = (Path.GetFileNameWithoutExtension(includeFile.Filename).PadRight(8).Substring(0, 8) + Path.GetExtension(includeFile.Filename).PadRight(4).Substring(1, 3)).ToUpper();
                var location = fat.CreateFile(newname, fileAttributes);

                if (!location.IsValid)
                    throw new Exception("Unable to write file");

                var fatFileStream = new FatFileStream(fat, location);
                fatFileStream.Write(includeFile.Content, 0, includeFile.Content.Length);
                fatFileStream.Flush();
            }

            if (options.PatchSyslinuxOption)
            {
                if (options.BootLoader == BootLoader.Syslinux_6_03)
                {
                    Syslinux.PatchSyslinux_6_03(partitionDevice, fat);
                }
                else if (options.BootLoader == BootLoader.Syslinux_3_72)
                {
                    Syslinux.PatchSyslinux_3_72(partitionDevice, fat);
                }
            }

            if (options.ImageFormat == ImageFormat.VHD)
            {
                // Create footer
                var footer = VHD.CreateFooter(
                    blockCount,
                    (uint)(DateTime.Now - (new DateTime(2000, 1, 1, 0, 0, 0))).Seconds,
                    options.MediaGuid.ToByteArray(),
                    diskGeometry
                );

                diskDevice.WriteBlock(blockCount, 1, footer);
            }

            diskDevice.Dispose();
        }
示例#6
0
        /// <summary>
        /// Starts this instance.
        /// </summary>
        public static void Start()
        {
            // Setup hardware abstraction interface
            IHardwareAbstraction hardwareAbstraction = new Mosa.EmulatedKernel.HardwareAbstraction();

            // Set device driver system to the emulator port and memory methods
            Mosa.DeviceSystem.HAL.SetHardwareAbstraction(hardwareAbstraction);

            // Start the emulated devices
            Mosa.EmulatedDevices.Setup.Initialize();

            // Initialize the driver system
            Mosa.DeviceSystem.Setup.Initialize();

            // Registry device drivers
            Mosa.DeviceSystem.Setup.DeviceDriverRegistry.RegisterBuiltInDeviceDrivers();
            Mosa.DeviceSystem.Setup.DeviceDriverRegistry.RegisterDeviceDrivers(typeof(Mosa.DeviceDrivers.ISA.CMOS).Module.Assembly);

            // Set the interrupt handler
            Mosa.DeviceSystem.HAL.SetInterruptHandler(Mosa.DeviceSystem.Setup.ResourceManager.InterruptManager.ProcessInterrupt);

            // Start the driver system
            Mosa.DeviceSystem.Setup.Start();

            // Create pci controller manager
            PCIControllerManager pciControllerManager = new PCIControllerManager(Mosa.DeviceSystem.Setup.DeviceManager);

            // Create pci controller devices
            pciControllerManager.CreatePartitionDevices();

            // Create synthetic graphic pixel device
            Mosa.EmulatedDevices.Synthetic.PixelGraphicDevice pixelGraphicDevice = new Mosa.EmulatedDevices.Synthetic.PixelGraphicDevice(Mosa.EmulatedDevices.Setup.PrimaryDisplayForm);

            // Added the synthetic graphic device to the device drivers
            Mosa.DeviceSystem.Setup.DeviceManager.Add(pixelGraphicDevice);

            // Create synthetic ram disk device
            Mosa.EmulatedDevices.Synthetic.RamDiskDevice ramDiskDevice = new Mosa.EmulatedDevices.Synthetic.RamDiskDevice(1024 * 1024 * 10 / 512);

            // Add emulated ram disk device to the device drivers
            Mosa.DeviceSystem.Setup.DeviceManager.Add(ramDiskDevice);

            // Create disk controller manager
            DiskControllerManager diskControllerManager = new DiskControllerManager(Mosa.DeviceSystem.Setup.DeviceManager);

            // Create disk devices from disk controller devices
            diskControllerManager.CreateDiskDevices();

            // Get the text VGA device
            LinkedList<IDevice> devices = Mosa.DeviceSystem.Setup.DeviceManager.GetDevices(new FindDevice.WithName("VGAText"));

            // Create a screen interface to the text VGA device
            ITextScreen screen = new TextScreen((ITextDevice)devices.First.value);

            // Create synthetic keyboard device
            Mosa.EmulatedDevices.Synthetic.Keyboard keyboard = new Mosa.EmulatedDevices.Synthetic.Keyboard(Mosa.EmulatedDevices.Setup.PrimaryDisplayForm);

            // Add the synthetic keyboard device to the device drivers
            Mosa.DeviceSystem.Setup.DeviceManager.Add(keyboard);

            // Create master boot block record
            MasterBootBlock mbr = new MasterBootBlock(ramDiskDevice);
            mbr.DiskSignature = 0x12345678;
            mbr.Partitions[0].Bootable = true;
            mbr.Partitions[0].StartLBA = 17;
            mbr.Partitions[0].TotalBlocks = ramDiskDevice.TotalBlocks - 17;
            mbr.Partitions[0].PartitionType = PartitionType.FAT12;
            mbr.Write();

            // Create partition device
            PartitionDevice partitionDevice = new PartitionDevice(ramDiskDevice, mbr.Partitions[0], false);

            // Set FAT settings
            FatSettings fatSettings = new FatSettings();

            fatSettings.FATType = FatType.FAT12;
            fatSettings.FloppyMedia = false;
            fatSettings.VolumeLabel = "MOSADISK";
            fatSettings.SerialID = new byte[4] { 0x01, 0x02, 0x03, 0x04 };

            // Create FAT file system
            FatFileSystem fat12 = new FatFileSystem(partitionDevice);
            fat12.Format(fatSettings);

            // Create partition manager
            PartitionManager partitionManager = new PartitionManager(Mosa.DeviceSystem.Setup.DeviceManager);

            // Create partition devices
            partitionManager.CreatePartitionDevices();

            // Get a list of all devices
            devices = Mosa.DeviceSystem.Setup.DeviceManager.GetAllDevices();

            // Print them
            screen.WriteLine("Devices: ");
            foreach (IDevice device in devices) {

                screen.Write(device.Name);
                screen.Write(" [");

                switch (device.Status) {
                    case DeviceStatus.Online: screen.Write("Online"); break;
                    case DeviceStatus.Available: screen.Write("Available"); break;
                    case DeviceStatus.Initializing: screen.Write("Initializing"); break;
                    case DeviceStatus.NotFound: screen.Write("Not Found"); break;
                    case DeviceStatus.Error: screen.Write("Error"); break;
                }
                screen.Write("]");

                if (device.Parent != null) {
                    screen.Write(" - Parent: ");
                    screen.Write(device.Parent.Name);
                }
                screen.WriteLine();

                if (device is IPartitionDevice) {
                    FileSystem.FAT.FatFileSystem fat = new Mosa.FileSystem.FAT.FatFileSystem(device as IPartitionDevice);

                    screen.Write("  File System: ");
                    if (fat.IsValid) {
                        switch (fat.FATType) {
                            case FatType.FAT12: screen.WriteLine("FAT12"); break;
                            case FatType.FAT16: screen.WriteLine("FAT16"); break;
                            case FatType.FAT32: screen.WriteLine("FAT32"); break;
                            default: screen.WriteLine("Unknown"); break;
                        }
                        screen.WriteLine("  Volume Name: " + fat.VolumeLabel);
                    }
                    else
                        screen.WriteLine("Unknown");
                }

                if (device is PCIDevice) {
                    PCIDevice pciDevice = (device as PCIDevice);

                    screen.Write("  Vendor:0x");
                    screen.Write(pciDevice.VendorID.ToString("X"));
                    screen.Write(" [");
                    screen.Write(DeviceTable.Lookup(pciDevice.VendorID));
                    screen.WriteLine("]");

                    screen.Write("  Device:0x");
                    screen.Write(pciDevice.DeviceID.ToString("X"));
                    screen.Write(" Rev:0x");
                    screen.Write(pciDevice.RevisionID.ToString("X"));
                    screen.Write(" [");
                    screen.Write(DeviceTable.Lookup(pciDevice.VendorID, pciDevice.DeviceID));
                    screen.WriteLine("]");

                    screen.Write("  Class:0x");
                    screen.Write(pciDevice.ClassCode.ToString("X"));
                    screen.Write(" [");
                    screen.Write(ClassCodeTable.Lookup(pciDevice.ClassCode));
                    screen.WriteLine("]");

                    screen.Write("  SubClass:0x");
                    screen.Write(pciDevice.SubClassCode.ToString("X"));
                    screen.Write(" [");
                    screen.Write(SubClassCodeTable.Lookup(pciDevice.ClassCode, pciDevice.SubClassCode, pciDevice.ProgIF));
                    screen.WriteLine("]");

                    //					screen.Write("  ");
                    //					screen.WriteLine(DeviceTable.Lookup(pciDevice.VendorID, pciDevice.DeviceID, pciDevice.SubDeviceID, pciDevice.SubVendorID));

                    foreach (BaseAddress address in pciDevice.BaseAddresses) {
                        if (address == null)
                            continue;

                        if (address.Address == 0)
                            continue;

                        screen.Write("    ");

                        if (address.Region == AddressType.IO)
                            screen.Write("I/O Port at 0x");
                        else
                            screen.Write("Memory at 0x");

                        screen.Write(address.Address.ToString("X"));

                        screen.Write(" [size=");

                        if ((address.Size & 0xFFFFF) == 0) {
                            screen.Write((address.Size >> 20).ToString());
                            screen.Write("M");
                        }
                        else if ((address.Size & 0x3FF) == 0) {
                            screen.Write((address.Size >> 10).ToString());
                            screen.Write("K");
                        }
                        else
                            screen.Write(address.Size.ToString());

                        screen.Write("]");

                        if (address.Prefetchable)
                            screen.Write("(prefetchable)");

                        screen.WriteLine();
                    }

                    if (pciDevice.IRQ != 0) {
                        screen.Write("    ");
                        screen.Write("IRQ at ");
                        screen.Write(pciDevice.IRQ.ToString());
                        screen.WriteLine();
                    }
                }
            }

            //while (keyboard.GetKeyPressed() == null) ;

            Mosa.HelloWorld.Boot.Main();

            //EmulatorDemo.StartDemo();

            return;
        }
示例#7
0
        /// <summary>
        /// Creates the specified options.
        /// </summary>
        /// <param name="options">The options.</param>
        public static void Create(Options options)
        {
            if (File.Exists(options.DiskImageFileName))
            {
                File.Delete(options.DiskImageFileName);
            }

            uint blockCount = options.BlockCount;

            if (blockCount == 0)
            {
                blockCount = 8400 + 1;
                foreach (var file in options.IncludeFiles)
                {
                    blockCount += ((uint)file.Content.Length / 512) + 1;
                }
            }

            var diskGeometry = new Mosa.DeviceSystem.DiskGeometry();
            diskGeometry.GuessGeometry(blockCount);

            // Create disk image file
            BlockFileStream diskDevice = new BlockFileStream(options.DiskImageFileName);

            if (options.ImageFormat == ImageFormatType.VDI)
            {
                // Create header
                byte[] header = Mosa.DeviceSystem.VDI.CreateHeader(
                    blockCount,
                    options.MediaGuid.ToByteArray(),
                    options.MediaLastSnapGuid.ToByteArray(),
                    diskGeometry
                );

                diskDevice.WriteBlock(0, 1, header);

                byte[] map = Mosa.DeviceSystem.VDI.CreateImageMap(blockCount);

                diskDevice.WriteBlock(1, (uint)(map.Length / 512), map);

                diskDevice.BlockOffset = 1 + (uint)(map.Length / 512);
            }

            // Expand disk image
            diskDevice.WriteBlock(blockCount - 1, 1, new byte[512]);

            // Create partition device
            PartitionDevice partitionDevice;

            if (options.MBROption)
            {
                // Create master boot block record
                MasterBootBlock mbr = new MasterBootBlock(diskDevice);

                // Setup partition entry
                mbr.DiskSignature = 0x12345678;
                mbr.Partitions[0].Bootable = true;
                mbr.Partitions[0].StartLBA = diskGeometry.SectorsPerTrack;
                mbr.Partitions[0].TotalBlocks = blockCount - mbr.Partitions[0].StartLBA;

                switch (options.FileSystem)
                {
                    case FileSystemType.FAT12: mbr.Partitions[0].PartitionType = PartitionType.FAT12; break;
                    case FileSystemType.FAT16: mbr.Partitions[0].PartitionType = PartitionType.FAT16; break;
                    case FileSystemType.FAT32: mbr.Partitions[0].PartitionType = PartitionType.FAT32; break;
                    default: break;
                }

                mbr.Code = options.MBRCode;

                mbr.Write();

                partitionDevice = new PartitionDevice(diskDevice, mbr.Partitions[0], false);
            }
            else
            {
                partitionDevice = new PartitionDevice(diskDevice, false);
            }

            // Set FAT settings
            FatSettings fatSettings = new FatSettings();

            switch (options.FileSystem)
            {
                case FileSystemType.FAT12: fatSettings.FATType = FatType.FAT12; break;
                case FileSystemType.FAT16: fatSettings.FATType = FatType.FAT16; break;
                case FileSystemType.FAT32: fatSettings.FATType = FatType.FAT32; break;
                default: break;
            }

            fatSettings.FloppyMedia = false;
            fatSettings.VolumeLabel = options.VolumeLabel;
            fatSettings.SerialID = new byte[4] { 0x01, 0x02, 0x03, 0x04 };
            fatSettings.SectorsPerTrack = diskGeometry.SectorsPerTrack;
            fatSettings.NumberOfHeads = diskGeometry.Heads;
            fatSettings.HiddenSectors = diskGeometry.SectorsPerTrack;
            fatSettings.OSBootCode = options.FatBootCode;

            // Create FAT file system
            FatFileSystem fat = new FatFileSystem(partitionDevice);
            if (!fat.Format(fatSettings))
            {
                throw new Exception("ERROR: Invalid FAT settings");
            }

            fat.SetVolumeName(options.VolumeLabel);

            foreach (var includeFile in options.IncludeFiles)
            {
                Mosa.FileSystem.FAT.FatFileAttributes fileAttributes = new Mosa.FileSystem.FAT.FatFileAttributes();
                if (includeFile.Archive) fileAttributes |= Mosa.FileSystem.FAT.FatFileAttributes.Archive;
                if (includeFile.ReadOnly) fileAttributes |= Mosa.FileSystem.FAT.FatFileAttributes.ReadOnly;
                if (includeFile.Hidden) fileAttributes |= Mosa.FileSystem.FAT.FatFileAttributes.Hidden;
                if (includeFile.System) fileAttributes |= Mosa.FileSystem.FAT.FatFileAttributes.System;

                //byte[] file = File.ReadAllBytes(includeFile.Filename);
                string newname = (Path.GetFileNameWithoutExtension(includeFile.Filename).PadRight(8).Substring(0, 8) + Path.GetExtension(includeFile.Filename).PadRight(4).Substring(1, 3)).ToUpper();
                FatFileLocation location = fat.CreateFile(newname, fileAttributes, 0);

                if (!location.Valid)
                    throw new Exception("Unable to write file");

                FatFileStream fatFileStream = new FatFileStream(fat, location);
                fatFileStream.Write(includeFile.Content, 0, includeFile.Content.Length);
                fatFileStream.Flush();
            }

            if (options.PatchSyslinuxOption)
            {
                // Locate ldlinux.sys file for patching
                string filename = "ldlinux.sys";
                string name = (Path.GetFileNameWithoutExtension(filename) + Path.GetExtension(filename).PadRight(4).Substring(0, 4)).ToUpper();

                FatFileLocation location = fat.FindEntry(new Mosa.FileSystem.FAT.Find.WithName(name), 0);

                if (location.Valid)
                {
                    // Read boot sector
                    Mosa.ClassLib.BinaryFormat bootSector = new Mosa.ClassLib.BinaryFormat(partitionDevice.ReadBlock(0, 1));

                    // Set the first sector location of the file
                    bootSector.SetUInt(0x1F8, fat.GetSectorByCluster(location.FirstCluster));

                    // Change jump address
                    bootSector.SetUInt(0x01, 0x58);

                    // Write back patched boot sector
                    partitionDevice.WriteBlock(0, 1, bootSector.Data);

                    // Get the file size & number of sectors used
                    uint fileSize = fat.GetFileSize(location.DirectorySector, location.DirectorySectorIndex);
                    uint sectorCount = (fileSize + 511) >> 9;

                    uint[] sectors = new uint[65];
                    uint nsec = 0;

                    // Create list of the first 65 sectors of the file
                    for (uint cluster = location.FirstCluster; ((cluster != 0) & (nsec <= 64)); cluster = fat.GetNextCluster(cluster))
                    {
                        uint sec = fat.GetSectorByCluster(cluster);
                        for (uint s = 0; s < fat.SectorsPerCluster; s++)
                            sectors[nsec++] = sec + s;
                    }

                    // Read the first cluster of the file
                    Mosa.ClassLib.BinaryFormat firstCluster = new Mosa.ClassLib.BinaryFormat(fat.ReadCluster(location.FirstCluster));

                    uint patchArea = 0;

                    // Search for 0x3EB202FE (magic)
                    for (patchArea = 0; (firstCluster.GetUInt(patchArea) != 0x3EB202FE) && (patchArea < fat.ClusterSizeInBytes); patchArea += 4) ;

                    patchArea = patchArea + 8;

                    if (patchArea < fat.ClusterSizeInBytes)
                    {
                        // Set up the totals
                        firstCluster.SetUShort(patchArea, (ushort)(fileSize >> 2));
                        firstCluster.SetUShort(patchArea + 2, (ushort)(sectorCount - 1));

                        // Clear sector entries
                        firstCluster.Fill(patchArea + 8, 0, 64 * 4);

                        // Set sector entries
                        for (nsec = 0; nsec < 64; nsec++)
                            firstCluster.SetUInt(patchArea + 8 + (nsec * 4), sectors[nsec + 1]);

                        // Clear out checksum
                        firstCluster.SetUInt(patchArea + 4, 0);

                        // Write back the updated cluster
                        fat.WriteCluster(location.FirstCluster, firstCluster.Data);

                        // Re-Calculate checksum by opening the file
                        FatFileStream file = new FatFileStream(fat, location);

                        uint csum = 0x3EB202FE;
                        for (uint index = 0; index < (file.Length >> 2); index++)
                        {
                            uint value = (uint)file.ReadByte() | ((uint)file.ReadByte() << 8) | ((uint)file.ReadByte() << 16) | ((uint)file.ReadByte() << 24);
                            csum -= value;
                        }

                        // Set the checksum
                        firstCluster.SetUInt(patchArea + 4, csum);

                        // Write patched cluster back to disk
                        fat.WriteCluster(location.FirstCluster, firstCluster.Data);
                    }
                }
            }

            if (options.ImageFormat == ImageFormatType.VHD)
            {
                // Create footer
                byte[] footer = Mosa.DeviceSystem.VHD.CreateFooter(
                    blockCount,
                    (uint)(DateTime.Now - (new DateTime(2000, 1, 1, 0, 0, 0))).Seconds,
                    options.MediaGuid.ToByteArray(),
                    diskGeometry
                );

                diskDevice.WriteBlock(blockCount, 1, footer);
            }

            diskDevice.Dispose();
        }
示例#8
0
        /// <summary>
        /// Main
        /// </summary>
        /// <param name="args">The args.</param>
        /// <returns></returns>
        static int Main(string[] args)
        {
            Console.WriteLine();
            Console.WriteLine("MakeImageBoot v1.0 [www.mosa-project.org]");
            Console.WriteLine("Copyright 2010. New BSD License.");
            Console.WriteLine("Written by Philipp Garcia ([email protected])");
            Console.WriteLine();

            string mbrFilename = string.Empty;
            string fatcodeFilename = string.Empty;
            string volumeLabel = string.Empty;
            ImageFormat imageFormat = ImageFormat.VHD;
            bool mbrOption = true;
            bool patchSyslinuxOption = false;
            bool floppyMedia = false;
            uint blockCount = 1024 * 1024 / 512;
            FileSystem fileSystem = FileSystem.FAT12;
            List<IncludeFile> includeFiles = new List<IncludeFile>();

            bool valid = (args.Length < 2);

            if (valid)
                valid = System.IO.File.Exists(args[0]);

            if (valid)
            {
                Console.WriteLine("Usage: CreateBootImage <boot.config file> <image name>");
                Console.Error.WriteLine("ERROR: Missing arguments");
                return -1;
            }

            Console.WriteLine("Building image...");

            try
            {

                StreamReader reader = File.OpenText(args[0]);

                while (true)
                {
                    string line = reader.ReadLine();
                    if (line == null) break;

                    if (string.IsNullOrEmpty(line))
                        continue;

                    string[] parts = line.Split('\t');

                    switch (parts[0].Trim())
                    {
                        case "-mbr": mbrOption = true; mbrFilename = (parts.Length > 1) ? parts[1] : null; break;
                        case "-boot": fatcodeFilename = (parts.Length > 1) ? parts[1] : null; break;
                        case "-vhd": imageFormat = ImageFormat.VHD; break;
                        case "-img": imageFormat = ImageFormat.IMG; break;
                        case "-vdi": imageFormat = ImageFormat.VDI; break;
                        case "-syslinux": patchSyslinuxOption = true; break;
                        case "-fat12": fileSystem = FileSystem.FAT12; break;
                        case "-fat16": fileSystem = FileSystem.FAT16; break;
                        case "-fat32": fileSystem = FileSystem.FAT32; break;
                        case "-file": if (parts.Length > 2) includeFiles.Add(new IncludeFile(parts[1], parts[2]));
                            else includeFiles.Add(new IncludeFile(parts[1])); break;
                        case "-blocks": blockCount = Convert.ToUInt32(parts[1]); break;
                        case "-volume": volumeLabel = parts[1]; break;
                        case "-floppy": floppyMedia = true; break;
                        default: break;
                    }
                }

                reader.Close();

                if (System.IO.File.Exists(args[1]))
                    System.IO.File.Delete(args[1]);

                DiskGeometry diskGeometry = new Mosa.DeviceSystem.DiskGeometry();
                diskGeometry.GuessGeometry(blockCount);

                Console.WriteLine("Disk Geometry CHS = " + diskGeometry.Cylinders + "/" + diskGeometry.Heads + "/" + diskGeometry.SectorsPerTrack);

                // Create disk image file
                Mosa.EmulatedDevices.Synthetic.DiskDevice diskDevice = new Mosa.EmulatedDevices.Synthetic.DiskDevice(args[1]);

                if (imageFormat == ImageFormat.VDI)
                {
                    // Create header
                    byte[] header = Mosa.DeviceSystem.VDI.CreateHeader(
                        blockCount,
                        Guid.NewGuid().ToByteArray(),
                        Guid.NewGuid().ToByteArray(),
                        diskGeometry
                    );

                    diskDevice.WriteBlock(0, 1, header);

                    byte[] map = Mosa.DeviceSystem.VDI.CreateImageMap(blockCount);

                    diskDevice.WriteBlock(1, (uint)(map.Length / 512), map);

                    diskDevice.BlockOffset = 1 + (uint)(map.Length / 512);
                }

                // Expand disk image
                diskDevice.WriteBlock(blockCount - 1, 1, new byte[512]);

                // Create partition device
                PartitionDevice partitionDevice;

                if (mbrOption)
                {
                    // Create master boot block record
                    MasterBootBlock mbr = new MasterBootBlock(diskDevice);

                    // Setup partition entry
                    mbr.DiskSignature = 0x12345678;
                    mbr.Partitions[0].Bootable = true;
                    mbr.Partitions[0].StartLBA = diskGeometry.SectorsPerTrack;
                    mbr.Partitions[0].TotalBlocks = blockCount - mbr.Partitions[0].StartLBA;

                    switch (fileSystem)
                    {
                        case FileSystem.FAT12: mbr.Partitions[0].PartitionType = PartitionType.FAT12; break;
                        case FileSystem.FAT16: mbr.Partitions[0].PartitionType = PartitionType.FAT16; break;
                        case FileSystem.FAT32: mbr.Partitions[0].PartitionType = PartitionType.FAT32; break;
                        default: break;
                    }

                    if (!string.IsNullOrEmpty(mbrFilename))
                        mbr.Code = ReadFile(mbrFilename);

                    mbr.Write();

                    partitionDevice = new PartitionDevice(diskDevice, mbr.Partitions[0], false);
                }
                else
                {
                    partitionDevice = new PartitionDevice(diskDevice, false);
                }

                // Set FAT settings
                FatSettings fatSettings = new FatSettings();

                switch (fileSystem)
                {
                    case FileSystem.FAT12: fatSettings.FATType = FatType.FAT12; break;
                    case FileSystem.FAT16: fatSettings.FATType = FatType.FAT16; break;
                    case FileSystem.FAT32: fatSettings.FATType = FatType.FAT32; break;
                    default: break;
                }

                fatSettings.FloppyMedia = floppyMedia;
                fatSettings.VolumeLabel = volumeLabel;
                fatSettings.SerialID = new byte[4] { 0x01, 0x02, 0x03, 0x04 };
                fatSettings.SectorsPerTrack = diskGeometry.SectorsPerTrack;
                fatSettings.NumberOfHeads = diskGeometry.Heads;
                fatSettings.HiddenSectors = diskGeometry.SectorsPerTrack;
                if (!string.IsNullOrEmpty(fatcodeFilename))
                    fatSettings.OSBootCode = ReadFile(fatcodeFilename);

                // Create FAT file system
                FatFileSystem fat = new FatFileSystem(partitionDevice);
                fat.Format(fatSettings);

                fat.SetVolumeName(volumeLabel);

                foreach (IncludeFile includeFile in includeFiles)
                {
                    string filename = includeFile.Filename;

                    Mosa.FileSystem.FAT.FatFileAttributes fileAttributes = new Mosa.FileSystem.FAT.FatFileAttributes();
                    if (includeFile.Archive) fileAttributes |= Mosa.FileSystem.FAT.FatFileAttributes.Archive;
                    if (includeFile.ReadOnly) fileAttributes |= Mosa.FileSystem.FAT.FatFileAttributes.ReadOnly;
                    if (includeFile.Hidden) fileAttributes |= Mosa.FileSystem.FAT.FatFileAttributes.Hidden;
                    if (includeFile.System) fileAttributes |= Mosa.FileSystem.FAT.FatFileAttributes.System;

                    byte[] file = ReadFile(filename);
                    string newname = (Path.GetFileNameWithoutExtension(includeFile.Newname).PadRight(8).Substring(0, 8) + Path.GetExtension(includeFile.Newname).PadRight(3).Substring(1, 3)).ToUpper();
                    FatFileLocation location = fat.CreateFile(newname, fileAttributes, 0);

                    if (!location.Valid)
                        throw new Exception("Unable to write file");

                    FatFileStream fatFileStream = new FatFileStream(fat, location);
                    fatFileStream.Write(file, 0, file.Length);
                    fatFileStream.Flush();
                }

                if (patchSyslinuxOption)
                {
                    // Locate ldlinux.sys file for patching
                    string filename = "ldlinux.sys";
                    string name = (Path.GetFileNameWithoutExtension(filename) + Path.GetExtension(filename).PadRight(3).Substring(0, 4)).ToUpper();

                    FatFileLocation location = fat.FindEntry(new Mosa.FileSystem.FAT.Find.WithName(name), 0);

                    if (location.Valid)
                    {
                        // Read boot sector
                        Mosa.ClassLib.BinaryFormat bootSector = new Mosa.ClassLib.BinaryFormat(partitionDevice.ReadBlock(0, 1));

                        // Set the first sector location of the file
                        bootSector.SetUInt(0x1F8, fat.GetSectorByCluster(location.FirstCluster));

                        // Change jump address
                        bootSector.SetUInt(0x01, 0x58);

                        // Write back patched boot sector
                        partitionDevice.WriteBlock(0, 1, bootSector.Data);

                        // Get the file size & number of sectors used
                        uint fileSize = fat.GetFileSize(location.DirectorySector, location.DirectorySectorIndex);
                        uint sectorCount = (fileSize + 511) >> 9;

                        uint[] sectors = new uint[65];
                        uint nsec = 0;

                        // Create list of the first 65 sectors of the file
                        for (uint cluster = location.FirstCluster; ((cluster != 0) & (nsec <= 64)); cluster = fat.GetNextCluster(cluster))
                        {
                            uint sec = fat.GetSectorByCluster(cluster);
                            for (uint s = 0; s < fat.SectorsPerCluster; s++)
                                sectors[nsec++] = sec + s;
                        }

                        // Read the first cluster of the file
                        Mosa.ClassLib.BinaryFormat firstCluster = new Mosa.ClassLib.BinaryFormat(fat.ReadCluster(location.FirstCluster));

                        uint patchArea = 0;

                        // Search for 0x3EB202FE (magic)
                        for (patchArea = 0; (firstCluster.GetUInt(patchArea) != 0x3EB202FE) && (patchArea < fat.ClusterSizeInBytes); patchArea += 4) ;

                        patchArea = patchArea + 8;

                        if (patchArea < fat.ClusterSizeInBytes)
                        {
                            // Set up the totals
                            firstCluster.SetUShort(patchArea, (ushort)(fileSize >> 2));
                            firstCluster.SetUShort(patchArea + 2, (ushort)(sectorCount - 1));

                            // Clear sector entries
                            firstCluster.Fill(patchArea + 8, 0, 64 * 4);

                            // Set sector entries
                            for (nsec = 0; nsec < 64; nsec++)
                                firstCluster.SetUInt(patchArea + 8 + (nsec * 4), sectors[nsec + 1]);

                            // Clear out checksum
                            firstCluster.SetUInt(patchArea + 4, 0);

                            // Write back the updated cluster
                            fat.WriteCluster(location.FirstCluster, firstCluster.Data);

                            // Re-Calculate checksum by openning the file
                            FatFileStream file = new FatFileStream(fat, location);

                            uint csum = 0x3EB202FE;
                            for (uint index = 0; index < (file.Length >> 2); index++)
                            {
                                uint value = (uint)file.ReadByte() | ((uint)file.ReadByte() << 8) | ((uint)file.ReadByte() << 16) | ((uint)file.ReadByte() << 24);
                                csum -= value;
                            }

                            // Set the checksum
                            firstCluster.SetUInt(patchArea + 4, csum);

                            // Write patched cluster back to disk
                            fat.WriteCluster(location.FirstCluster, firstCluster.Data);
                        }

                    }
                }

                if (imageFormat == ImageFormat.VHD)
                {
                    // Create footer
                    byte[] footer = Mosa.DeviceSystem.VHD.CreateFooter(
                        blockCount,
                        (uint)(DateTime.Now - (new DateTime(2000, 1, 1, 0, 0, 0))).Seconds,
                        Guid.NewGuid().ToByteArray(),
                        diskGeometry
                    );

                    diskDevice.WriteBlock(blockCount, 1, footer);
                }

                Console.WriteLine("Completed!");
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Error: " + e.ToString());
                return -1;
            }

            return 0;
        }
示例#9
0
        private static void Main(string[] args)
        {
            // Create synthetic ram disk device
            var ramDiskDevice = new RamDiskDevice(1024 * 1024 * 10 / 512);

            // Create master boot block record
            var mbr = new MasterBootBlock(ramDiskDevice);
            mbr.DiskSignature = 0x12345678;
            mbr.Partitions[0].Bootable = true;
            mbr.Partitions[0].StartLBA = 17;
            mbr.Partitions[0].TotalBlocks = ramDiskDevice.TotalBlocks - 17;
            mbr.Partitions[0].PartitionType = PartitionType.FAT12;
            mbr.Write();

            // Create partition device
            var partitionDevice = new PartitionDevice(ramDiskDevice, mbr.Partitions[0], false);

            // Set FAT settings
            var fatSettings = new FatSettings();

            fatSettings.FATType = FatType.FAT12;
            fatSettings.FloppyMedia = false;
            fatSettings.VolumeLabel = "MOSADISK";
            fatSettings.SerialID = new byte[4] { 0x01, 0x02, 0x03, 0x04 };

            // Create FAT file system
            var fat = new FatFileSystem(partitionDevice);
            fat.Format(fatSettings);

            if (fat.IsValid)
            {
                switch (fat.FATType)
                {
                    case FatType.FAT12: Console.WriteLine("FAT12"); break;
                    case FatType.FAT16: Console.WriteLine("FAT16"); break;
                    case FatType.FAT32: Console.WriteLine("FAT32"); break;
                    default: Console.WriteLine("Unknown"); break;
                }
                Console.WriteLine("  Volume Name: " + fat.VolumeLabel);
            }
            else
            {
                Console.WriteLine("Unknown File System");
            }

            var files = new List<IncludeFile>();

            files.Add(new IncludeFile("CREDITS.TXT", GetResource("CREDITS.txt")));
            files.Add(new IncludeFile("LICENSE.TXT", GetResource("LICENSE.txt")));

            foreach (var includeFile in files)
            {
                Console.WriteLine("Writing File: " + includeFile.Filename);

                var fileAttributes = new FatFileAttributes();
                if (includeFile.Archive) fileAttributes |= FatFileAttributes.Archive;
                if (includeFile.ReadOnly) fileAttributes |= FatFileAttributes.ReadOnly;
                if (includeFile.Hidden) fileAttributes |= FatFileAttributes.Hidden;
                if (includeFile.System) fileAttributes |= FatFileAttributes.System;

                string newname = (Path.GetFileNameWithoutExtension(includeFile.Filename).PadRight(8).Substring(0, 8) + Path.GetExtension(includeFile.Filename).PadRight(4).Substring(1, 3)).ToUpper();
                var location = fat.CreateFile(newname, fileAttributes);

                if (!location.IsValid)
                    throw new Exception("Unable to write file");

                var fatFileStream = new FatFileStream(fat, location);
                fatFileStream.Write(includeFile.Content, 0, includeFile.Content.Length);
                fatFileStream.Flush();

                Console.WriteLine("  Source Length: " + includeFile.Content.Length.ToString());
                Console.WriteLine("  Stream Length: " + fatFileStream.Length.ToString());
            }

            foreach (var includeFile in files)
            {
                Console.WriteLine("Searching File: " + includeFile.Filename);

                var location = fat.FindEntry(includeFile.Filename);

                if (location.IsValid)
                {
                    Console.WriteLine("  Found: " + includeFile.Filename);

                    var fatFileStream = new FatFileStream(fat, location);
                    Console.WriteLine("  Length: " + fatFileStream.Length.ToString());

                    for (;;)
                    {
                        int i = fatFileStream.ReadByte();

                        if (i < 0)
                            break;

                        Console.Write((char)i);
                    }
                    Console.WriteLine();
                    fatFileStream.Position = 0;

                    var buffer = new byte[fatFileStream.Length];
                    fatFileStream.Read(buffer, 0, (int)fatFileStream.Length);

                    Console.WriteLine(System.Text.Encoding.UTF8.GetString(buffer));
                }
                else
                {
                    Console.WriteLine("  Not Found: " + includeFile.Filename);
                }
            }

            return;
        }