Is there any BIOS call that can be used in order to obtain the BIOS' boot sequence? The origin of this question was me trying to install Windows 7 on a very old Pentium III machine, where the installer kept insisting that "The computer's hardware may not support booting to this disk", in spite of the 1st HDD being set as the first boot device.
The only mention of programatically getting the boot sequence that I could find was in the DOS API reference, where int 21/AX=3305h in DOS 4.0+ is defined as "Get Boot Drive", with the dl register set on return to the drive the OS was booted from, 1 meaning A: and so on. However, it is obviously very doubtful that this call is used by the Windows 7 installer.
There is no (standard) BIOS call for obtaining the boot sequence, and as you say, DOS calls aren't relevant to Windows. However, it doesn't really matter in the case you're considering, because by convention only one hard drive (drive 0) is bootable.
Some BIOSes do allow you to select a particular hard drive as the boot drive. They do this by rearranging the drive order at boot time so that the selected drive is drive 0.
The warning message you describe was probably due to the size of the hard disk drive. Some older BIOSes can't boot to larger drives, and since the Windows installer had no way to tell whether your machine was one of the exceptions, it gave you the warning. (There are various other similar possibilities, such as the hard drive type.)
Assuming it did in fact boot, you don't really need to worry about it. :-)
Related
I am creating an operating system, and am able to create a simple multitasking kernel (though the code has been lost) and an IDE/ATA PIO driver without BIOS interrupts. I wish to create a boot loader that puts the system into Protected Mode, disables paging, creates a flat memory model, and then does a long jump to the 0x0 offset of a file named OS.SYS in the root directory of a FAT32 formatted hard drive. I know how do do everything except for one thing: change the boot sector of the disk. I know how to format a hard drive as FAT32 to get the correct BPB and such at the beginning of the file, but I do not know how to copy over the code so that the BPB is not corrupted. Even in Linux when DD was available, I was unable to overcome this hurdle - I always used a custom file system. I am now seeing the disadvantages to this, though, such as not being able to use simple tools like file managers to move files around for testing.
Basically, to sum it up, I'm asking how to change the boot sector code on an already working FAT32 file system without messing up the BPB.
Note: I am using Windows 10 and NASM, and intend to use virtual hard disks with QEMU or Virtualbox.
I'm using Borland C++ Builder for a project which connects to a database.
There is a configuration which does backups to a USB drive. The problem with the current approach is that the drive is manually configured by the end user and sometimes things get messed up. E.g. People move the USB drive to a different port, get a different letter and then the back up process no longer works. As a side note, we have other "better" processes for backing up to the cloud, etc., however some locations don't have internet access and aren't running on a RAID... so backing up to USB gives them a saving grace from a HD crash.
I'm hoping to do some coding to help remove this issue. I'm hoping to be able to get a handle to the OS (Windows 8/7/XP) and be able to identify the drives on the machine. Once I have those, I can then iterate through them and check for a path location (e.g. File marker, so if a the file exists, I know its the USB we supplied). Then once I have that, I can do the back up.
As a worse case scenario, I will be able to iterate through all 26 letters to test each drive. However I'm using this as a learning opportunity and hoping to get a handle to the OS so reduce the number of checks/fails I can run into. Besides, I'm curious if anyone has a better approach :)
I don't think there's much to be gained by trying to do something more advanced than iterating over the 26 drive letters.
Before attempting to check whether or not the marker path exists you could add a call to GetDriveType and compare the return value against DRIVE_REMOVABLE. This will make sure that your code doesn't spin up the CD/DVD drive, or hit the network in the case of a mapped share.
I've got a question for dos & win7 boot process.
Is it possible that dos boot and execute some dos-app before win7 boot without reboot?
I mean boot process like win95 or win3.1.
I'll explain more detail.
dos boot ->
execute some dos app ->
cleanup memory ->
load win7 volume boot record into memory 7c00 ->
win7 boot without reboot
Is this possible?
The scenario you have described is basically a warm reboot, interrupt 0x19 behaves almost like that, with the exception that it always loads the Master Boot Record (with the partition table). Win3.1 or Win95 were started as normal executables from DOS and not from their boot record. Win7 does not have any DOS phase during boot.
However, I think it's possible, but won't be easy. These are a few options:
The easiest solution would be if you can find an appropriate boot manager software that can do this for you. Take a look at GRUB and GRUB4DOS and this question.
If it is enough (the DOS program you want to run does not strictly require 16-bit DOS environment), I'm not sure, but maybe you can tweak Win7's boot.ini to boot in safe mode with command line and start it from there and then reboot.
In the worst case you must manually write a small DOS program that reads the Win7 boot sector to the address 0000:7C00 and executes it. For this to work you must now exactly where the Win7 boot sector is located in the disk. Be aware that on hardware that supports it, Win7 will prefer EFI boot method instead of the old MBR-based one. You must check what method your Win7 installation uses. There may be other difficulties like how to select active partition or that the DOS partition must reside in the beginning of the disk, and so on.
I'm need to find a method to programmatically determine which disk drive Windows is using to boot. In other words, I need a way from Windows to determine which drive the BIOS is using to boot the whole system.
Does Windows expose an interface to discover this? With how big the Windows API is, I'm hoping there is something buried in there that might do the trick.
Terry
p.s. Just reading the first sectors of the hard disk isn't reveling anything. On my dev box I have two hard disks, and when I look at the contents of the first couple of sectors on either of the hard disks I have a standard boiler plate MBR.
Edit to clarify a few things.
The way I want to identify the device is with a string which will identify a physical disk drive (as opposed to a logical disk drive). Physical disk drives are of the form "\\.\PHYSICALDRIVEx" where x is a number. On the other hand, a logical drive is identified by a string of the form, "\\.\x" where x is a drive letter.
Edit to discuss a few of the ideas that were thrown out.
Knowing which logical volume Windows used to boot doesn't help me here. Here is the reason. Assume that C: is using a mirrored RAID setup. Now, that means we have at least two physical drives. Now, I get the mapping from Logical Drive to Physical Drive and I discover that there are two physical drives used by that volume. Which one did Windows use to boot? Of course, this is assuming that the physical drive Windows used to boot is the same physical drive that contains the MBR.
Go into Control Panel
System and Security
Administrative Tools
Launch the System Configuration tool
If you have multiple copies of Windows installed, the one you are booted with will be named such as:
Windows 7 (F:\Windows)
Windows 7 (C:\Windows) : Current OS, Default OS
Unless C: is not the drive that windows booted from.Parse the %SystemRoot% variable, it contains the location of the windows folder (i.e. c:\windows).
You can use WMI to figure this out. The Win32_BootConfiguration class will tell you both the logical drive and the physical device from which Windows boots. Specifically, the Caption property will tell you which device you're booting from.
For example, in powershell, just type gwmi Win32_BootConfiguration to get your answer.
That depends on your definition of which disk drive Windows used to boot. I can think of 3 different answers on a standard BIOS system (who knows what an EFI system does):
The drive that contains the active MBR
The active partition, with NTLDR (the system partition)
The partition with Windows on it (the boot partition)
2 and 3 should be easy to find - I'm not so sure about 1. Though you can raw disk read to find an MBR, that doesn't mean it's the BIOS boot device this time or even next time (you could have multiple disks with MBRs).
You really can't even be sure that the PC was started from a hard drive - it's perfectly possible to boot Windows from a floppy. In that case, both 1 and 2 would technically be a floppy disk, though 3 would remain C:\Windows.
You might need to be a bit more specific in your requirements or goals.
You type diskpart, list disk and check disks for boot.
Ex:
dispart
list disk
select disk 0
detail disk
The disk with Boot volume is disk with windows installed:
There is no boot.ini on a machine with just Vista installed.
How do you want to identify the drive/partition: by the windows drive letter it is mapped to (eg. c:\, d:) or by how its hardware signature (which bus, etc).
For the simple case check out GetSystemDirectory
Try HKEY_LOCAL_MACHINE\SYSTEM\Setup\SystemPartition
You can try use simple command line. bcdedit is what you need, just run cmd as administrator and type bcdedit or bcdedit \v, this doesn't work on XP, but hope it is not an issue.
Anyway for XP you can take a look into boot.ini file.
a simpler way
search downloads in the start menu and click on downloads in the search results to see where it will take you the drive will be highlighted in the explorer.
On Windows 10.
Open "Computer Management"
Look for "Storage" in list "left top side of page"
select "Disk Management"
On section of page showing the list of disks and the partitions find the disk that has the partition assigned as drive C:
On that disk containing C: partition
Use the right mouse button to select the Square section containing The Disk Number, Type of drive and size in GB . When menu opens select the Properties.
A window will open showing what drive hardware was used.
I need to modify the MBR of Windows, and I would really like to do this from Windows.
Here are my questions. I know that I can get a handle on a physical device with a call to CreateFile. Will the MBR always be on \\.\PHYSICALDRIVE0? Also, I'm still learning the Windows API to read directly from the disk. Is readabsolutesectors and writeabsolutesectdors the two functions I'm going to need to use to read/write to the disk sectors which contain the MBR?
Edit from from what I've learned on my own.
The MBR will not always be on \\.\PHYSICALDRIVE0. Also, you can write to the bootsector (at least as Administrator on XP) by call CreateFile with the device name of the drive that contains the MBR. Also, you can write to this drive by simply calling WriteFile and passing the handle of the device created by calling CreateFile.
Edit to address Joel Coehoorn.
I need to edit the MBR because I'm working on a project that needs to modify hardware registers after POST in BIOS, but before Windows will be allowed to boot. Our plan is to make these changes by modifying the bootloader to execute our code before Windows boots up.
Edit for Cd-MaN.
Thanks for the info. There isn't anything in your answer, though, that I didn't know and your answer doesn't address my question. The registry in particular absolutely will not do what we need for multiple reasons. The big reason being that Windows is the highest layer among multiple software layers that will be running with our product. These changes need to occur even before the lower levels run, and so the registry won't work.
P.S. for Cd-MaN.
As I understand it, the information you give isn't quite correct. For Vista, I think you can write to a volume if the sectors being written to are boot sectors. See http://support.microsoft.com/kb/942448
Once the OS is started the MBR is typically protected for virus reasons - this is one of the oldest virus tricks in the books - goes back to passing viruses from floppy to floppy.
Even if it wasn't restricted, you have to write low level code - it isn't part of the file system, but exists on a specific location on the hard drive.
Due to that, you pretty much are restricted to writing low level (most programs implement this in assembly) or C code targeting 16 bit DOS.
Most of these programs use the BIOS interface (13h, I believe) to access the sectors of the disk directly. You can access these in C using some inline assembly, or compiler provided interfaces. You will generally not get access to BIOS without the cooperation of the OS, though, so your program, again, will be restricted to DOS. If you can access these you're almost home free - the nice thing about BIOS is you don't have to worry about what type of HD is in the system - even RAID cards often insert themselves into the BIOS routines so they can be accessed without knowing where in memory the ATA or SATA controller is, and executing commands on that low level.
If you absolutely must access it within an OS, though, you pretty much have to write a device driver to access the BIOS or the memory space where the HD controllers exist. I wouldn't recommend it, though, as this is very tricky to deal with - modern computers put the HD controllers in different spots in memory, with different IRQs, and each chipset has become a little more esoteric because they can provide a minimum interface to bios for bootup, and then a specific driver for Windows. They skip all the other interface niceties that would be considered compatible with other controllers because it's more expensive to be compatible.
You may find that at the driver level inside windows you'll have methods for accessing the drive sectors directly (or pseudo directly), but again, they are likely very well protected due to the aforementioned virus issues.
Good luck!
Modifying the bootloader is bad, bad idea. Here are just a few of the possible gotcha's:
it will potentially kill full disk encryption products (Truecrypt, PGP, Vista's BitLocker, etc)
it will potentially trip up AV products (scaring users)
it will potentially kill complicated booting scenarios (chained boot loaders, etc)
it will kill off the chain of trust when using the TPM module (because it checks the MBR for change before executing it)
direct disk access is not allowed starting from Vista (only using drivers)
Alternatives (like modifying the hardware register during the Windows bootup via a driver which is set to load at boot time or after Windows has booted) should really be considered. If the modification is as simple as writing to a port, ie:
OUT AX, BL
then drivers exists for all versions of Window which can do this (reading/writing a value from/to a certain port) which can be called from user mode.
Maybe a PXE boot scenario could help you? Simply boot on your crafted PXE image which modify the hardware registers you need to modify, and then return the control to the Master Boot Record or to the active partition's boot record.
This way you don't have to modify the boot records.