a1ive / grub

Fork of GRUB 2 to add various features.
GNU General Public License v3.0
138 stars 38 forks source link

NTBOOT with BCD parser #66

Closed a1ive closed 4 years ago

a1ive commented 4 years ago

Usage: ntboot [--v|-w|-n|-r] [-p] [-e FILE] [-s FILE] [BCD_OPTIONS] FILE -g, --gui Display graphical boot messages. -p, --pause Print debug messages and wait for key press. -e, --efi=FILE Set bootmgfw.efi path. -s, --sdi=FILE Set boot.sdi path. FILE TYPE: -w, --wim Boot WIM. -n, --win Boot Windows. -v, --vhd Boot VHD/VHDX. -r, --ramvhd Boot RamOS VHD. (not work) BCD OPTION: --testmode=yes|no Test mode (testsigning). --highest=yes|no Force highest resolution. --nx=OptIn|OptOut|AlwaysOff|AlwaysOn Nx policy. --pae=Default|Enable|Disable PAE policy. --detecthal=yes|no Detect HAL and kernel. --winpe=yes|no Boot into WinPE. --imgoffset=n Set Ramdisk image offset (RamOS VHD). --timeout=n Set timeout. --sos=yes|no ??? --novesa=yes|no Avoid VESA BIOS calls. --novga=yes|no Disable VGA modes. x86_64-efi.tar.gz

a1ive commented 4 years ago

The smallest possible size of boot.sdi https://docs.microsoft.com/en-us/previous-versions/windows/embedded/ms940108(v=winembedded.5)?redirectedfrom=MSDN

a1ive commented 4 years ago

SDI file format spec

Page as used in SDI file format is default i386 MMU page, 4096 bytes. All numeric values in SDI file are stored in little-endian 64-bit format. Empty (reserved) fields and space from a BLOB end to the beginning of next BLOB are padded with 0-s.

SDI file is not padded at the end, so total length of an SDI file equals to sum of aligned offset to last BLOB and exact (not aligned) length of that BLOB.

All BLOBs are aligned on boundary of alignment block. Size of alignment block is specified as multiple of page size. Size of SDI header alone is always 1 page, so if SDI consists of only a header, its length is exactly 4096 bytes regardless of alignment block size.

First sector (512 bytes, the header) is checksummed, as described in previous article http://skolk.livejournal.com/886.html For empty header with 1-page alignment the checksum value is 0x3A.

TOC begins at third sector (at 0x400 = 1K) (may be it can last until end of page ;-) )

Header format (offset 0)

char magic[4] (= '$SDI') char ver[4] (= '0001', you can define char magic[8] instead ) QWORD MDBtype 0 --- (Unspecified) 1 RAM 2 ROM

QWORD BootCodeOffset QWORD BootCodeSize Them are just copies of Offset and Size fields from the BOOT BLOB TOC record, if present. QWORD VendorID (16-bit HEX value, PCI SIG?) QWORD DeviceID (16-bit HEX value - what chip do you mean? Northbridge? Network?)

GUID DeviceModel QWORD DeviceRole (int32 value) QWORD Reserved1 GUID RuntimeGUID QWORD RuntimeOEMrev (int32 value) QWORD Reserved2 QWORD PageAlignment (BLOB alignment value in pages, as specified in /pack: ) QWORD Reserved3[48] (48=384/8; 384=0x80*3) QWORD Checksum

TOC (Table-of-Content) record format (record size 64 bytes (0x40) ), offset of first record 0x400

char BLOBtype[8] (3-4 bytes UPPERCASE value, 0-padded) QWORD Attr (uint32 value) QWORD Offset QWORD Size QWORD BaseAddress (0 for non-filesystem BLOBs, filesystem code for PART (as in MBR) - 7 for NTFS, 6 for BIGFAT, etc) QWORD Reserved[3]

end-of-TOC is just 0-record (may be detected by 0-blobtype)

known BLOB types: BOOT (startrom., you could use server' hdlscom?. for debug) LOAD (osloader.exe, bootmgr.exe for PE 2.0) You can unstub regular ntldr or setupldr.bin with oneliner from oss.netfarm.it

PART (Winimage .ima - just a filesystem, as old Linux initrd) DISK (image with a MBR, you could import flat-VHD or *-flat.vmdk) WIM (a new squashfs-style Windows Vista filesystem)

sdimgr /pack just needs to alphabetically sort BLOBs ('BOOT' < 'LOAD' < 'PART')

There are neither checksums for TOC and files (BLOB-s), nor sdimgr supports signing of SDI file.

You should not make BootCodeOffset point to non-aligned-boundary (for example to point into unused part of TOC in the first page), some loaders can depend on it!

I hope this info is enough to write your own open-source version of sdimgr :-)

a1ive commented 4 years ago

The System Deployment Image (SDI) file format is often used to allow the use of a virtual disk for startup or booting. Some versions of Microsoft Windows allow for "RAM booting", which is essentially the ability to load an SDI file into memory and then boot from it. The SDI file format also lends itself to network booting using the Preboot Execution Environment (PXE). Another usage is hard disk imaging. The SDI file itself is partitioned into the following sections:

Boot BLOB This contains the actual boot program, STARTROM.COM. This is analogous to the boot sector of a hard disk. Load BLOB This typically contains NTLDR and is launched by the boot BLOB. Part BLOB This contains the actual boot runtime (i.e. the contents of the disk image including any Operating System [OS] files) and also includes the boot.ini (used by NTLDR) and ntdetect.com files which should be located within the root directory of the runtime. The size of the runtime cannot exceed 500 MB. In addition to this requirement the runtime must also be capable of dealing with the fact that it is booting from a ramdisk. This implies that the runtime must include the "Windows RAM Disk Driver" component (specified within the boot.ini). Disk BLOB This is flat HDD image starting with a MBR. It is used for hard drive imaging instead of booting. Also only Disk BLOBs can be mounted with Microsoft's utilities. SDI usually contains either Disk BLOB (HD cloning or temporary SDI) or three other of them (bootable SDI).

Windows Vista or Windows PE 2.0 boot sequence includes a boot.sdi file, which contains Part BLOB for an empty NTFS volume and a Table-of-Contents slot for the WIM image, which is stored on a separate on-disk file.