flat assembler
Message board for the users of flat assembler.

Index > OS Construction > [SOLVED] I/O LBA28 jump to loaded code clarification

Author
Thread Post new topic Reply to topic
binary



Joined: 10 Oct 2009
Posts: 29
binary 27 Nov 2010, 19:18
I'm trying to make a HDD driver for unreal mode using I/O ports for LBA28
and I don't know how to make the jump to the loaded code.

Where I found the code , gives very little explanation how to make the jump

I have this code:


Code:
mov     dx,1f6h
mov     al,0a0h
out     dx,al

mov     dx,0x1F1
mov     al,0h
out     dx,al

mov     dx,1f2h
mov     al,1            ;number of sectors to read
out     dx,al

mov     dx,1f3h
mov     al,1    ; first address part
out     dx,al

mov     dx,1f4h
mov     al,0     ; 2nd address part
out     dx,al

mov     dx,1f5h     ;3rd address part
mov     al,0
out     dx,al

mov     dx,1f7h
mov     al,20h          ;read command
out     dx,al


 ; I don't know what this does , probably waits for the read process to be finished
w: 
  in      al,dx
  test    al,8
jz w  


; the jump
    


Can someone tell me how to jump to the load code in memory


Last edited by binary on 28 Dec 2010, 06:25; edited 1 time in total
Post 27 Nov 2010, 19:18
View user's profile Send private message Reply with quote
dosin



Joined: 24 Aug 2007
Posts: 337
dosin 27 Nov 2010, 20:31
you can start here.. shows code for a read and write.. using buffers .. and has more notes for the code.

http://board.flatassembler.net/topic.php?t=8771

once you read the code into your buffer..

to execute it.. you can do something like this:
Code:
mov esp, buffer    ; or adress of code.. 
sti
cld
mov si,sp
mov di, 7C00h     ; copy buffer to 7c00h
mov cx,512/2
rep movsw

xor eax,eax
xor ebx,ebx

jmp farjmp



farjmp  dw 0x7c00
            dw 0x0000
    
Post 27 Nov 2010, 20:31
View user's profile Send private message Reply with quote
binary



Joined: 10 Oct 2009
Posts: 29
binary 27 Nov 2010, 21:48
If I understood correctly this:
Code:
mov     cx,512/2        
mov     edi, 1400000
mov     dx,1f0h        
rep     insw 
    

should copy the sector to address [1400000] ( I use protected mode addressing )

After that I checked the byte at [1400000] to see if my sector was loaded and it didn't. ( I checked the bytes around it and nothing )

I want to load sector 2 at [1400000]

What am I doing wrong
Post 27 Nov 2010, 21:48
View user's profile Send private message Reply with quote
dosin



Joined: 24 Aug 2007
Posts: 337
dosin 27 Nov 2010, 23:53
Quote:
want to load sector 2 at [1400000]

did you write something at sector 2???

1st step with reading the hdd.. is knowing what is on your disk.. sector 0 is the MBR

sector 2.

well in LBA sectors the disc is layed out like

0,1,2,3,4 ect...

on I think all MS fat file system there is nothing in sector 2...
its empty... uless you have written something there,,

or if you have grub.. I think it uses sector 2..
so depending on what file system you have there may or may not be something
there.. empty...

you should get a hex editor and look at the hd.. to see whats on it..


but you should keep it simple.. start with sector 0...

read it from a floppy test program.. then execute to boot your OS on the HDD..

then learn about the layout of the MBR..
how to decode it.. and find the lba boot address of the portion your os is on..
and then boot it..

next step should be to understand the MBR...
and the portions.. the layout.. ect..


and then read sector 0 and dump it to screen and decode it.. or use a hex editor

------------
if you have writen a boot program to sector 2.. you should do the same ...
read it 1st.. then dump it to screen as hex.. to and cmp it. make sure what you
put there is correct..

double check everything with a program like hex edit..

this one is very good..

http://mh-nexus.de/en/programs.php

use with caution,.. you can overwrite stuff with this app.. and with the code your using..

also.. if using your personal computer and not a test one.. all I can say is Back it up..
some people here have found out the hard way,,
Post 27 Nov 2010, 23:53
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4354
Location: Now
edfed 28 Nov 2010, 02:45
Quote:
also.. if using your personal computer and not a test one.. all I can say is Back it up..
some people here have found out the hard way,,

yes! Very Happy

make backup, or find a way to don't write directlly to disks.

for example, you test a first time your lba routine on a virtual machine.
and after, you just play with a memory buffer when you do some tests.
and ones your memory shows good results, test under virtual machine.
and ones it is ok on virtual machine, test on real hardware, but with a lot of care.
Post 28 Nov 2010, 02:45
View user's profile Send private message Visit poster's website Reply with quote
binary



Joined: 10 Oct 2009
Posts: 29
binary 28 Nov 2010, 13:29
Thank you
I use an emulator ( Bochs ) and from time to time a USB stick (with HDD emulation) to test it on real hardware.

I've done all that experimentation with floppy and hdd with int 13h.
I don't use MS's file system,and I always use a hex editor for copying the compiled binary file to a hdd image or USB stick.

I have a 2 stage boot loader and I'm trying to load the second stage(located after the first stage on drive) using I/O ports instead of int 13h,the problem is that the code that I use for loading doesn't copy my second stage to memory so I'm dumping on screen only zeros.
Post 28 Nov 2010, 13:29
View user's profile Send private message Reply with quote
dosin



Joined: 24 Aug 2007
Posts: 337
dosin 29 Nov 2010, 16:46
sorry.. but with out seeing all whats going on its hard to give an answer on what is failing..

could be a few things..

you could post an example of the stage 1.. and we can try and help..
Post 29 Nov 2010, 16:46
View user's profile Send private message Reply with quote
binary



Joined: 10 Oct 2009
Posts: 29
binary 29 Nov 2010, 17:16
Code:
ORG 0x7c00

; unreal mode
   xor ax, ax
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax
   mov ss, ax
   mov sp, 0x9c00

 
   cli
   push ds
 
   lgdt [TabelGDT]
 
   mov  eax, cr0
   or al,1
   mov  cr0, eax
 
   mov  bx, 0x08
   mov  ds, bx
 
   and al,0xFE
   mov  cr0, eax
 
   pop ds
   sti
 
; ------------------------------------------------------------------------------------






; set default video mode 80x25:
mov     ah, 00h
mov     al, 03h
int     10h

; hide blinking text cursor:
mov ch, 32
mov ah, 1
int 10h












; Load stage 2
mov     dx,1f6h
mov     al,0a0h
out     dx,al

mov     dx,0x1F1
mov     al,0h
out     dx,al

; Number of sectors
mov     dx,1f2h
mov     al,1
out     dx,al

; loacation
mov     dx,1f3h
mov     al,1
out     dx,al

mov     dx,1f4h
mov     al,0
out     dx,al

mov     dx,1f5h
mov     al,0
out     dx,al

; read
mov     dx,1f7h
mov     al,20h     
out     dx,al

t:
  in      al,dx
  test    al,8
jz t


mov     cx,512/2
mov     edi, 1400000
mov     dx,1f0h
rep     insw






; check if there is something at 1400000

mov bh,[1400000]
cmp bh,0
je nd
 mov dh, 10  
 mov dl, 21  
 mov bh, 0
 mov ah, 2
 int 10h

 mov al , "2"  
 mov bl , 00001111b 

 mov AH , 09h
 mov bh , 0
 mov cx , 1
 INT 10h

nd:


cli
hlt

 
TabelGDT:
 dw gdt_end - gdt - 1
 dd gdt

gdt         dd 0,0
flatdesc    db 0xff, 0xff, 0, 0, 0, 10010010b, 11001111b, 0
gdt_end:


times 510 - ($-$$) db 0
dw 0xAA55  
    
Post 29 Nov 2010, 17:16
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4354
Location: Now
edfed 29 Nov 2010, 20:56
you cannot execute BIOS interrupt when in protected mode.

means that for the moment, you call an unexisting vector because in PM, the IDTR points to a memory zone where is located the IDT, and each entry in the IDT points to a memory where is loaded the routine.

that code cannot work at all because you set PM before to initialise it.
Post 29 Nov 2010, 20:56
View user's profile Send private message Visit poster's website Reply with quote
dosin



Joined: 24 Aug 2007
Posts: 337
dosin 30 Nov 2010, 02:27
Do this before entering PMode
Code:
; set default video mode 80x25: 
mov     ah, 00h 
mov     al, 03h 
int     10h 

; hide blinking text cursor: 
mov ch, 32 
mov ah, 1 
int 10h 

    



once in PM there is no more bios int 10h..
as edfed pointed out..

just a quick way to print text in pm for testing:

Code:
mov   byte [es:0xB809A], "A" ;print a char     


you will want to write your own text function for PMode

same goes for your stage 2..
since your in pm.. bios int 10h text functions
will not work in it..
Post 30 Nov 2010, 02:27
View user's profile Send private message Reply with quote
binary



Joined: 10 Oct 2009
Posts: 29
binary 05 Dec 2010, 17:18
The code that I posted above was a Flat real mode loader and int 10 and 13 worked , but anyway , now I have a P mode loader , did some research and some of experimentation and the second sector seems to be loaded but when I try to execute it with:

mov eax,500000
jmp eax

or

jmp 500000

or

jmp far dword [500000]

or

jmp far pword [500000]

the CPU resets
- everything else works as it should , I checked everything separately.

here's the loader:
Code:
org 7C00h


 ; A20
 in  al, 092h
 or  al, 2
 out 080h, al
 out 092h, al

; video mode 80x25:
mov     ah, 00h
mov     al, 03h
int     10h

; Hide blinking
 mov ch, 32
 mov ah, 1
 int 10h

; ---------------------------------  enter 32 biti  mode  --------------------------------------

        cli

        lgdt fword [gdt.size]

        mov eax,cr0
        or al,1
        mov cr0,eax

        jmp  gdt.code_descriptor:Mode32

; --------------------------------------  GDT  --------------------------------------------

gdt:
dw 0
.size   dw gdt_end -gdt - 1
        dd gdt

.null_descriptor = $ - gdt
        dq 0
.code_descriptor = $ - gdt
        dw 0FFFFh
        dw 0
        db 0
        db 10011010b
        db 11001111b
        db 0
.data_descriptor = $ - gdt
        dw 0FFFFh
        dw 0
        db 0
        db 10010010b
        db 11001111b
        db 0
gdt_end:

; --------------------------------------  GDT  --------------------------------------------
use32
Mode32:
        mov     ax,gdt.data_descriptor
        mov     ds,ax
        mov     es,ax
        mov     fs,ax
        mov     gs,ax
        mov     ss,ax
        mov     esp, 90000h
; -------------------------------------------------------------------------------------------




;Load the 2'nd sector 
mov     dx,1f6h
mov     al,01000000b
out     dx,al

mov     dx,0x1F1
mov     al,0h
out     dx,al


mov     dx,1f2h
mov     al,1            
out     dx,al



mov     dx,1f3h
mov     al,1    
out     dx,al

mov     dx,1f4h
mov     al,0    
out     dx,al

mov     dx,1f5h     
mov     al,0
out     dx,al


mov     dx,1f7h
mov     al,20h        
out     dx,al

w:
  in      al,dx
  test    al,8
jz w


mov     cx,512/2       
mov     edi, 500000
mov     dx,1f0h         
rep     insw



; Verify if 2nd sector is loaded
mov byte ah,[500012]
cmp ah,0x80
jne fd

mov byte[0xB8000], "1"
mov byte[0xB8001], 00011011b

fd:










; ASCII viewer
mov ebx,500000
mov edi,0xB8000
l:
cmp edi,757664
je ad


mov ah,[ebx]
mov byte [edi], ah        
add edi,1
mov byte [edi], 00011011b   
add edi,1
add ebx,2

jmp l
ad:






; jump
mov ax,[500000]
jmp ax



hlt
; ---------------------------------------- variables -----------------------------------------





; ---------------------------------------- variables -----------------------------------------
times 510-($-$$) db 0
dw 0xAA55   

    
Post 05 Dec 2010, 17:18
View user's profile Send private message Reply with quote
dosin



Joined: 24 Aug 2007
Posts: 337
dosin 07 Dec 2010, 06:09
the 1st jmp code is more for a cold boot.. to a MBR to the boot loader..
to execute an app loaded at [500000] you could try this...
Code:
        mov   ax,18h
  mov   ds,ax
 mov   es,ax
 xor   eax,eax
       mov   ebx,eax
       mov   ecx,eax
       mov   edx,eax
       call  dword[500000]
                                 ;... exit stuff   
  mov   ax,18h                                    
    mov   ds,ax
 mov   es,ax
 xor   eax,eax
       mov   ebx,eax
       mov   ecx,eax
       mov   edx,eax
    
Post 07 Dec 2010, 06:09
View user's profile Send private message Reply with quote
egos



Joined: 10 Feb 2009
Posts: 144
egos 10 Dec 2010, 08:35
Quote:

The code that I posted above was a Flat real mode loader and int 10 and 13 worked , but anyway , now I have a P mode loader , did some research and some of experimentation and the second sector seems to be loaded but when I try to execute it with:

mov eax,500000
jmp eax

or

jmp 500000

or

jmp far dword [500000]

or

jmp far pword [500000]

the CPU resets
- everything else works as it should , I checked everything separately.
You should use far jump to execute self-loading (self-modifying) code. Try jmp pword [startptr] or jmp CODE_SEL:500000 or push cs/push 500000/retf.
Post 10 Dec 2010, 08:35
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4354
Location: Now
edfed 10 Dec 2010, 09:28
Quote:

jmp far dword [500000]

or

jmp far pword [500000]


it is not the good way.

the far pointer is a data, not a direct adress.
then, you will need to create this far pointer somewhere in bootloader as said egos.

Code:
jmp pword[stratptr]
...
stratptr dp CODE_SEL:500000
    


indead, it is interresting to see that it doesn't work the easy way with jmp 500000.

are you sure you load it in DS=CS?

indeed, good job, it is a good start to overcome the int13h Very Happy
but it will be a problem if you want to try with other mediums than HDD.
Post 10 Dec 2010, 09:28
View user's profile Send private message Visit poster's website Reply with quote
binary



Joined: 10 Oct 2009
Posts: 29
binary 10 Dec 2010, 20:13
@dosin
I tried that and it triple faults for some reason

@ egos and edfed
I tried that and it seams to work (at least it doesn't triple fault).
In stage 2 I have a code to print a character on screen but it doesn't print it. I also tried some combinations with dosin's code and it still doesn't work


Second stage:
Code:

mov byte[0xB8004], "2"
mov byte[0xB8005], 00011011b

hlt  
    



Quote:

are you sure you load it in DS=CS?


Before the jmp DS an CS are not egual
CS = 8
DS = 16
Post 10 Dec 2010, 20:13
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4354
Location: Now
edfed 10 Dec 2010, 22:54
sorry, i wanted to say

[GDT.base+CS] = [GDT.base+DS]
Post 10 Dec 2010, 22:54
View user's profile Send private message Visit poster's website Reply with quote
binary



Joined: 10 Oct 2009
Posts: 29
binary 17 Dec 2010, 23:25
It works now


Here's an example code that loads a sector within protected mode , jumps to it and writes to HDD:


Code:
; -- -----------------------------------------------------------------------------------------
; ----------------------------- Bootloader ( first sector ) ---------------------------------
; -------------------------------------------------------------------------------------------

org 7C00h

; video mode 80x25:
 mov     ah, 00h
 mov     al, 03h
 int     10h

; hide blinking
 mov ch, 32
 mov ah, 1
 int 10h

; ---------------------------------  enter 32 biti  mode  --------------------------------------

        cli

        lgdt  [gdt]

        mov eax,17
        mov cr0,eax

        jmp   CodeDescriptor:Mode32

; --------------------------------------  GDT  --------------------------------------------

gdt_begin:

NullDescriptor:
        dq 0
CodeDescriptor = $ - gdt_begin
        dw 0FFFFh
        dw 0 
        db 0 
        db 10011010b
        db 11001111b 
        db 0
DataDescriptor = $ - gdt_begin
        dw 0FFFFh
        dw 0 
        db 0 
        db 10010010b
        db 11001111b 
        db 0
gdt_end:

gdt:
   dw gdt_end - gdt_begin - 1
   dd gdt_begin

; --------------------------------------  GDT  --------------------------------------------
use32
Mode32:
        mov     ax,DataDescriptor
        mov     ds,ax
        mov     es,ax
        mov     fs,ax
        mov     gs,ax
        mov     ss,ax
        mov     esp, 654000
; -------------------------------------------------------------------------------------------



; print a character
 mov byte[0xB8000], "1"
 mov byte[0xB8001], 00011011b










; load sectors to 2 MB location in RAM using LBA28

mov     dx,0x1F1
mov     al,0h
out     dx,al

; sector count
mov     dx,1f2h
mov     al,4           ; number of sectors to read
out     dx,al


; sector location
mov     dx,1f3h
mov     al,[rb1]        ; 4 8 8 [8]
out     dx,al

mov     dx,1f4h
mov     al,[rb2]        ; 4 8 [8] 8
out     dx,al

mov     dx,1f5h        ; 4 [8] 8 8
mov     al,[rb3]
out     dx,al

mov     dx,1f6h
mov     al,01000000b
or      al,[rb4]        ; [4] 8 8 8
out     dx,al


; read/write command
mov     dx,1f7h
mov     al,20h          ;20h - read    30h - write
out     dx,al


WhaitRead:
  in      al,dx
  test    al,8
jz WhaitRead


mov     cx,256*4  ; 4 sectors to load 
mov     edi, 2000000   ; location in RAM
mov     dx,1f0h
rep     insw






; jump to loaded code
 jmp CodeDescriptor:2000000



; sector location
 rb1 db 1
 rb2 db 0
 rb3 db 0
 rb4 db 0



; fill witgh zeroes the rest
times 510-($-$$) db 0
dw 0xAA55

; -------------------------------------------------------------------------------------------
; ----------------------------- Kernel ( second sector ) ---------------------------------
; -------------------------------------------------------------------------------------------

org 0


; print a character
 mov byte[0xB8002], "2"
 mov byte[0xB8003], 00011011b


; print a character
 mov eax , 2000000
 add eax,var
 mov ah , [eax]
 mov byte[0xB8004], ah
 mov byte[0xB8005], 00011011b






; write sectors from 2 MB location in RAM using LBA28

mov     dx,0x1F1
mov     al,0h
out     dx,al

; sector count
mov     dx,1f2h
mov     al,1            ; number of sectors to write
out     dx,al


; sector location
mov     dx,1f3h
mov     al,2        ; 4 8 8 [8]
out     dx,al

mov     dx,1f4h
mov     al,0        ; 4 8 [8] 8
out     dx,al

mov     dx,1f5h        ; 4 [8] 8 8
mov     al,0
out     dx,al

mov     dx,1f6h
mov     al,01000000b
or      al,0        ; [4] 8 8 8
out     dx,al


; read/write command
mov     dx,1f7h
mov     al,30h          ;20h - read    30h - write
out     dx,al


WhaitWrite:
  in      al,dx
  test    al,8
jz WhaitWrite


mov     cx,256
mov     esi, 2000000
mov     dx,1f0h
rep     outsw











hlt
 var db "3"
    
Post 17 Dec 2010, 23:25
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.