Code: Select all
E_INVALID_GPT: db 'GPT error.',0
E_INVALID_MBR: db 'MBR error.',0
E_DISK_ERROR: db 'Disk error.',0
E_REBOOT: db ' Please reboot your computer.',0
Code: Select all
E_INVALID_GPT: db 'GPT error.',0
E_INVALID_MBR: db 'MBR error.',0
E_DISK_ERROR: db 'Disk error.',0
E_REBOOT: db ' Please reboot your computer.',0
Code: Select all
; Public Domain Master Boot Record
ORG 0x0600
; Code start at physical address 0x00007C00. The exact CS and IP
; values are unknown. Register dl contains the boot drive number.
; Code runs in real mode and BIOS owns the hardware.
Addr_7C00: xor cx,cx ; cx = 0
mov si,0x7C00 ; si = source
mov di,0x0600 ; di = destination
cli ; disable interrupts
mov ss,cx ; ss = 0
mov sp,si ; sp = 0x7C00
sti ; enable interrupts
mov es,cx ; es = 0
mov ds,cx ; ds = 0
mov ch,0x01 ; cx = 0x0100
cld ; clear direction flag
rep movsw ; relocate 0x07C00 -> 0x00600 (512)
mov bx,0x55AA ; bx = 0x55AA (for INT 13h check)
push dx ; save register dx (dl=boot drive)
jmp 0x0000:Addr_0620 ; far jump to the relocated code
; Far jump sets cs = 0x0000 and ip = 0x0620
; ____________________________________________________________________________
Addr_0620: mov ah,0x41 ; INT 13h installation check
stc ; preset carry flag
int 0x13 ; bios disk service call
pop dx ; restore register dx (dl=boot drive)
jc ReadSecCHSInit ; if cf = 1, no INT 13h extensions
cmp bx,0xAA55 ; compare return value
jne ReadSecCHSInit ; if not equal, no INT 13h extensions
shr cx,1 ; check bit 0, function support
; Note: cx was set to zero before INT 13h call. If bit 0 was set,
; this gives very good confidence that INT 13h extensions are
; available. This also gives good confidence that the CPU is >= 80386.
jnc ReadSecCHSInit ; if bit 0 = 0, no INT 13h extensions
; jmp ReadSecLBAInit ; fall through to ReadSecLBAInit
; ____________________________________________________________________________
ReadSecLBAInit: ; NOT IMPLEMENTED
; ...
; ...
; ...
; ...
; Update "ReadSector" function pointer.
mov word [ReadSector],ReadSecLBA
jmp CheckPartTable ; jump to CheckPartTable
; ____________________________________________________________________________
ReadSecCHSInit: ; NOT IMPLEMENTED
; ...
; ...
; ...
; ...
; jmp CheckPartTable ; fall through to CheckPartTable
; ____________________________________________________________________________
CheckPartTable: ; NOT IMPLEMENTED
ReadSecCHS: ; NOT IMPLEMENTED
ReadSecLBA: ; NOT IMPLEMENTED
; By default, assume that INT 13h extensions are not available. This
; pointer will be changed if extensions are available.
align 2
ReadSector: dw (ReadSecCHS)
Yes - I'm partly (but not necessarily entirely) illustrating my previous "While "minimum required functionality" is trivial and relatively well defined; "maximum desired functionality" is a hornet's nest" comment.Antti wrote:That missing label will be fixed but the point was to underline this nice 32-byte aligned code section before jumping to the relocated code. It is pointless, I know, but if that code section would be used at the beginning of millions of storage drives, why not made it like a "signature boilerplate".
Brendan, you are right but I doubt I/we are able to finish this if we extend the scope too much. I think it could be realistic to make this 512-byte fully polished and bug-free.
For GPT, I'd want the boot manager to have its own partition (that isn't a UEFI system partition and isn't FAT).Antti wrote:Using the first track is possible but I would like to reserve it for GUID partition tables. The primary GPT header is at LBA 1, so it is the next sector.
Imagine a user sends you a bug report that says "Disk error" and nothing else. After wondering how the user managed to send the bug report when their only computer doesn't boot, do you:Antti wrote:How many error messages there should be? Not too many because there is no space. Of course, strings should be "compressed". No need to have "errors" duplicated three times. Beeping PC speaker would be nice.
Code: Select all
E_INVALID_GPT: db 'GPT error.',0 E_INVALID_MBR: db 'MBR error.',0 E_DISK_ERROR: db 'Disk error.',0 E_REBOOT: db ' Please reboot your computer.',0
Absolutely true. I have to think about this. In hindsight, those error messages I suggested are so bad that it feels bad. It is impossible to have that much functionality and have acceptable error handling procedures.Brendan wrote:The only way around that is to shift functionality elsewhere, so that the first sector contains very little functionality and requires much less error handling.
But how it can load something from an active partition without checking partition table?Brendan wrote:GRUB's MBR ignores the partition table and loads GRUB's stage 2; it doesn't check the partition table and load the first sector of an active partition (which I assume is the goal here).
May be it is better to say that the project is paused for some short time?Antti wrote:There is so much controversy that this project probably does not make sense. Actually, the project goal makes sense in itself but there are too many things to take into consideration. Maybe it is better to leave the MBR as a part of the real boot manager. The project is halted for now.
Antti wrote: The conclusion:
- Worldwide acceptance? A nice dream.
- Boot Manager Partition? Probably a good idea.
- Standard interface between MBR and Boot Manager? A good idea.
- Same MBR code for "Legacy partitions" and "GUID partitions"? Maybe a bad idea.
- Chain of trust? An unknown area.
Nothing in GRUB's MBR (at least, the version linked to earlier) checks or cares about the partition table - it just loads "stage 2" starting from the sector indicated in a fixed location in the MBR (that I'd assume must be set by whatever utility installed GRUB). I'd also assume something in that "stage 2" does check/use the partition table.embryo wrote:But how it can load something from an active partition without checking partition table?Brendan wrote:GRUB's MBR ignores the partition table and loads GRUB's stage 2; it doesn't check the partition table and load the first sector of an active partition (which I assume is the goal here).
The basic idea is reasonably simple - create a hash of the kernel so that other systems can determine if the kernel/OS has been compromised by malicious software (more specifically, to allow "remote attestation").embryo wrote:Antti wrote:For me it's also something still undefined. But may be I even know it, but with some different name.[/list]
- Chain of trust? An unknown area.
It is in a halt state but external interrupts will resume execution. I would compose the instructions if I knew how it should work. Besides, maybe this project is ten years too late. What if the MBR just printed the message: "Please use UEFI-compatible hardware."embryo wrote:May be it is better to say that the project is paused for some short time?
May be it just relies on the fact, that 99% of MBRs have the first partition as active and, because of partition table structure, the location of the disk offset is always placed at the only address within the MBR? And yes, it's error prone, but in 99% of cases it works and GRUB developers just don't pay attention to the missed 1%.Brendan wrote:Nothing in GRUB's MBR (at least, the version linked to earlier) checks or cares about the partition table - it just loads "stage 2" starting from the sector indicated in a fixed location in the MBR (that I'd assume must be set by whatever utility installed GRUB).
I see it looks like certificate chain, when every certificate is signed by the previous in the chain until the root certificate.Brendan wrote:The basic idea is reasonably simple - create a hash of the kernel so that other systems can determine if the kernel/OS has been compromised by malicious software (more specifically, to allow "remote attestation").
If a user incidentally (just to try it) inserts some untrusted USB key and boots from it, then everything in the trust chain is useless. It's also the case when some stranger is able to insert the same USB stick and boot from it.Brendan wrote:The problem is that malicious code in a boot loader can do "something" (e.g. install a temporary IRQ handler) that corrupts the kernel after the hash has been created. To fix that you need to create a hash of the boot loader and then combine it with the kernel's hash in some way; so that other systems can determine if the boot loader or kernel/OS has been compromised by malicious software. However, the MBR/boot manager could corrupt the boot loader after the hash has been created, so...
Yes, I suppose it's better to include some hardware into the security package, than to relay on a software only. But still some unauthorized access to the PC can break the wall. So, as a solution, I can suggest something like removable USB BIOS, which keeps the information about MBR, boot loader, kernel or whatever hashes and performs hash checks on every booting and can be kept secure just because it can be easily detached and carried with the owner. Also, if there is some OS's vulnerability, that was exploited and allowed to install some malicious software that had made changes in the kernel, even then the USB BIOS can detect the kernel's change and warn it's owner.Brendan wrote:Of course it's more complicated than that. For example, the hash needs to be stored somewhere secure (and not in normal RAM where anything can modify it) and you also have to protect the code used to create the hash. This is mostly what the TPM chip provides.
It means you still have no clear picture of the booting process. But here is the place, where everybody can ask an clarify his vision of anything OS-related.Antti wrote:I would compose the instructions if I knew how it should work.
It's too easy to keep old (BIOS related) parts of legacy OSes instead of just rejecting to boot from MBR on a PC, that was built, for example, 5 years ago. So, I suppose such message will be actual somewhere in 2030-s or even later.Antti wrote:Besides, maybe this project is ten years too late. What if the MBR just printed the message: "Please use UEFI-compatible hardware."
If there is a valid protective MBR, there is only one legacy partition covering the whole disk starting from LBA 1. It is undefined, but allowed, to set the "bootable" flag. Of course, the partition starts with bytes "EFI PART", so it is not really very bootable. If it is not marked as bootable, then the BIOS may check that there are no bootable partitions and it may not load the MBR at all. Marking it as bootable and trusting that there are no BIOS versions skipping the MBR and loading LBA 1 even if there is a "non-FAT filesystem" may guarantee that on every computer the MBR code section gets jumped into.UEFI wrote:5.2.3 Protective MBR
...
A Protective MBR may be located at LBA 0...
...
5.3.1 GPT overview
...
LBA 0 (i.e., the first logical block) contains a protective MBR...
...
There are such words:Antti wrote:I have carefully read the latest UEFI specification (Section 5, GUID Partition Table). I am not sure whether it is allowed to have the GPT layout without a protective MBR.UEFI wrote:5.2.3 Protective MBR
...
A Protective MBR may be located at LBA 0...
...
5.3.1 GPT overview
...
LBA 0 (i.e., the first logical block) contains a protective MBR...
...
So, in case of the legacy booting there should be a legacy MBR. And in case of the UEFI booting there should be a protective MBR. The word "may" is correctly used to show us that there are some variants possible. And, obviously, a writer had assumed that we are acknowledged about the variants.UEFI wrote:5.2.1 Legacy Master Boot Record (MBR)
A legacy MBR may be located at LBA 0 (i.e., the first logical block) of the disk if it is not using the
GPT disk layout (i.e., if it is using the MBR disk layout). The boot code on the MBR is not executed
by UEFI firmware
If it is a UEFI system then the BIOS should be aware of the situation and play with it correctly. And if it is a legacy system, then the BIOS just loads the first sector and starts it's code. In fact it is complicated by some checks some BIOSes can perform, but generally the main principle is always the same - BIOS should work correctly with the MBR's data if the data follows some standards the BIOS expects.Antti wrote:If it is not marked as bootable, then the BIOS may check that there are no bootable partitions and it may not load the MBR at all.
In case if you want to write your own bootloader instead of the whole UEFI thing the situation can be even more complicated. There should be an information about how exactly the UEFI handles the situation when the MBR is replaced with a legacy one. I suppose the information can be found after careful reading of the chapter 3 of the UEFI specification where UEFI firmware boot manager is described, but I haven't done this yet. At least the specification states that:Antti wrote:Marking it as bootable and trusting that there are no BIOS versions skipping the MBR and loading LBA 1 even if there is a "non-FAT filesystem" may guarantee that on every computer the MBR code section gets jumped into.
But where in the specification the information about legacy booting is located I just don't know. May be it is even a part of a particular BIOS implementation.UEFI wrote:1.7 Migration Requirements
Migration requirements cover the transition periodfrom initial implementation of this specification
to a future time when all platforms and operating systems implement to this specification. During
this period, two major compatibility considerations are important:
• The ability to continue booting legacy operating systems