Is there a way through code to know a hard disk location?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Braceq
Posts: 9
Joined: Wed Apr 04, 2012 10:13 pm

Is there a way through code to know a hard disk location?

Post by Braceq »

As I wrote on other forums (but never been able to solve), I've been trying to read the first 512 bytes of my hard disk and print them to the screen for more than 1 year, but failed in every single attempt. I'm trying to make a single phase boot loader. Its been so much time trying but I really want to do this :cry: , that's why I haven't given up. I have already backed up my MBR and a couple of other sectors so no need to tell me something is dangerous since I'm pretty secured.

In order to know whether I had been reading the hard disk correctly (to then continue with the rest of the boot loader) I tried to read the first 512 bytes of it and print them to the screen, just to know I was doing things correctly. Never been successful. All I find is how to read floppies, but I'm testing in my real computer (which doesn't have a floppy drive and I wonder which computer today has one) by booting from a flash drive. Here is my current code:

Code: Select all

#make_boot#

org 7c00h      ; set location counter.

Buffer DW 512  ;This will contain the read sector
MOV CX, 5      ;Read counter

read_loop:
    XOR AH, AH      ;Reset drive function
    INT 13H         ;Reset Drive
    
    MOV AX, DS
    MOV ES, AX
    MOV BX, Buffer
    MOV DL, 80h     ;Hard disk number identifier
    MOV DH, 0       ;Head 0
    MOV AL, 1       ;Read 1 sector
    MOV CH, 1       ;Cylinder 1
    MOV CL, 0       ;Start from sector 0
    
    MOV AH, 2H       ;Set function 2H
    INT 13H          ;Read

    JNC DisplayData  ;If carry flag is 0, it worked
    loop read_loop ; try 5 times


DisplayData:

    LEA SI, Buffer
    MOV AH, 0EH     ;Function 0EH
    
    Print:
    MOV AL, [SI]    ;Store on AL what is on SI (Buffer)
    CMP AL, 0       ;Check if we have reached the end of our 512 bytes data
    JZ  Exit        ;If yes, jump to the end
    INT 10H         ;Else print current character
    INC SI          ;Move forward to next character
    JMP Print:     


Exit:

    MOV AH, 0H       ;Function 0H
    INT 16H          ;Wait for any key...
 

INT 19h        ; reboot
My questions are:
1) Suppose I'm reading everything correctly, how do I display what is stored on BX?
2) Is there a way to enumerate the location of hard disks? For example something that tells me through code there is a device on 80h or on 81h. I need this because since I can't print any data to the screen I need to know if there is actually a hard disk to where I'm telling the program. Then I can know whether I'm reading something and my problem is printing to the screen or I'm not reading anything at all.
3) Also, this loop I have is not working, its not looping 5 times at all, but I'll deal with that later.

I have made countless tries and got rid of many other boot loaders because they did not worked. If anyone is sure to have a working code that reads from the first hard disk (not a floppy) it would great to see a segment of it, but any help is appreciated.

PS: I have even tried with the segment of read_sector of True Crypt boot loader, but nothing. They are missing DL register value (what contains the drive number) and I have no idea where they take that from. In the comments it says:

Code: Select all

; DL = drive number passed from BIOS
But that doesn't help at all.
AndrewBuckley
Member
Member
Posts: 95
Joined: Thu Jan 29, 2009 9:13 am

Re: Is there a way through code to know a hard disk location

Post by AndrewBuckley »

try stuffing ascii bytes to the frame buffer, debugging will be a pain if you have no way of seeing what your are doing.

-framebuffer starts at 0xb8000
-even numbers are the char value(ascii)
-odd numbers are the colors(char and background)
AndrewBuckley
Member
Member
Posts: 95
Joined: Thu Jan 29, 2009 9:13 am

Re: Is there a way through code to know a hard disk location

Post by AndrewBuckley »

and DL gives you the drive that you booted from, why is that not helpfull?
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Is there a way through code to know a hard disk location

Post by Solar »

Braceq wrote:In order to know whether I had been reading the hard disk correctly (to then continue with the rest of the boot loader) I tried to read the first 512 bytes of it and print them to the screen, just to know I was doing things correctly. Never been successful.
ATA in x86 RealMode (BIOS)
Printing to Screen
BIOS
Every good solution is obvious once you've found it.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Is there a way through code to know a hard disk location

Post by Combuster »

And try not to execute data first thing in your code - put it somewhere else with the correct size.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
Yoda
Member
Member
Posts: 255
Joined: Tue Mar 09, 2010 8:57 am
Location: Moscow, Russia

Re: Is there a way through code to know a hard disk location

Post by Yoda »

There are ready-to-use tools that can boot your kernel. If GRUB is too complicated, you may try this one: http://goncharov.pp.ru/en/osboot.htm
The archive contains boot codes, boot code installation program and tiny sample kernel that prints a couple of messages on the screen.
Yet Other Developer of Architecture.
OS Boot Tools.
Russian national OSDev forum.
User avatar
DavidCooper
Member
Member
Posts: 1150
Joined: Wed Oct 27, 2010 4:53 pm
Location: Scotland

Re: Is there a way through code to know a hard disk location

Post by DavidCooper »

Braceq wrote:As I wrote on other forums (but never been able to solve), I've been trying to read the first 512 bytes of my hard disk and print them to the screen for more than 1 year, but failed in every single attempt.
I can't not admire someone who hasn't given up after so much lack of success. It isn't immediately clear what you're trying to do, so can you clarify it so that everyone can see exactly what's what. Are you trying to boot this code from a USB flash drive in order to try to read from the internal hard drive of the computer and then to print its MBR to the screen?
MOV CX, 5 ;Read counter
Ask yourself if this will be preserved when you write to CH and CL below.
MOV AX, DS
MOV ES, AX
Are you sure you want to work with the value in DS? How do you know what it is? Set up your own segments so that you know exactly what's in them.
MOV DL, 80h ;Hard disk number identifier
Here you're preparing to read from the hard drive which I think you're correct in assuming will be on 80h (correct me, someone, if this isn't guaranteed), but you're doing it without storing the existing value for the USB flash drive you've just booted from, so you may have trouble finding it again when you want to use it later on.
MOV CH, 1 ;Cylinder 1
MOV CL, 0 ;Start from sector 0
Are you sure you want cylinder 1 rather than 0, and is there such a thing as sector 0 when using Int 13h with AH=2h?
LEA SI, Buffer
I've never worked out what LEA is for, but I'm hoping it does the same as a MOV here. Even so, I don't know where your buffer is. If it's where you stated it up at the top (I'm never sure how assembler works with things of this kind), that's going to be inside this boot sector, so it'll be written over this code while this code's trying to run, assuming that any of your code actually makes it into your boot sector at all. It would be better just to line up on an address directly for the data from disk to be written to and to load registers with the same direct address to access them, using numbers - stick it somewhere well out of the way such as at the 128K point (and set up a stack at 7C00 while you're at it).
Print:
MOV AL, [SI] ;Store on AL what is on SI (Buffer)
CMP AL, 0 ;Check if we have reached the end of our 512 bytes data
JZ Exit ;If yes, jump to the end
INT 10H ;Else print current character
INC SI ;Move forward to next character
JMP Print:
How do you know there's going to be a 0 at the end of the data? The memory could have anything in it, so you'd need to write a zero after the loaded sector first. Worse though, it will stop printing at the first 0 in the data that it reaches, so it's completely the wrong approach. Set up a count of 512 and stop when that count runs out.
My questions are:
1) Suppose I'm reading everything correctly, how do I display what is stored on BX?
Set ES to b800h and DI to 0, then move BL into AL and set AH to 12 (red colour) and post it to the screen with STOSW, then move BH into AL and use STOSW again. For a clearer view of the content of BX, convert it to hex first and print four bytes to the screen instead, but do it the simpler way first even though it's harder to interpret the result as it will make sure you've got the hang of printing directly to the screen.
2) Is there a way to enumerate the location of hard disks? For example something that tells me through code there is a device on 80h or on 81h. I need this because since I can't print any data to the screen I need to know if there is actually a hard disk to where I'm telling the program. Then I can know whether I'm reading something and my problem is printing to the screen or I'm not reading anything at all.
Your best bet is to look at the content of DL right at the start and store it - if it isn't 80h, the hard drive will almost certainly be 80h, but if DL is already 80h (I don't know if that ever happens), I'm guessing that you'd then find the hard drive at 81h, and if that failed you could then rewrite the code to try other values.

Edit:-

You also need the boot sig in the last two bytes of your boot sector, and that's AA55h.

Another thing to think about is where you've put your code on the flash drive. If it's written on top of the MBR it will pretend to be a floppy disk, and for all I know that might result in it being given the drive number 0h.
Help the people of Laos by liking - https://www.facebook.com/TheSBInitiative/?ref=py_c

MSB-OS: http://www.magicschoolbook.com/computing/os-project - direct machine code programming
Braceq
Posts: 9
Joined: Wed Apr 04, 2012 10:13 pm

Re: Is there a way through code to know a hard disk location

Post by Braceq »

:D I think I have it working!!!! I copied 5 lines of the True Crypt boot loader and I'm getting a carry flag of 0 after executing INT 13H. I'll be back with the details after I have some sleep since its 3:18 AM and I'm really tired. I will also answer the questions you have asked me :wink: . Thank you all for your active support. The links helped a lot too. I hope the carry flag being 0 right after executing the int 13h is really meaning success [-o< . Be back soon...
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Is there a way through code to know a hard disk location

Post by Solar »

Speaking so strangely why are you? :twisted:
Every good solution is obvious once you've found it.
rdos
Member
Member
Posts: 3307
Joined: Wed Oct 01, 2008 1:55 pm

Re: Is there a way through code to know a hard disk location

Post by rdos »

berkus wrote:Assume shall you not. Documentation read you must.
An OS developer with that approach will never get anywhere. Most hardware/software is not properly documented. :roll:
rdos
Member
Member
Posts: 3307
Joined: Wed Oct 01, 2008 1:55 pm

Re: Is there a way through code to know a hard disk location

Post by rdos »

BIOS disk IO only adheres to M$ practises, and the only thing one can be fairly certain about is that they obey those (largely undocumented) practises.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Is there a way through code to know a hard disk location

Post by Solar »

Underdocumented, INT 0x13 is not. If documentation available is, relying on trial & error, folly is. Your claims, no purpose they serve here.
Every good solution is obvious once you've found it.
rdos
Member
Member
Posts: 3307
Joined: Wed Oct 01, 2008 1:55 pm

Re: Is there a way through code to know a hard disk location

Post by rdos »

I happen to own a copy of IBMs BIOS manual that is roughly 15-20 years old, but it documents none of the strangeness that were invented (because of M$) after that point of time.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Is there a way through code to know a hard disk location

Post by Solar »

Your post #1: "Don't look up documentation, it's bad as most things aren't in there."

Your post #2: "Microsoft added stuff and BIOS documentation doesn't include that."

Your post #3: "My BIOS documentation - which is 15+ years old - doesn't cover the things Microsoft added."

Our point: Use (up-to-date) documentation, and do look things up when in doubt.

Your point: ...?
Every good solution is obvious once you've found it.
rdos
Member
Member
Posts: 3307
Joined: Wed Oct 01, 2008 1:55 pm

Re: Is there a way through code to know a hard disk location

Post by rdos »

Solar is on my ignore list..
Post Reply