Page 1 of 2

Dex HDD PIO Driver problem

Posted: Thu Mar 26, 2009 5:03 am
by djsilence
Hi, everyone!

Hi, Dex. I have some questions to you (about your HDD PIO driver demo).

1: Yor wrote that we put to drive/head port value 0a0h. This means we set drive 0 head 0. If i want to use drive 1 i need to put 0b0h. What need I do if I want to read drive2 (or even drive3)?

2: While putting head number we use just 4bits(0-3). This means I can use just 15 heads. What need I do if I want to read from head, for ex., 200?

3: Can you write me what need I do exactly with cylinders? See, I have variable Cylinder:

Cylinder dw 0

What need I do with it next if I want to read cylinder, for ex., 1234?

Thanks great!

Re: Dex HDD PIO Driver problem

Posted: Thu Mar 26, 2009 5:19 am
by kmtdk
well
sry that im not dex, but i can answerd the question more or less :P

1:
well
the controller can only handle 2 drives, so you have yo use the secound ( or 3'ed if you want 3. and 4.) controller to acess 2 and 3 drive.
WIKI(ATA PIO MODE):
If the next two busses exist, they are normally controlled by IO ports 0x1E8 through 0x1EF, and 0x168 through 0x16F, respectively. The associated Device Control Registers/Alternate Status ports are IO ports 0x3E6, and 0x366.

2(and 3):
In CHS ( cylinder head sector) mode, you can not use that head, you will have to use LBA.
The CHS standard are as this:
sector: 0-63 ( 63 i max, you can not get by this, unless you use LBA)
Head : 0-15 (15 is max ^)
Cylinder 0-1023 ( 1023 is max^)

hope this helps you


KMT dk

Re: Dex HDD PIO Driver problem

Posted: Thu Mar 26, 2009 5:24 am
by djsilence
Thanks for very quick reply.

As I understand this means I cannot get access to head with number more than 15? So, if I realy need this I cannot use Dex demo?

Daniel.

Re: Dex HDD PIO Driver problem

Posted: Thu Mar 26, 2009 7:10 am
by Solar
Can't tell really without a link to the demo. ;-)

Re: Dex HDD PIO Driver problem

Posted: Thu Mar 26, 2009 11:31 pm
by Dex
Maybe this will help, just keep inc EAX to read from start of disk to end, so just add a loop, that inc eax, call HddRead , move 512 bytes from hdd-buffer and test for end of drive.

Code: Select all


hdbase	 equ  0x1f0					; 0x1f0 for primary device
							; 0x170 for secondary device
hdid	 equ  0x00					; 0x00 for master hd
							; 0x10 for slave hd

 ;---------------------------------------------------------;
 ; hd_read.                    ; eax = sector to read  ;
 ;---------------------------------------------------------;
HddRead:						 
	pushad 
	push  eax
newhdread:
	mov edx,[hdbase]
	inc   edx
	mov   al,0
	out   dx,al

	inc   edx
	mov   al,1
	out   dx,al

	inc   edx
	pop   ax
	out   dx,al

	inc   edx
	shr   ax,8
	out   dx,al

	inc   edx
	pop   ax
	out   dx,al

	inc   edx
	shr   ax,8
	and   al,1+2+4+8
	add   al,[hdid]	
	add   al,128+64+32
	out   dx,al

	inc   edx
	mov   al,20h
	out   dx,al
hddwait:
	in    al,dx
	test  al,128
	jnz   hddwait

	mov   edi,HddBuffer 
	mov   ecx,256
	mov edx,[hdbase]
	cld
	rep   insw

	popad
	ret


Re: Dex HDD PIO Driver problem

Posted: Sat Mar 28, 2009 2:26 am
by djsilence
Thanks great!

Dex you really help me not the first time!

This code seems to be asm interpretation of 28bitLBA which is posted at the ATA PIO Mode...

Thanks, once more!!! :D

Re: Dex HDD PIO Driver problem

Posted: Sat Mar 28, 2009 5:54 am
by djsilence
Hey, Dex, I've got a problem (once again :) ).

What did I do:
I've changed HddBuffer, let's say, to 0x1000.
I mean I do not

Code: Select all

mov edi, HddBuffer
,
I do this one:

Code: Select all

mov edi, 0x1000
Then in my main code, I do the next (NASM):

Code: Select all

mov eax, dword 1
call HddRead

mov bl, byte [0x1000]
call Putch32

cli
hlt
But I get nothing printed. I know exactly that my printchar is right because it was used to determinate right reading of sector in your demo (Not the last) and it worked. I tried to make loop for example for 1024 sectors (1 - 1024) and got NOTHING. I opened the image of my HDD in WinHEX and saw that there are at least 15 sectors of that range that have something in the begining (and that are printable characters which can be printed by my Putch32).

I know that HddRead finish work, because my VMware shows me message ala "You called HLT" (And I really did that :D ). Everything else is just the same as you wrote. What can it be? Thanks for help.

PS: In you previous demo you tested al to 8 and in this one you test al to 128. :?:

Daniel.

Re: Dex HDD PIO Driver problem

Posted: Sat Mar 28, 2009 3:51 pm
by Dex
Sorry small mistake :lol: i use var in my OS so i can use differant bases, so there should have been no [ ] around the hdbase and hdid, as its not whats in them, but what they = , as i have use "equ" in this example.
So just use this and you should be OK and start EAX from 0 when looping the sectors, also if your char function stops at 0, it may stop alot as there will be many in the dumped sectors, so maybe you could covert to ASCII hex before printing..
Good luck and let me know if that works.

Code: Select all


hdbase	 equ  0x1f0					; 0x1f0 for primary device
							; 0x170 for secondary device
hdid	 equ  0x00					; 0x00 for master hd
							; 0x10 for slave hd

 ;---------------------------------------------------------;
 ; hd_read.                    ; eax = sector to read  ;
 ;---------------------------------------------------------;
HddRead:						 
	pushad 
	push  eax
newhdread:
	mov edx,hdbase
	inc   edx
	mov   al,0
	out   dx,al

	inc   edx
	mov   al,1
	out   dx,al

	inc   edx
	pop   ax
	out   dx,al

	inc   edx
	shr   ax,8
	out   dx,al

	inc   edx
	pop   ax
	out   dx,al

	inc   edx
	shr   ax,8
	and   al,1+2+4+8
	add   al,hdid	
	add   al,128+64+32
	out   dx,al

	inc   edx
	mov   al,20h
	out   dx,al
hddwait:
	in    al,dx
	test  al,128
	jnz   hddwait

	mov   edi,HddBuffer 
	mov   ecx,256
	mov edx,hdbase
	cld
	rep   insw

	popad
	ret


Re: Dex HDD PIO Driver problem

Posted: Sun Mar 29, 2009 5:06 am
by djsilence
Great! Thanks a lot! But I have some questions:

1. Is it needed to use CLD before rep insw?
2. I can use insd with ecx = 128. Is it more "clever"? I mean that our loop causes not 256 times, it causes 128 times. Will this make the code more quickly? (Or maybe time of executing insd is MUCH longer than time to execute insw? Then maybe I would use insb with ecx = 512 ? :oops: :arrow: :D )

Thanks, Daniel!

Re: Dex HDD PIO Driver problem

Posted: Sun Mar 29, 2009 5:56 am
by ru2aqare
djsilence wrote:1. Is it needed to use CLD before rep insw?
Yes, you have to use, if you want the di or edi register to be incremented (as opposed to being decremented) when the instruction executes.
djsilence wrote: 2. I can use insd with ecx = 128. Is it more "clever"? I mean that our loop causes not 256 times, it causes 128 times. Will this make the code more quickly? (Or maybe time of executing insd is MUCH longer than time to execute insw? Then maybe I would use insb with ecx = 512 ? :oops: :arrow: :D )
You have to access the HDD controller with word instructions (insw, outsw, in ax,dx, out dx,ax) when transfering the contents of a sector.

Re: Dex HDD PIO Driver problem

Posted: Sun Mar 29, 2009 1:51 pm
by Dex
As ru2aqare, pointed out, it's not alway whats the fastest, but what the spec say you need to use.
Also you could try using

Code: Select all

     
ALIGN   4 
just before the loop labels, if they are used alot
http://www.asmcommunity.net/board/index ... nt;sa=view

Re: Dex HDD PIO Driver problem

Posted: Mon Mar 30, 2009 5:27 am
by djsilence
All right... Thanks, Dex. Now I have everything I was needed (I mean HDD).

Daniel.

Re: Dex HDD PIO Driver problem

Posted: Wed Apr 22, 2009 1:54 am
by djsilence
Hi, Dex!

I've got one more problem with code you gave me...
See:
I need to load file that is located not in root directory. My kernel file is located in '\SYOS\system32\krnl32.exe'. So first I load root directory, look for 'SYOS', load it, look for 'system32', load it, look for 'KRNL32.exe' and TRY to load it! TRY! But do not do it... When I call HddRead I get no errors, but when I try to do this:

mov bl, byte [0x100000]
call Putch32
cli
hlt

where 0x100000 - physical adress of my loaded sector (first byte of it for example latin letter 'A', so it can be printed) i gets nothing. I got known that the problem is while mov bl, byte [0x100000] because I don't see VMware message about HLT instruction. If i remove that string I got my message from VMware... The problem is exactly after the last invoking of HddRead, because previous calls worked great and there were no any errors during reading sectors. I get no any ideas about what can it be... So, please help.

Thanks, Daniel!

Re: Dex HDD PIO Driver problem

Posted: Wed Apr 22, 2009 12:10 pm
by Dex
This is a case of it could be any number of a 1000 things, but if it works fine with root dir, but not with other dirs then the problem is with the load dir code which is more fat?, than hdd load.
When you load each dir do you load it to a place that does not over write anything ? and do you save all regs etc.
Do you get any error codes that file not found ?.
Anyway i need to see the code or you can see DexOS code to see if you see a differanc.
Hope it helps, Dex.

Re: Dex HDD PIO Driver problem

Posted: Sat May 02, 2009 7:18 am
by djsilence
Hi, Dex. Here is what I've got:

Code: Select all

[BITS 16]
[SECTION .text]
[ORG 0x500]

[GLOBAL start]
start:
	jmp Entry

%include "stdio.inc"			; basic i/o routines
%include "Gdt.inc"			; Gdt routines
%include "A20.inc"			; A20 enabling
%include "Common.inc"
%include "bootinfo.inc"
%include "memory.inc"
%include "vesa.inc"
%include "vesaModes.asm"

%define bpp 32
%define y_res 480
%define x_res 640

mode dd 0

boot_info:
istruc multiboot_info
	at multiboot_info.flags,			dd 0
	at multiboot_info.memoryLo,			dd 0
	at multiboot_info.memoryHi,			dd 0
	at multiboot_info.bootDevice,			dd 0
	at multiboot_info.cmdLine,			dd 0
	at multiboot_info.mods_count,			dd 0
	at multiboot_info.mods_addr,			dd 0
	at multiboot_info.syms0,			dd 0
	at multiboot_info.syms1,			dd 0
	at multiboot_info.syms2,			dd 0
	at multiboot_info.mmap_length,			dd 0
	at multiboot_info.mmap_addr,			dd 0
	at multiboot_info.drives_length,		dd 0
	at multiboot_info.drives_addr,			dd 0
	at multiboot_info.config_table,			dd 0
	at multiboot_info.bootloader_name,		dd 0
	at multiboot_info.apm_table,			dd 0
	at multiboot_info.vbe_control_info,		dd 0
	at multiboot_info.vbe_mode_info,		dw 0
	at multiboot_info.vbe_interface_seg,		dw 0
	at multiboot_info.vbe_interface_off,		dw 0
	at multiboot_info.vbe_interface_len,		dw 0
iend

Entry:    
	;-------------------------------;
	;   Setup segments and stack	;
	;-------------------------------;

	cli	                   ; clear interrupts
	xor		ax, ax             ; null segments
	mov		ds, ax
	mov		es, ax
	mov		ax, 0x0000         ; stack begins at 0x9000-0xffff
	mov		ss, ax
	mov		sp, 0xFFFF
	sti	                   ; enable interrupts

	mov     	[boot_info+multiboot_info.bootDevice], dl

	call		_EnableA20
	call		InstallGDT
	sti

	xor		eax, eax
	xor		ebx, ebx
	call		BiosGetMemorySize64MB

	push		eax
	mov		eax, 64
	mul		ebx
	mov		ecx, eax
	pop		eax
	add		eax, ecx
	add		eax, 1024		; the routine doesnt add the KB between 0-1MB; add it

	mov		dword [boot_info+multiboot_info.memoryHi], 0
	mov		dword [boot_info+multiboot_info.memoryLo], eax

	mov		eax, 0x0
	mov		ds, ax
	mov		di, 0x1000
	call		BiosGetMemoryMap

	jmp EnterStage3

EnterStage3:
	cli	                           ; clear interrupts
	mov	eax, cr0                   ; set bit 0 in cr0--enter pmode
	or	eax, 1
	mov	cr0, eax

	jmp	CODE_DESC:Stage3

bits 32

%include "Paging.inc"
%include "HDD.inc"

%define ba		0x7C00
%define data_start	ba+0x4C
%define fat_start	ba+0x48
%define fat_sector	ba+0x44
%define root_cluster	ba+0x2C
%define sec_per_cluster	ba+0x0D
%define bytes_per_sec	ba+0x0b ; bytes/sector (dw)
%define res_sectors	ba+0x0e	; # reserved sectors (dw)
%define fat_count	ba+0x10	; # of fats (db)
%define hidden_sectors	ba+0x1c	; # hidden sectors (dd)
%define sec_per_fat	ba+0x24	; Sectors/Fat (dd)

msgWelcome db " SYOS Bootstrap utility", 0x00
msgControls db " Use arrows <UP> and <DOWN> to select item and use <ENTER> to boot selected OS", 0x00
msgChoise db " Please, make a choise from following variants: ", 0x00

X db 0
Y db 0
W db 0
C db 0
B db 0
R dd 0

Stage3:

	;-------------------------------;
	;   Set registers				;
	;-------------------------------;
	mov	ax, DATA_DESC		; set data segments to data selector (0x10)
	mov	ds, ax
	mov	ss, ax
	mov	es, ax
	mov	esp, 90000h		; stack begins from 90000h

	mov 	al, 0x09
	mov [CHAR_ATTRIB], al
	call ClrScr32
	mov al, 0
	mov [X], al
	mov [Y], al
	mov al, 0x07
	mov [C], al
	mov al, 80
	mov [W], al
	call DrawFilledRect
	mov al, 0
	mov ah, 24
	mov [X], al
	mov [Y], ah
	call DrawFilledRect
	mov al, 0
	mov ah, 0
	call GotoXY
	mov al, 0x70
	mov [CHAR_ATTRIB], al
	mov ebx, msgWelcome
	call Puts32
	mov al, 0
	mov ah, 24
	call GotoXY
	mov ebx, msgControls
	call Puts32
	mov al, 0
	mov ah, 2
	call GotoXY
	mov al, 0x07
	mov [CHAR_ATTRIB], al
	mov ebx, msgChoise
	call Puts32

	mov eax, dword 63		;63 - This is bootsector of first partition on master drive
	mov ebx, 0x7C00
	mov [HddBuffer], ebx
	call HddRead
	
	call LoadRoot
	call FindFile

	mov bl, '1'
	call Putch32

	cli
	jmp 0x08:0x100000	

infinite:
	jmp infinite

;Loads root directory of 1st partition to 0x7E00
LoadRoot:
	mov al, [fat_count]
	mov ebx, [sec_per_fat]
	mul ebx
	add eax, [hidden_sectors]
	add ax, [res_sectors]
	mov [R], eax
	mov [data_start], eax
	mov ebx, 0x7E00
	mov [HddBuffer], ebx
	call HddRead

	ret

FindFile:
	pusha
	mov eax, 0x7E00
next:
	mov ecx, 11
	mov edi, KERNEL_DIR1		;This finds '\SYOS'
	mov esi, eax
	repe cmpsb
	jz done
	add eax, dword 0x20
	jmp next

done:
	add eax, 0x1A			
	mov ebx, [eax]
	mov [R], ebx
	dec dword [R]
	dec dword [R]
	mov eax, [R]
	movzx edx, byte [sec_per_cluster]
	push edx
	mul edx
	pop edx
	add eax, [data_start]
	mov ebx, 0x7E00
	mov [HddBuffer], ebx		;This loads '\SYOS'
	call HddRead

	mov eax, 0x7E00			;This finds '\system32'
next_m:
	mov ecx, 11
	mov edi, KERNEL_DIR2
	mov esi, eax
	repe cmpsb
	jz done_m
	add eax, dword 0x20
	jmp next_m

done_m:	
	add eax, 0x1A
	mov ebx, [eax]
	mov [R], ebx
	dec dword [R]
	dec dword [R]
	mov eax, [R]
	movzx edx, byte [sec_per_cluster]
	push edx
	mul edx
	pop edx
	add eax, [data_start]
	mov ebx, 0x7E00
	mov [HddBuffer], ebx		;This loads '\system32'
	call HddRead

	mov eax, 0x7E00			;This finds '\KRNL32.EXE'
next_m1:
	mov ecx, 11
	mov edi, KERNEL_FN
	mov esi, eax
	repe cmpsb
	jz done_m1
	add eax, dword 0x20
	jmp next_m1
done_m1:
	add eax, 0x1A
	mov ebx, [eax]
	mov [R], ebx
	dec dword [R]
	dec dword [R]
	mov eax, [R]
	movzx edx, byte [sec_per_cluster]
	push edx
	mul edx
	pop edx
	add eax, [data_start]
	mov ebx, 0x100000
	mov [HddBuffer], ebx		;This loads '\KRNL32.EXE'
	call HddRead

	popa
	ret


DrawFilledRect:
	pusha
	mov al, [X]
	mov ah, [Y]
	call GotoXY
	mov al, [C]
	mov [CHAR_ATTRIB], al
	mov ch, 0
	mov bl, 0xDB
draw1:
	call Putch32
	inc ch
	cmp ch, byte [W]
	je done1
	jmp draw1
done1:
	popa
	ret

KERNEL_DIR1 db "SYOS       ", 0x00
KERNEL_DIR2 db "SYSTEM32   ", 0x00
KERNEL_FN db "KRNL34     ", 0x00

and HDD.inc:

Code: Select all

HddBuffer dd 0

hdbase    equ  0x1f0               ; 0x1f0 for primary device
                     ; 0x170 for secondary device
hdid    equ  0x00               ; 0x00 for master hd
                     ; 0x10 for slave hd

;---------------------------------------------------------;
; hd_read.                    ; eax = sector to read  ;
;---------------------------------------------------------;
HddRead:                   
   pushad 
   push  eax
newhdread:
   mov   edx,hdbase
   inc   edx
   mov   al,0
   out   dx,al

   inc   edx
   mov   al,1
   out   dx,al

   inc   edx
   pop   ax
   out   dx,al

   inc   edx
   shr   ax,8
   out   dx,al

   inc   edx
   pop   ax
   out   dx,al

   inc   edx
   shr   ax,8
   and   al,1+2+4+8
   add   al,hdid   
   add   al,128+64+32
   out   dx,al

   inc   edx
   mov   al,20h
   out   dx,al
hddwait:
   in    al,dx
   test  al,128
   jnz   hddwait

   mov   edi,[HddBuffer]
   mov   ecx,256
   mov   edx,hdbase
   cld
   rep   insw

   popad
   ret

See, I tried to get known where is error and when is it called? I got known that error is while executing these two opcodes:

Code: Select all

mov ecx, 256
mov edi, hdbase
I know it because I made it commented and really got no error. So it is somewhere here. This trouble is called after the fourth calling of HddRead. See, if I do this I else get error:

Code: Select all

mov eax, dword 1
mov ebx, 0x7E00
mov [HddBuffer], ebx
call HddRead


mov eax, dword 2
mov ebx, 0x7E00
mov [HddBuffer], ebx
call HddRead


mov eax, dword 3
mov ebx, 0x7E00
mov [HddBuffer], ebx
call HddRead


mov eax, dword 4
mov ebx, 0x7E00
mov [HddBuffer], ebx
call HddRead
But if I remove last four strings (then just three times HddRead is called) there is no errors.
Even when I try to use other registers(not ecx and edi) everything is the same.
And one more: I tried to set that values via stack in such a way:

Code: Select all

push dword 256
pop ecx
push dword hdbase
pop edi
But in this case I get infinity loop :?: :?: :?: (my last instructions are CLI HLT, so I can get known if everything is great with VMware message about halting, but using stack I really do not get it and nothing is displayed!!!)

Thanks, Daniel.

PS: I use VMWare and it shows me Kernel Stack Error Message (maybe it is something another, but in my bootloader I do not set IDT and that is why I cannot use exceptions fully)