OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Mar 19, 2024 5:51 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: int 13h ah 42h start sector
PostPosted: Mon Oct 18, 2021 8:34 am 
Offline

Joined: Mon Oct 18, 2021 7:39 am
Posts: 2
I'm trying to read from disk using int 13h ah 42h and it works fine only if I read the whole kernel in one call.
When reading in chunks it seems like only first call is having effect.
And I guess it works only when source sector in disk address packet is equal to 1.
I tried debugging it in bochs and it showed me that every read except first does not change the memory.
I'm interested to know why this happens.

Here's the boot code:
Code:
kernel_offset equ 0x7E00 ; The same one we used when linking the kernel
port_com1     equ 0x3f8

[bits 16]
org 0x7c00

e_read equ 0

sectors_per_iteration equ 1

boot_main_16:
   mov [boot_disk_id], dl

   mov ax, 0
   mov ds, ax
   mov es, ax
   mov fs, ax
   mov gs, ax

   mov sp, 0x7c00 ; free memory from 0x500 to 0x7c00
   mov bp, sp

   mov si, 0
   mov ds, si
   mov si, disk_address_packet
   mov ah, 0x42
   mov dl, [boot_disk_id]

   mov bx, kernel_size_in_sectors ; remaining sectors count

.read_next:
   cmp bx, sectors_per_iteration
   jg .more_remaining
   mov word [disk_address_packet.sectors_to_transfer], bx
   jmp .update_remaining_sector_count
.more_remaining:
   mov word [disk_address_packet.sectors_to_transfer], sectors_per_iteration
.update_remaining_sector_count:
   sub bx, word [disk_address_packet.sectors_to_transfer]

   mov di, 3 ; try count
.retry_read:
   stc
   int 0x13
   jnc .read_success

   .read_error:
      dec di
      test di, di
      jnz .retry_read
      jmp shutdown

   .read_success:
      test bx, bx
      jz .read_done
      add dword [disk_address_packet.destination_segment], sectors_per_iteration*512/16
      add dword [disk_address_packet.source_sector], sectors_per_iteration
      jmp .read_next

.read_done:
   call kernel_offset
   call shutdown

shutdown:
   mov dx, 0x604
   mov ax, 0x2000
   out dx, ax
   cli
   hlt
   jmp shutdown

boot_disk_id: db 0

disk_address_packet:
.size:                db 16
.reserved:            db 0
.sectors_to_transfer: dw 1
.destination_offset:  dw 0
.destination_segment: dw kernel_offset/16
.source_sector:       dq 1

times 510-($-$$) db 0
dw 0xaa55

kernel_size_in_sectors equ 63


Top
 Profile  
 
 Post subject: Re: int 13h ah 42h start sector
PostPosted: Mon Oct 18, 2021 2:35 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5069
Code:
boot_main_16:
   mov [boot_disk_id], dl

You're accessing memory through DS before you've set DS to a known value.

Code:
   mov sp, 0x7c00 ; free memory from 0x500 to 0x7c00

You're setting SP without setting SS, so your stack is at an unknown location.

Code:
      add dword [disk_address_packet.destination_segment], sectors_per_iteration*512/16

That's a word, not a dword.

Code:
kernel_size_in_sectors equ 63

How big is your kernel in bytes?


Top
 Profile  
 
 Post subject: Re: int 13h ah 42h start sector
PostPosted: Tue Oct 19, 2021 1:26 am 
Offline

Joined: Mon Oct 18, 2021 7:39 am
Posts: 2
Octocontrabass wrote:
How big is your kernel in bytes?

32256 bytes.

Octocontrabass wrote:
You're accessing memory through DS before you've set DS to a known value.
You're setting SP without setting SS, so your stack is at an unknown location.

Yes but qemu and bochs seem to intialize all segment registers with zeros so that's not the problem.

Octocontrabass wrote:
That's a word, not a dword.

True, but that didn't matter because x86 is little endian and addition didn't overflow.

I printed sectors_to_transfer, source_sector, and destination_segment before each read and they look correct.
Code:
0001 sectors read from 0001 into 07e0
0001 sectors read from 0002 into 0800
0001 sectors read from 0003 into 0820
...........


But still, memory at 0x8000 remains empty.

I also tried reading from sector 0x2 into segment 0x7e0 and it didn't work.


Top
 Profile  
 
 Post subject: Re: int 13h ah 42h start sector
PostPosted: Tue Oct 19, 2021 9:04 am 
Offline
Member
Member

Joined: Sat Mar 10, 2018 10:16 am
Posts: 296
twixuss wrote:
Yes but qemu and bochs seem to intialize all segment registers with zeros so that's not the problem.

Everything you need to fix this is move first line after line mov ds, ax

Code:
   mov si, 0
   mov ds, si
   mov si, disk_address_packet

You already set ds to right value, so you just can remove first and second line.

You are able to read 127 sectors per one packet, so for testing you can just load whole kernel through one packet and test if it was loaded right.

Just control question, are you reading from hard disk?

_________________
https://github.com/VendelinSlezak/BleskOS


Top
 Profile  
 
 Post subject: Re: int 13h ah 42h start sector
PostPosted: Tue Oct 19, 2021 10:58 am 
Offline
Member
Member

Joined: Sun Nov 23, 2008 5:56 am
Posts: 42
Location: Russia, Saint-Petersburg
Try setting ah to 0x42 immediately before int 0x13, as each successful call to this BIOS function resets ah to zero.


Top
 Profile  
 
 Post subject: Re: int 13h ah 42h start sector
PostPosted: Tue Oct 19, 2021 12:17 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5069
twixuss wrote:
Yes but qemu and bochs seem to intialize all segment registers with zeros so that's not the problem.

It will be a problem elsewhere.

twixuss wrote:
Octocontrabass wrote:
That's a word, not a dword.

True, but that didn't matter because x86 is little endian and addition didn't overflow.

It works, but it wastes at least one byte. Space is limited in a boot sector.


Top
 Profile  
 
 Post subject: Re: int 13h ah 42h start sector
PostPosted: Tue Oct 19, 2021 2:56 pm 
Offline
Member
Member
User avatar

Joined: Fri Sep 03, 2021 5:20 pm
Posts: 91
twixuss wrote:
Yes but qemu and bochs seem to intialize all segment registers with zeros so that's not the problem.


It's not advisable to make this kind of assumptions (as in don't assume anything, always initialize everything). The fact that they do that now, doesn't mean that all versions always will. Per your own words: "seem to", and not "ensure that". Also, if you intend to one day use your kernel outside of the sandbox, you definitely can't make that assumption. If you make that assumption now, especially if you don't document it, you'll forget to fix it later and you'll have one hell of a hard time debugging it when it bites you. Assumptions are the mother of all undefined behaviors.

_________________
Writing a bootloader in under 15 minutes: https://www.youtube.com/watch?v=0E0FKjvTA0M


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 17 guests


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 post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group