OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 9:34 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 77 posts ]  Go to page 1, 2, 3, 4, 5, 6  Next
Author Message
 Post subject: How do I load my sector with if it's more than 512 bytes?
PostPosted: Sat Aug 12, 2017 2:32 pm 
Offline
Member
Member

Joined: Wed Aug 09, 2017 7:37 am
Posts: 80
Hello.

How do I load my sector with INT 13h if there is more than 512 bytes? A sector is 512 bytes. Also, could I have some resources for FAT12 please? I've checked out the Wiki. I also checked out things from Microsoft Technet and Wikipedia.

Any help would be appreciated.

Thanks
Steve.


Top
 Profile  
 
 Post subject: Re: How do I load my sector with if it's more than 512 bytes
PostPosted: Sat Aug 12, 2017 2:42 pm 
Offline
Member
Member
User avatar

Joined: Fri Feb 17, 2017 4:01 pm
Posts: 640
Location: Ukraine, Bachmut
stevewoods1986 wrote:
Hello.

How do I load my sector with INT 13h if there is more than 512 bytes? A sector is 512 bytes. Also, could I have some resources for FAT12 please? I've checked out the Wiki. I also checked out things from Microsoft Technet and Wikipedia.

Any help would be appreciated.

Thanks
Steve.

You could if you wanted. :) The FAT specification is available.

_________________
ANT - NT-like OS for x64 and arm64.
efify - UEFI for a couple of boards (mips and arm). suspended due to lost of all the target park boards (russians destroyed our town).


Top
 Profile  
 
 Post subject: Re: How do I load my sector with if it's more than 512 bytes
PostPosted: Sat Aug 12, 2017 2:48 pm 
Offline
Member
Member

Joined: Wed Aug 09, 2017 7:37 am
Posts: 80
zaval wrote:
stevewoods1986 wrote:
Hello.

How do I load my sector with INT 13h if there is more than 512 bytes? A sector is 512 bytes. Also, could I have some resources for FAT12 please? I've checked out the Wiki. I also checked out things from Microsoft Technet and Wikipedia.

Any help would be appreciated.

Thanks
Steve.

You could if you wanted. :) The FAT specification is available.


I might look at that. How would I load my sector if there is more than 512 bytes?


Top
 Profile  
 
 Post subject: Re: How do I load my sector with if it's more than 512 bytes
PostPosted: Sat Aug 12, 2017 2:57 pm 
Offline
Member
Member
User avatar

Joined: Fri Aug 07, 2015 6:13 am
Posts: 1134
"al" = number of sectors to read.
Quite simple.

For more info see: http://www.ctyme.com/intr/rb-0607.htm
This page: http://wiki.osdev.org/FAT
This page:http://www.maverick-os.dk/FileSystemFormats/FAT12_FileSystem.html
This thread: http://forum.osdev.org/viewtopic.php?t=21155

_________________
OS: Basic OS
About: 32 Bit Monolithic Kernel Written in C++ and Assembly, Custom FAT 32 Bootloader


Top
 Profile  
 
 Post subject: Re: How do I load my sector with if it's more than 512 bytes
PostPosted: Sat Aug 12, 2017 3:23 pm 
Offline
Member
Member

Joined: Wed Aug 09, 2017 7:37 am
Posts: 80
Octacone wrote:


I tried that. Doesn't work. I tried making a file that does lots of operands and including it. I changed al in my bootloader. It just stops my kernel from working. By the way, how would I load my kernel by filename?


Top
 Profile  
 
 Post subject: Re: How do I load my sector with if it's more than 512 bytes
PostPosted: Sat Aug 12, 2017 4:15 pm 
Offline
Member
Member
User avatar

Joined: Sun Feb 18, 2007 7:28 pm
Posts: 1564
Hello,

What do you mean by "making a file that does lots of operands and including it?" Nothing about int 13h involves files. If you are going to use fat12, write a "Read Sector" function that reads only 1 sector. Don't worry about reading "multiple" sectors - with any of the fat filesystems you'll be reading 1 sector at a time.

How are you currently calling this interrupt? What is the expected behavior and what is currently happening? Have you tried just loading 1 sector to some location and verifying that it gets loaded? How have you verified that the function works/does not work? It is helpful to use a hex editor with bochsdbg to compare and test.

Don't worry about file systems until you are able to read sectors. (To answer the question however, you locate the file from the root directory structure which gives you the starting cluster. The fat gives you the next chain of clusters until eof. All of this is in the fat32 whitepaper linked earlier.)

_________________
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}


Top
 Profile  
 
 Post subject: Re: How do I load my sector with if it's more than 512 bytes
PostPosted: Sun Aug 13, 2017 3:59 am 
Offline
Member
Member

Joined: Sat Mar 01, 2014 2:59 pm
Posts: 1146
Sectors are always 512 bytes. To load more bytes, you load multiple sectors. So to read 1024 bytes, you need to read two sectors. The simplest way, I find, to do this is to loop your sector-reading function, and for each sector you increment the start sector value (carrying over to the side and/or cylinder/track values if required) and add 512 to the destination address (make sure that you've got enough space to read however much data you're trying to read).

Mine looks like this:
Code:
;read sectors from disk
;ax = start sector, bx = end sector (exclusive), es = destination segment
;updates es to end of data
readsectors:
push cx
push ax
read_loop:
call readsector
mov cx, es
add cx, #0x20
mov es, cx
inc ax
cmp ax, bx
jb read_loop
pop ax
pop cx
ret

;read a sector from disk
;ax = sector, es = destination segment
readsector:
push dx
push cx
push bx
push ax
push ax
mov cl, #36
div cl
mov bl, al
pop ax
mov cl, #18
div cl
and al, #0x01
add ah, #0x01
;bl = cylinder/track, al = head, ah = sector
mov ch, bl
mov cl, ah
mov dh, al
mov dl, #0
mov ax, #0x0201
mov bx, #0x0000
int 0x13
pop ax
pop bx
pop cx
pop dx
ret
I seem to remember that cylinders/tracks are numbered from 1, not 0. EDIT: Sectors are numbered from 1, cylinders/tracks and heads are numbered from 0.

_________________
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing


Last edited by onlyonemac on Sun Aug 13, 2017 2:17 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: How do I load my sector with if it's more than 512 bytes
PostPosted: Sun Aug 13, 2017 6:37 am 
Offline
Member
Member

Joined: Thu Aug 13, 2015 4:57 pm
Posts: 384
onlyonemac wrote:
Sectors are always 512 bytes.

Except when they aren't. Not really important within the context of this thread, but it would be good to not claim that they always are..

As for the OP, seriously, if you know how to read one sector and you can't figure out on your own how to read two or more sectors, then osdev might not be for you... Can't really think of a simpler programming problem to solve than creating a function and calling it twice..


Top
 Profile  
 
 Post subject: Re: How do I load my sector with if it's more than 512 bytes
PostPosted: Sun Aug 13, 2017 9:22 am 
Offline
Member
Member

Joined: Sat Mar 01, 2014 2:59 pm
Posts: 1146
LtG wrote:
onlyonemac wrote:
Sectors are always 512 bytes.

Except when they aren't. Not really important within the context of this thread, but it would be good to not claim that they always are..
AFAIK logical sectors are always 512 bytes. Physical sectors can, of course, be any size, but that's a hardware technicality. For standard storage device interfaces/protocols, a "sector" is always 512 bytes, even if you use LBA.
LtG wrote:
Can't really think of a simpler programming problem to solve than creating a function and calling it twice..
It's a bit more complicated than that. You also need to change the destination address, and handle crossing over from one side of the disk to the other or moving to the next track. And of course if you're using the BIOS interrupt then you'll probably overlook the idea of even using a subroutine/loop and instead get confused about the built-in ability to read multiple sectors and the various BIOS bugs that affect this function (I believe that this is what happened here).

_________________
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing


Top
 Profile  
 
 Post subject: Re: How do I load my sector with if it's more than 512 bytes
PostPosted: Sun Aug 13, 2017 10:05 am 
Offline
Member
Member

Joined: Wed Aug 09, 2017 7:37 am
Posts: 80
onlyonemac wrote:
LtG wrote:
onlyonemac wrote:
Sectors are always 512 bytes.

Except when they aren't. Not really important within the context of this thread, but it would be good to not claim that they always are..
AFAIK logical sectors are always 512 bytes. Physical sectors can, of course, be any size, but that's a hardware technicality. For standard storage device interfaces/protocols, a "sector" is always 512 bytes, even if you use LBA.
LtG wrote:
Can't really think of a simpler programming problem to solve than creating a function and calling it twice..
It's a bit more complicated than that. You also need to change the destination address, and handle crossing over from one side of the disk to the other or moving to the next track. And of course if you're using the BIOS interrupt then you'll probably overlook the idea of even using a subroutine/loop and instead get confused about the built-in ability to read multiple sectors and the various BIOS bugs that affect this function (I believe that this is what happened here).


So should I do?

Code:
mov ah, 2
mov al, 1
mov ch, 0
mov cl, 2
mov dh, 0
mov dl, 0
mov bx, 0x7c00
mov es, bx
mov bx, 0x00
int 13h

mov ah, 2
mov al, 1
mov ch, 0
mov cl, 3
mov dh, 0
mov dl, 0
mov bx, 0x7c00
mov es, bx
mov bx, 0x00
int 13h

jmp 0x7c00:0x00


What do I do?

neon wrote:
Hello,

What do you mean by "making a file that does lots of operands and including it?" Nothing about int 13h involves files. If you are going to use fat12, write a "Read Sector" function that reads only 1 sector. Don't worry about reading "multiple" sectors - with any of the fat filesystems you'll be reading 1 sector at a time.

How are you currently calling this interrupt? What is the expected behavior and what is currently happening? Have you tried just loading 1 sector to some location and verifying that it gets loaded? How have you verified that the function works/does not work? It is helpful to use a hex editor with bochsdbg to compare and test.

Don't worry about file systems until you are able to read sectors. (To answer the question however, you locate the file from the root directory structure which gives you the starting cluster. The fat gives you the next chain of clusters until eof. All of this is in the fat32 whitepaper linked earlier.)


To add bytes. Make a file with lots of moving that is over 512 bytes and see if my other code works.

Code:
%include "junkymoving.asm"

more code here...
doesn't run :( thats what happens when its more than 512 bytes


Top
 Profile  
 
 Post subject: Re: How do I load my sector with if it's more than 512 bytes
PostPosted: Sun Aug 13, 2017 2:16 pm 
Offline
Member
Member

Joined: Sat Mar 01, 2014 2:59 pm
Posts: 1146
stevewoods1986 wrote:
So should I do?

Code:
mov ah, 2
mov al, 1
mov ch, 0
mov cl, 2
mov dh, 0
mov dl, 0
mov bx, 0x7c00
mov es, bx
mov bx, 0x00
int 13h

mov ah, 2
mov al, 1
mov ch, 0
mov cl, 3
mov dh, 0
mov dl, 0
mov bx, 0x7c00
mov es, bx
mov bx, 0x00
int 13h

jmp 0x7c00:0x00


What do I do?
I haven't tried your code but at a glance it seems to me that it will write the second sector to the same place that it wrote the first sector. Your second
Code:
mov bx, 0x7c00
should probably be
Code:
mov bx, 0x7e00
otherwise you'll overwrite (in memory) the first sector with the second sector.

Also why are you writing to 0x7c00:0x0000, IIRC that will overwrite your bootsector?

_________________
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing


Top
 Profile  
 
 Post subject: Re: How do I load my sector with if it's more than 512 bytes
PostPosted: Sun Aug 13, 2017 2:50 pm 
Offline
Member
Member

Joined: Wed Aug 09, 2017 7:37 am
Posts: 80
onlyonemac wrote:
stevewoods1986 wrote:
So should I do?

Code:
mov ah, 2
mov al, 1
mov ch, 0
mov cl, 2
mov dh, 0
mov dl, 0
mov bx, 0x7c00
mov es, bx
mov bx, 0x00
int 13h

mov ah, 2
mov al, 1
mov ch, 0
mov cl, 3
mov dh, 0
mov dl, 0
mov bx, 0x7c00
mov es, bx
mov bx, 0x00
int 13h

jmp 0x7c00:0x00


What do I do?
I haven't tried your code but at a glance it seems to me that it will write the second sector to the same place that it wrote the first sector. Your second
Code:
mov bx, 0x7c00
should probably be
Code:
mov bx, 0x7e00
otherwise you'll overwrite (in memory) the first sector with the second sector.

Also why are you writing to 0x7c00:0x0000, IIRC that will overwrite your bootsector?


It works. That's why. No problems. I don't think I need 0x7e00 unless I have stack problems... wait. you mean. oh


Top
 Profile  
 
 Post subject: Re: How do I load my sector with if it's more than 512 bytes
PostPosted: Sun Aug 13, 2017 5:00 pm 
Offline
Member
Member
User avatar

Joined: Sun Feb 18, 2007 7:28 pm
Posts: 1564
Hello,

The provided code loads to 0x7c000 and 0x7e000 not 0x7c00. However, I suspect this might have not been done intentionally; it might be a good idea for the original poster to review segmentation.

- How are you copying the boot record to the disk image?
- What happens if you load it to 0x7e0:0 and 0x800:0? You should not need a jump since the sectors would be loaded in consecutive memory.
- Where is the stack?

_________________
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}


Last edited by neon on Sun Aug 13, 2017 5:25 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: How do I load my sector with if it's more than 512 bytes
PostPosted: Sun Aug 13, 2017 5:24 pm 
Offline
Member
Member
User avatar

Joined: Fri Oct 27, 2006 9:42 am
Posts: 1925
Location: Athens, GA, USA
@onlyonemac: I was confused too, until I noticed that the code is setting ES, via BX, and then clearing BX. IOW, it's not not writing to 0000:7c00 (computed absolute address 7c00 hex, or 31,774 decimal), where the BIOS loads the boot sector) but to 7c00:0000 (computed absolute address 7c000, or 507,904 decimal) - which is a much higher, being about 5/6ths of the way towards the top of base RAM memory according to the Memory Map.

You're point about it overwriting the first loaded sector is correct. However, in this instance, the OP would probably use something closer to this, assuming that ES and BX are not clobbered by the BIOS:

Code:
add bx, 0x10    ; advance the load location by 512 bytes
int 0x13


@stevewoods1986: In my own VERBUM boot sector demonstrator, I use an approach similar to the one onlyonemac used (as shown above), but I also used some NASM assembler macros to ease the process of calling some routines (though not the one for reading from disk), EQUates to give names to important constants, and memory variables to hold the values rather than hard-coding them.

equates:
Code:
;;constants
;

%define boot_base   0x0000      ; the segment:offset pair for the
%define boot_offset 0x7C00   ;  boot code entrypoint

stage2_base      equ 0x1000      ; the segment:offset to load
stage2_offset   equ 0x0000   ; the second stage into
stack_seg     equ 0x9000
stack_top   equ 0xFFFC

VBIOS           equ 0x10        ; BIOS interrupt vector for video services
GOTO_XY         equ 0x02        ; VBIOS routine - go to the given x, y coordinates
block_write     equ 0x09        ; VBIOS routine - write a fixed number of times to the screen
ttype           equ 0x0E        ; VBIOS routine - print character, teletype mode

DBIOS           equ 0x13        ; BIOS interrupt vector for disk services
disk_reset   equ 0x00        ; disk reset service
disk_read   equ 0x02        ; disk read service

;  BIOS error codes
reset_failure   equ 0x01        ; error code returned on disk reset failure
read_failure    equ 0x02        ; error code returned on disk read failure

; operational constants
tries           equ 0x03        ; number of times to attempt to access the FDD


macros:
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; macros
;
%define zero(x) xor x, x

%macro write 1
   mov si, %1
   call printstr
%endmacro


data section (which I put below the code):
Code:
[section data]
loading         db 'Loading stage two... ', NULL
done            db 'done.', CR, LF, NULL
snd_stage   db 'Second stage loaded, proceeding to switch context.', CR, LF, NULL
returned   db 'Control returned to first stage, ', NULL
reset_failed   db 'Could not reset drive,', NULL
read_failed   db 'Could not read second stage, ', NULL
exit            db ' system halted.', NULL

bootdrv           resb 1      ; byte reserved for boot drive ID number

; DBIOS arguments, values given are defaults
cyl             db 0        ; cylinder to read from
head           db 0        ; head to read from
startsector   db 2        ; sector to start reading at
numsectors   db 1        ; number of sectors to read



disk reset and read functions
Code:
; reset_disk
reset_disk:
  mov dl, [bootdrv]
  mov ah, disk_reset
  int DBIOS
  ret

; read_disk
read_disk:
  mov cx, tries        ; set count of attempts for disk reads
  .try_read:
    push cx
    mov cx, tries      ; set count of attempts to reset disk
    .try_reset:
      call reset_disk
      jnc short .read
      loop .try_reset       ; if the reset fails, try up to three times
      mov ax, reset_failure ; if all three fail, set an error code and return
      pop cx                ; make sure that the stack is correctly aligned
      jmp short .end_fail
  .read:
    mov ax, stage2_base
    mov es, ax
    mov dl, [bootdrv]
    mov ch, [cyl]           ; cylinder
    mov dh, [head]          ; head
    mov cl, [startsector]   ; first sector
    mov al, [numsectors]    ; number of sectors to load   
    mov ah, disk_read
    mov bx, stage2_offset
    int DBIOS
    jnc short .end_success
    pop cx
    loop .try_read
  mov ax, read_failure ; if attempts to read the disk fail, report error code
  jmp short .end_fail
.end_success:
  pop cx               ; make sure that the stack is correctly aligned
  zero(ax)
.end_fail:
  ret


The part of the actual loader that calls this is:
Code:
  mov [bootdrv], dl   ; save boot drive info for later use

; read in the data from disk and load it to ES:BX (already initialized)
  write loading
  call read_disk
  cmp ax, reset_failure
  jne good_reset
  write reset_failed
  jmp short shutdown


The point is that just because you are using assembly doesn't mean you have to throw good coding practices out the window. In this case, I probably should re-write this to use parameters for those arguments, as onlyonemac did, rather than hard-coding in the addresses, but one thing at a time.

_________________
Rev. First Speaker Schol-R-LEA;2 LCF ELF JAM POEE KoR KCO PPWMTF
Ordo OS Project
Lisp programmers tend to seem very odd to outsiders, just like anyone else who has had a religious experience they can't quite explain to others.


Top
 Profile  
 
 Post subject: Re: How do I load my sector with if it's more than 512 bytes
PostPosted: Mon Aug 14, 2017 6:35 am 
Offline
Member
Member

Joined: Wed Aug 09, 2017 7:37 am
Posts: 80
neon wrote:
Hello,

The provided code loads to 0x7c000 and 0x7e000 not 0x7c00. However, I suspect this might have not been done intentionally; it might be a good idea for the original poster to review segmentation.

- How are you copying the boot record to the disk image?
- What happens if you load it to 0x7e0:0 and 0x800:0? You should not need a jump since the sectors would be loaded in consecutive memory.
- Where is the stack?


What? So it's not 0x7c00? I don't need to jump to DS:BX?

I don't know where the stack is... Is it at 0x7c00?
Do I have to do mov sp, 0x7c00?

Am I an idiot?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 77 posts ]  Go to page 1, 2, 3, 4, 5, 6  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 56 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