Archived

This topic is now archived and is closed to further replies.

Wyrframe

Boot Record

Recommended Posts

Does anybody around here know where I can get information on... - Boot Record, Master Boot Record, et cetera - Low-level drive access (reading and writing disk images, modifying the boot record) - OS-less IO (monitor & keyboard only) Any help and pointers are much appreciated!

Share this post


Link to post
Share on other sites
*bump*

So, after such a long time, I''ve dug this up again. I tried google, as LessBread suggested, but can only find those "Filesystems for the Illiterate" (and I don''t mean just computer-illiterate) explanations... y''know, the ones that say "Files are really just entries in a table that the computer manages", but in much simpler language than that, and never go any deeper.

I was hoping to get info on standard formats of boot records, how the BIOS determines if a disk is "bootable" or not, and how I would go about low-level disk access.

Any help is much appreciated...

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
try this
http://www.nondot.org/sabre/os/articles
theres lots there, i made an entire os from the stuff there for my windtunel i made

-Ian

Share this post


Link to post
Share on other sites
ok if u want low-level disk acces there are many ways to do it:

1 - int 0x13 -> slow but has some interesting functions (a description of this can be found by googleing)
2 - i think in int 0x21 - DOS services there are some functions for this as well as higher level stuff (files)

1 and 2 are quite slow coz they go through BIOS

3 - using hard drive ports: the HDD has a couple of IO ports to receive commands and output data. i found on the net some functions to use these (in assembly of course) (these should be lightning fast) ( google for "direct hard drive acces" or "hard drive ports" + variations , i would have posted the code but it's on my old hard drive which is kaput )

about the BootRecord:

the BootRecord is the first physical sector on the HDD. it contains 2 things: OS (of boot manager) loading code and the partition table (the last 66 bytes). the partition table has 4 entries (in DOS only 4 partions are allowed (logical drives are not treated as partitions))
u can get a description of the partition table on google also



ok about screen IO -> segment 0xB800 and 0xA000 should ring a bell (text and video)
in textmode each char has 2 bytes (1 - attribute, 2 - value)
and there are 80 x 25 chars on screen -> 4000 bytes
in graphics mode it depends on the video mode

keyboard input can be handled by interrupt (hook int 0x09) or by the keyboard IO port whose value i dont remember)

i'll dig more stuff out of my mind and tell u mode




[edited by - Ilici on May 20, 2003 6:30:41 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Ilici
2 - i think in int 0x21 - DOS services there are some functions for this as well as higher level stuff (files)



If you start You app from MBR there is no service at int 0x21h
this services are supported only, and only by MS-DOS.

quote:
Original post by Ilici
3 - using hard drive ports: the HDD has a couple of IO ports to receive commands and output data. i found on the net some functions to use these (in assembly of course) (these should be lightning fast)

No way, You can not jump the overload of HDD. Time nedded to execute assembly code for HDD data access is only very, very small % of time that HDD need to get correct speed and find corect sector.





[edited by - Estor on May 20, 2003 6:42:58 AM]

Share this post


Link to post
Share on other sites
This reply is long (6 pages ) so if ur on dial up disconnect and read it coz it will take u some time.

BootSector:

As I said, the master boot sector (physical sector 0) is the key to the hard-drives operation. (if u delete it u can lose all ur data).
It contains 2 things: OS or Bootloader loading code and the PartitionTable;
- the loading code looks at the partition table to determine the active partition, loads the boot code of that partition into memory and jumps to it. (usually bootloader install here so they have acces to every partition).
The loading code of the boot sector on a partition with an OS does this: go the the root directory. Scan for some file to load (usually the kernel). Load it and jump to it. Usually the boot sector is just one sector, but Windows uses 3 :O which is kinda strange.

- The PartitionTable – 64 (or 66 (not sure) I think the last two are boot signature 0xAA55) bytes. It contains 4 entries of info ((start and end (head, cyl, sector) or LBA sector) for each partition (primary or ext) – it does not contain info about logical drives.

Reading and writing to the MBR:
- u can do this with int 0x13 – specify drive 0x80 (HDD 0), sector 1, cyl 0, head 0;
- to uninstall a bootloader -> read the MBR of the drive, read the MBR of a drive with the OS u want to keep, bake a MBR with the loading code of the drive with the OS and the PartitionTable of ur drive and write it back (quite dangerous if u don’t know what ur doing)

DirectHDD Access:

As I said there are some BIOS functions through in 0x13 and int 0x25 + 0x26 (not sure what these are) and int 0x21.
DOS functions use int 0x13 so it’s pretty much the same thing.

To do things the fast way:
The AT standard uses I/O port addresses 1f0-1f8 for the HDD. Heres the info for these ports:

; Technical Information on the ports:
; Port Read/Write Misc
; ------ ------------ -------------------------------------------------
; 1f0 r/w data register, the bytes are written/read here
; 1f1 r error register (look these values up yourself)
; 1f2 r/w sector count, how many sectors to read/write
; 1f3 r/w sector number, the actual sector wanted
; 1f4 r/w cylinder low, cylinders is 0-1024
; 1f5 r/w cylinder high, this makes up the rest of the 1024
; 1f6 r/w drive/head
; bit 7 = 1
; bit 6 = 0
; bit 5 = 1
; bit 4 = 0 drive 0 select
; = 1 drive 1 select
; bit 3-0 head select bits
; 1f7 r status register
; bit 7 = 1 controller is executing a command
; bit 6 = 1 drive is ready
; bit 5 = 1 write fault
; bit 4 = 1 seek complete
; bit 3 = 1 sector buffer requires servicing
; bit 2 = 1 disk data read corrected
; bit 1 = 1 index - set to 1 each revolution
; bit 0 = 1 previous command ended in an error
; 1f7 w command register
; commands:
; 50h format track
; 20h read sectors with retry
; 21h read sectors without retry
; 22h read long with retry
; 23h read long without retry
; 30h write sectors with retry
; 31h write sectors without retry
; 32h write long with retry
; 33h write long without retry

I’ll upload some code on my domain with asm functions to use HDD ports if ur interested. Using this ports is very very fast -> u’ll get the full read/write capacity of the drive.


About Screen output:

- the video card uses two memory ranges for the screen buffer: 0xB800 (text mode) and 0xA000(graphics mode). In normal text mode (mode 0x07) the screen has 80x25 characters (two bytes each (attribute + value) ). To write to the frame buffer, just set the bytes at some offset in the framebuffer:

For a color adapter the attribute byte is as shown,
Bit Color Ground

07 Blink ----------
06 Red Background
05 Green --- do ---
04 Blue --- do ---
03 Bright ----------
02 Red Foreground
01 Green --- do ---
00 Blue --- do ---

if there are more than 1 pages supported u’ll have to write to the active page. (usually only one page is used (page 0) )

Offset = page * pagesize + 2 * Y * maxcolumns + 2 * X
Segment= 0xB800 for color adapter or 0xB000 for monochrome
Here,
Pagesize is 2,048 for 40-column modes or 4,096 for 80-column.
Maxcolumn can be 40 or 80.


Heres my routine for writing a string to the screen:


  
void printf(const char *s)
{
unsigned i=0;
unsigned char c;

asm {
mov ax, textvid; // textvid = 0xB800;

mov es, ax;
}

while (s[i]!=0)
{
c=s[i];
switch (c) {
case 0x0A: {
if (cursory<24) gotoxy(0, cursory+1);
else {
gotoxy(0,0);
delline();
gotoxy(0, 24);
}
break;
}
case 0x09: {
gotoxy(cursorx+4, cursory);
}
case 0x08: {
if (cursorx==0)
{
if (cursory!=0) gotoxy(79, cursory-1);
}
else gotoxy(cursorx-1, cursory);
break;
}
default: {
asm {
mov ah, atr;
mov al, c;
mov bx, pos;
mov es:[bx], ax;
}
if (cursorx==79)
{
if (cursory==24)
{
gotoxy(0,0);
delline();
gotoxy(0,24);
}
else gotoxy(0, cursory+1);
}
else gotoxy(cursorx+1, cursory);
break;
}
}
i++;
}
}


also very usefull is a gotoxy routine (to move the blinking cursor). This is done using the video cards registers.

  
void gotoxy(unsigned char x, unsigned char y)
{
unsigned char at;

cursorx=x;
cursory=y;

pos=cursory*80+cursorx;

asm {
mov dx, 0x03D4;
mov al, 0x0E;
out dx, al;

mov ax, pos;
mov dx, 0x03D5;
mov al, ah;
out dx, al;

mov dx, 0x03D4;
mov al, 0x0F;
out dx, al;

mov ax, pos;
mov dx, 0x03D5;
out dx, al;
}
pos=(cupage*pagesize)+(cursory*80+cursorx)*2;
}


Keyboard Input:

Heres smth I got form an internet source long time ago:
So, how do we set about doing this? Well, to begin with, you need to know what happens AS SOON as a key is pressed on the keyboard. If you press the key ''A'' on your keyboard the 8031 controller inside the keyboard sends a KScan code value of 1Ch over the keyboard serial link. The 8042 controller on the motherboard receives the value and translates it into the system scan code value 1Eh. This value is then placed in its output buffer. The motherboard controller then issues an interrupt request indicating that data is available. The interrupt request calls the interrupt 9 handler, the keyboard BIOS and the scan code is further converted into it''s ASCII counterpart, 61h. Note that this is the code for ''a'', the lowercase value - this is because we are assuming that no shift key is being pressed at the same time. What happens after this is not important to us as we want to perform our own actions.

But hang on, don''t we want to detect a key release too? Well, yes, but the actions taken by the keyboard are not much different. Instead of sending the KScan code of ''A'', 1Ch over the serial link, it will this time send the release code F0h, followed then by 1Ch. The 8042 receives the two bytes and translates them to 1Eh like above, but this time, it sets bit 7 high to indicate that the key was released. So this time, the system scan code will be 9Eh.

Here are some help functions:

  
unsigned checkkeys()
{
unsigned char key;
asm {
in al, 0x60;
mov key, al;
// mov al, 0x20;

// out 0x20, al;

}
if (key & 0x80) {
keys[key-0x80]=1;
}
else {
keys[key-0x80]=0;
}
return key;
}

void getch()
{
asm {
mov ah, 0x00;
int 0x16;
}
}



the codes the keyboard sends are the same as DirectInput uses so u’ll find them in dinput.h.

If u have any more questions about this stuff ask me and I’ll dig up what I can find.


Estor: yes of course if u write a kernel that boots u wont have int 0x21 but i assume that is not what wyrframe wants

and using the ports is much faster becasue going through bios is slow. the HDD will do things at the same speed.

Share this post


Link to post
Share on other sites
Question: Will Windows allow You to access directly to HDD ports. Windows 98 i think will, but Windows XP will scream about IO protection about XP Im sure it will.

Share this post


Link to post
Share on other sites
HelpPC is a pretty good reference for BIOS interrupts, hardware IO port information, and other related stuff. (Google, and you may find the original HelpPC, which was a DOS program).
EDIT: The original HelpPC (a DOS program) is linked from the site above.

[edited by - Dactylos on May 20, 2003 8:24:06 AM]

Share this post


Link to post
Share on other sites