Weird error with floppy image booting Kernel?

  • Follow


[30208 May 28 12:33 kernel.sys] : This is the number of bytes that is
_allowed_ with my boot loader. When I 'nop' the kernel to 30209 bytes
or higher, the virtual machine resets. Why is this?

My Operating System written in Assembler works great when it is 30208
bytes in size, but one byte more, or one nop more, and boom! Reset.

Totally baffles me. Does anyone here have any light to shed on the
matter?

Thank you sincerely in advance,

Cat
0
Reply obrzut.alex (64) 5/28/2011 11:36:48 AM

On May 28, 12:36=A0pm, catcalls <obrzut.a...@nospicedham.gmail.com>
wrote:
> [30208 May 28 12:33 kernel.sys] : This is the number of bytes that is
> _allowed_ with my boot loader. When I 'nop' the kernel to 30209 bytes
> or higher, the virtual machine resets. Why is this?
>
> My Operating System written in Assembler works great when it is 30208
> bytes in size, but one byte more, or one nop more, and boom! Reset.
>
> Totally baffles me. Does anyone here have any light to shed on the
> matter?
>
> Thank you sincerely in advance,
>
> Cat

Some news.

I discovered my boot loader was wrote a lil' strange. So, I decided to
look into the boot loader.

Basically, the bootloader is an 0x13 INT ah 0x02 deal that reads 59
sectors at once, starting at sector 2.

    165         mov ah, 0x02
    166         mov al, 59
    167         ;mov ch,0               ; cylinder =3D 0
    168         mov ch, 0               ; sector =3D 2 (starts at sector
1 not 0)
    169         mov cl, 2
    170         mov dl,[bsDriveNumber]  ; disk =3D what we booted from
    171         int 0x13                ; read it
    172         jc read_me
    173 FIN:

This is the code. Please excuse the line numbers!

AH is the read function of INT 0x13
AL is the number of sectors to read.
CH is the cylinder or track of the floppy
CL is the location sector on floppy to start the floppy disk read.
DL is the drive number, DH is unknown to me at this point in time!

Well, I know a carry is thrown on error. Hence the jc read_me to
attempt another read.

But, all in all, this works fine and boots my Kernel when it is 30208
bytes in size.

How ever, the problem arose when the kernel grew to 30212 Bytes. It
wouldn't load any more.

So, looking into the boot loader, I discovered the fact that I was
reading 59 sectors at once. _And_ it is not possible to read 60 at
once as it is not supported by my CPU.

This leads to the conclusion I require a simple boot loader example
that reads a single sector at a time, does not work with the FAT file
system but a flat binary file system, and basically explains the CHS
to me.

I also know about LBA (Large Block Mode) where this is different to
CHS, but, how?

So many questions, I know. But, this is very important right now and
my friend, Patrick, is working on some legal case and cannot talk to
me about it (He is the boot loader author for the OS).

O.K. ~ one last question; is the code below any help to me or is that
just for a FAT file system?

;       mov word ax, [Cluster]
    149 .sector_loop:
    150 ;        mov si, ax
    151 ;        shl si, 1
    152 ;        mov [Cluster], si
    153 ;       add ax, 31                      ; ax =3D logical sector
    154 ;       mov dx, 0
    155 ;       mov di, 18
    156 ;       div di
    157 ;       mov cl, dl
    158 ;       add cl, 1                       ; cl =3D sector =3D
(logical % 18 + 1)
    159 ;       mov dx, 0
    160 ;       mov di, 2
    161 ;       div di
    162 ;       mov ch, al                      ; ch =3D track =3D
((logical / 18) / 2)
    163 ;       mov dh, dl                      ; dh =3D head =3D
((logical / 18) % 2)

I found this on the Internet searching for an example boot loader but
they all seem to use FAT?

Weird I know, but, I want to use my _own_ file system format. Starting
with a 30212 byte kernel with 512 byte boot loader preceding the
kernel and boot from that in a Virtual Machine like I have been doing.

Also, my floppy.c program that mimicked the 'cat' command has broke.
This might be due to gcc being screwed up.

Cat
0
Reply obrzut.alex (64) 5/28/2011 2:43:24 PM


146         mov ax, 0x0050          ; superblock goes to 9000:0000
(above stack)
    147         mov es, ax
    148         ;mov ds, ax
    149 .sector_loop:
    150         mov ah, 2
    151         mov al, 1
    152         mov ch, BYTE [cylinder] ; cylinder = 0
    153                                 ; sector = 2 (starts at sector
1 not 0)
    154         mov cl, BYTE [sector]
    155         mov dl, [bsDriveNumber] ; disk = what we booted from
    156         int 0x13                ; read it
    157         jc FIN
    158         inc BYTE [sector]
    159         inc BYTE [datasector]
    160         cmp BYTE [sector], 18
    161         jne .sector_loop
    162         inc BYTE [cylinder]
    163         mov BYTE [sector], 1
    164         cmp BYTE [datasector], 60
    165         jne .sector_loop
    166 FIN:

Excuse the line numbers. They are a symptom of VI.

What do you think of my new routine for reading my Kernel into the
RAM? It doesn't work...but maybe you can help with that?

sector = 2 to begin with. datasector, cylinder = 0.

So, I have an ORG 0x500 with DS set to 0x0000 in my boot to program
and it doesn't work. This is _after_ issuing the following code;

    173           push    WORD 0x0050
    174           push    WORD 0x0000
    175           retf

to jump to the RAM location where the program is loaded.

I've also tried no ORG and ds set to 0x0050 and that did not work
either!

Cannot seem to think where I am going wrong here. Perhaps my figures
are off in the boot loader? But, basically, I see the bootloader
finish loading, perform the jmp, and nothing happens!?

Any help?

Cat
0
Reply obrzut.alex (64) 5/28/2011 5:40:51 PM

On May 28, 6:40=A0pm, catcalls <obrzut.a...@nospicedham.gmail.com>
wrote:
> 146 =A0 =A0 =A0 =A0 mov ax, 0x0050 =A0 =A0 =A0 =A0 =A0; superblock goes t=
o 9000:0000
> (above stack)
> =A0 =A0 147 =A0 =A0 =A0 =A0 mov es, ax
> =A0 =A0 148 =A0 =A0 =A0 =A0 ;mov ds, ax
> =A0 =A0 149 .sector_loop:
> =A0 =A0 150 =A0 =A0 =A0 =A0 mov ah, 2
> =A0 =A0 151 =A0 =A0 =A0 =A0 mov al, 1
> =A0 =A0 152 =A0 =A0 =A0 =A0 mov ch, BYTE [cylinder] ; cylinder =3D 0
> =A0 =A0 153 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 ; sector =3D 2 (starts at sector
> 1 not 0)
> =A0 =A0 154 =A0 =A0 =A0 =A0 mov cl, BYTE [sector]
> =A0 =A0 155 =A0 =A0 =A0 =A0 mov dl, [bsDriveNumber] ; disk =3D what we bo=
oted from
> =A0 =A0 156 =A0 =A0 =A0 =A0 int 0x13 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0; rea=
d it
> =A0 =A0 157 =A0 =A0 =A0 =A0 jc FIN
> =A0 =A0 158 =A0 =A0 =A0 =A0 inc BYTE [sector]
> =A0 =A0 159 =A0 =A0 =A0 =A0 inc BYTE [datasector]
> =A0 =A0 160 =A0 =A0 =A0 =A0 cmp BYTE [sector], 18
> =A0 =A0 161 =A0 =A0 =A0 =A0 jne .sector_loop
> =A0 =A0 162 =A0 =A0 =A0 =A0 inc BYTE [cylinder]
> =A0 =A0 163 =A0 =A0 =A0 =A0 mov BYTE [sector], 1
> =A0 =A0 164 =A0 =A0 =A0 =A0 cmp BYTE [datasector], 60
> =A0 =A0 165 =A0 =A0 =A0 =A0 jne .sector_loop
> =A0 =A0 166 FIN:
>
> Excuse the line numbers. They are a symptom of VI.
>
> What do you think of my new routine for reading my Kernel into the
> RAM? It doesn't work...but maybe you can help with that?
>
> sector =3D 2 to begin with. datasector, cylinder =3D 0.
>
> So, I have an ORG 0x500 with DS set to 0x0000 in my boot to program
> and it doesn't work. This is _after_ issuing the following code;
>
> =A0 =A0 173 =A0 =A0 =A0 =A0 =A0 push =A0 =A0WORD 0x0050
> =A0 =A0 174 =A0 =A0 =A0 =A0 =A0 push =A0 =A0WORD 0x0000
> =A0 =A0 175 =A0 =A0 =A0 =A0 =A0 retf
>
> to jump to the RAM location where the program is loaded.
>
> I've also tried no ORG and ds set to 0x0050 and that did not work
> either!
>
> Cannot seem to think where I am going wrong here. Perhaps my figures
> are off in the boot loader? But, basically, I see the bootloader
> finish loading, perform the jmp, and nothing happens!?
>
> Any help?
>
> Cat

   1 bits 16
      2 ORG 0x0500
      3 jmp main
      4 ;************************************************;
      5 ;       Prints a string
      6 ;       DS=3D>SI: 0 terminated string
      7 ;************************************************;
      8 Print:
      9                         lodsb                           ; load
next byte from string from SI to A        L
     10                         or      al, al                  ; Does
AL=3D0?
     11                         jz      PrintDone               ; Yep,
null terminator found-bail out
     12                         mov     ah, 0eh                 ; Nope-
Print the character
     13                         int     10h
     14                         jmp     Print                   ;
Repeat until null terminator found
     15         PrintDone:
     16                         ret
     17
     18 main:
     19                     mov ax, 0x0000
     20                     mov ds, ax
     21
     22                     mov si, msgComplete
     23                     call Print
     24 inf: hlt
     25         jmp inf
     26                     msgComplete db "Completed Boot.", 0x00
     27

Excuse the line numbers! Haha.

This is the working 'Kernel' that I boot into from the above code. See
the ORG and DS input values for correctly booting up the kernel.

The problem lied with reading too many sectors from the 'disk' (i.e.
floppy file image on GNU/Linux).

Basically, I had it set up to read in 60 sectors, and was using that
to test the kernel. That failed. So, I tried 2 sectors. That fails.
Finally, I tried 1 sector, that works!

So, I discovered something new today. V. important information
pertaining to floppy disks. Read the _exact_ size of the program from
disk, else face a crash when trying to runtime the image.

Okies...next step...the _real kernel_!
0
Reply obrzut.alex (64) 5/28/2011 6:20:45 PM

    149 .sector_loop:
    150         mov ah, 2
    151         mov al, 1
    152         mov ch, BYTE [cylinder] ; cylinder = 0
    153                                 ; sector = 2 (starts at sector
1 not 0)
    154         mov cl, BYTE [sector]
    155         mov dl, [bsDriveNumber] ; disk = what we booted from
    156         int 0x13                ; read it
    157         jc FIN
    158         inc BYTE [datasector]
    159         cmp BYTE [datasector], 58    ; Is this correct? 58 or
59 or 60 here?
    160         je FIN
    161         inc BYTE [sector]
    162         cmp BYTE [sector], 18        ; Is this correct? 18 or
17 or 19 here?
    163         jne .sector_loop
    164         mov ah, 0x0e
    165         mov al, [0001]
    166         mov bx, 7
    167         int 0x10
    168         inc BYTE [cylinder]
    169         mov BYTE [sector], 1        ; Is this correct? 0 or 1
or 2 here?
    170         jmp .sector_loop
    171 FIN:

See line comments for lines 159, 162, and 169 for more information on
the present question...

Kind rgrds,

Cat
0
Reply obrzut.alex (64) 5/28/2011 6:45:45 PM

SUCCESS! Yes. I successfully re-created my original boot-loader with
the new, one sector at a time, code.

149 .sector_loop:
    150         mov ah, 2
    151         mov al, 1
    152         mov ch, BYTE [cylinder] ; cylinder = 0
    153                                 ; sector = 2 (starts at sector
1 not 0)
    154         mov cl, BYTE [sector]
    155         mov dl, [bsDriveNumber] ; disk = what we booted from
    156         int 0x13                ; read it
    157         jc FIN
    158         inc BYTE [datasector]
    159         cmp BYTE [datasector], 59
    160         je FIN
    161         inc BYTE [sector]
    162         xor ax, ax
    163         mov ax, [datasector]
    164         mov WORD bx, 512d
    165         mul bx
    166         mov es, ax
    167         cmp BYTE [sector], 18
    168         jbe .sector_loop
    169         mov ah, 0x0e
    170         mov al, [0x0100]
    171         mov bx, 7
    172         int 0x10
    173         inc BYTE [cylinder]
    174         mov BYTE [sector], 1
    175         jmp .sector_loop
    176 FIN:


This is the end result. It was bugging me that ES might _not_ be
getting advanced with the INT 0x13 ~ and that IS the case! So, with a
lil' mathematical mul I sorted it. Ha!

Nice, eh? Now all I have left is to test it with a kernel bigger than
30208 bytes in size (fingers crossed, eh?)

Cat
0
Reply obrzut.alex (64) 5/28/2011 9:14:57 PM

149         mov ax, 0x0050          ; superblock goes to 0050:0000
(above stack)
    150         mov es, ax
    151 .sector_loop:
    152         mov ah, 2
    153         mov al, 1
    154         mov cx, WORD [cylinder] ; cylinder = 0
    155         and cx, 0xFFC0
    156         shr cx, 6               ; ---CH--- ---CL---
    157                                 ; 76543210 98
    158                                 ;            543210
    159         mov dl, BYTE [sector]
    160         and dx, 63
    161         or cx, dx
    162 ; sector = 2 (starts at sector 1 not 0)
    163         mov dl, [bsDriveNumber] ; disk = what we booted from
    164         int 0x13                ; read it
    165         jc FIN
    166         inc BYTE [datasector]
    167         cmp BYTE [datasector], 59
    168         je FIN
    169         inc BYTE [sector]
    170         add bx, 0x200
    171         cmp BYTE [sector], 18
    172         jbe .sector_loop
    173         inc BYTE [cylinder]
    174         mov BYTE [sector], 1
    175         jmp .sector_loop
    176 FIN:
    177           mov ah, 0xe
    178           mov al, [0001]
    179           mov bx, 7
    180           int 0x10
    181           mov     ah, 0x00
    182
    183           push    WORD 0x0050
    184           push    WORD 0x0000
    185           retf

Again, working on the Boot Loader. Interesting article on Wiki stating
the Cylinder is a mixture of stuff and requires some bit shifting. Did
not know that!

This is the new code, but sadly, it does not work. Basically, when I
run this boot sector, it seems to jump back to the start of the boot
sector code? So, it seems to be reading the boot sector code in as
well as the kernel?

I get a double entry. NARF!

So, it is coming along (without anyones helps!?) Can anyone see why I
get that double entry and why I cannot load my kernel?

Kind regards,

Cat
0
Reply obrzut.alex (64) 5/29/2011 6:45:21 AM

catcalls wrote:

<snip>

> Basically, the bootloader is an 0x13 INT ah 0x02 deal that reads 59
> sectors at once, starting at sector 2.
>
>      165         mov ah, 0x02
>      166         mov al, 59
>      167         ;mov ch,0               ; cylinder = 0
>      168         mov ch, 0               ; sector = 2 (starts at sector
> 1 not 0)
>      169         mov cl, 2
>      170         mov dl,[bsDriveNumber]  ; disk = what we booted from
>      171         int 0x13                ; read it
>      172         jc read_me
>      173 FIN:
>
> This is the code. Please excuse the line numbers!
>
> AH is the read function of INT 0x13
> AL is the number of sectors to read.
> CH is the cylinder or track of the floppy
> CL is the location sector on floppy to start the floppy disk read.
> DL is the drive number, DH is unknown to me at this point in time!

DH = head number (0 or 1 for floppy, 0...255
for HD)

> Well, I know a carry is thrown on error. Hence the jc read_me to
> attempt another read.

If CF is set, AH holds the error code and AL
the number of properly transferred sectors.

> But, all in all, this works fine and boots my Kernel when it is 30208
> bytes in size.

59 * 512 = 30208

> How ever, the problem arose when the kernel grew to 30212 Bytes. It
> wouldn't load any more.

Four byte too much?

> So, looking into the boot loader, I discovered the fact that I was
> reading 59 sectors at once. _And_ it is not possible to read 60 at
> once as it is not supported by my CPU.
>
> This leads to the conclusion I require a simple boot loader example
> that reads a single sector at a time, does not work with the FAT file
> system but a flat binary file system, and basically explains the CHS
> to me.
>
> I also know about LBA (Large Block Mode) where this is different to
> CHS, but, how?

It allows larger capacities:

CHS: 512 * 63 * 256 * 1,024 =     8,455,716,864 byte
LBA: 512 * 4,294,967,295    = 2,199,023,255,040 byte


CHS to LBA:

LBA = (C * max_heads * max_sectors) + (H * max_sectors) + (S - 1)


LBA to CHS:

              LBA
C = -----------------------
     max_heads * max_sectors


     LBA - (C * max_heads * max_sectors)
H = -----------------------------------
              max_sectors

S = LBA - ((C * max_heads * max_sectors) + (H * max_sectors)) + 1


<snip>

> Weird I know, but, I want to use my _own_ file system format. Starting
> with a 30212 byte kernel with 512 byte boot loader preceding the
> kernel and boot from that in a Virtual Machine like I have been doing.

Try this (FASM syntax):

use 16
         ; ------------------------------------------
         ; test LBA support - we refuse to work w.o.
         ; ------------------------------------------
         mov ax,0x4100             ; AL = 00, AH = 41
         mov bx,0x55AA             ; BX = 55AA
         mov dx,0x80               ; DL = 0x00 / 0x01   floppy
                                   ;      0x80...0x87   HD
         int 0x13                  ; are we willing to continue?
         jc .lba
         ; ------------------------------------------
         ; set required segments and registers
         ; ------------------------------------------
         cli                       ; mi = off
         mov bx,0x3000             ; BX = 3000 (IBOOT code)
         mov si,0x7BC0             ; SI = 7BC0 (LBA parameter block)
         xor ax,ax                 ; AX = 0000 (used to clear)
         mov ds,bx                 ; DS = 3000
         mov es,bx                 ; ES = 3000
         mov ss,bx                 ; SS = 3000
         mov sp,0xFFFE             ; SP = FFFE
         sti                       ; mi = on
         ; ------------------------------------------
         ; load IBOOT
         ; ------------------------------------------
         mov [si],       word 0x10 ; structure size
         mov [si + 0x02],word 0x35 ; 53 sectors
         mov [si + 0x04],ax        ; buffer offset
         mov [si + 0x06],word 0x03 ;        segment (0x00030000)
         mov [si + 0x08],word 0x0A ; DQ LBA loDD low
         mov [si + 0x0A],ax        ;             high
         mov [si + 0x0C],ax        ;        hiDD low
         mov [si + 0x0E],ax        ;             high
         mov dl,0x80               ; DL = 1st HD
         mov ah,0x42               ; AH = read
         int 0x13                  ; read sectors
         jc .rde
         jmp 0x3000:0000           ; start boot manager
         ; ------------------------------------------
         ; error handling
         ; ------------------------------------------
    .rde:mov si,err1               ; SI = 00[msg1]
         jmp .msg
    .lba:mov si,err0               ; SI = 00[msg0]
    .msg:lodsb                     ; retrieve char
         xor bx,bx                 ; BX = 00 (ignored in text mode)
         mov ah,0x0E               ; AH = 0E
         test al,al                ; string end?
         je .hang
         int 0x10                  ; write char in TTY mode
         jmp .msg
   .hang:nop
         jmp .hang                 ; freeze
         ; ------------------------------------------
         ; messages
         ; ------------------------------------------
    err0:DB "IBOOT cannot run without LBA aware BIOS!"
         DB 00
    err1:DB "Read error - cannot load IBOOT!"
         DB 00


INT13, function 42 requires a structure like
this:

00 DB   structure size in byte
01 DB   must be zero
02 DW   blocks to transfer
04 DD   address transfer buffer
08 DQ   first LBA to transfer

AH    = 0x42 (extended read)
DL    = drive number
DS:SI = address where structure is stored

The number of blocks to transfer (word 0x02)
might be limited by the BIOS. If so, use the
allowed number, then repeat until the entire
code is transferred. Just add max_sectors to
the (quad)word at 0x08 and reset AH to 0x42.
Call int 0x13 as often as required. The word
at 0x02 probably needs a correction prior to
the last call (less blocks to read).

Change addresses and parameters to suit your
needs. The code occupies 172 byte (fits into
a standard MBR with plenty of room for other
data below the partition table).


Greetings from Augsburg

Bernhard Schornak
0
Reply schornak1 (82) 5/29/2011 7:42:17 AM

On May 29, 8:42=A0am, Bernhard Schornak <schor...@nospicedham.web.de>
wrote:
> catcalls wrote:
>
> <snip>
>
>
>
>
>
>
>
>
>
> > Basically, the bootloader is an 0x13 INT ah 0x02 deal that reads 59
> > sectors at once, starting at sector 2.
>
> > =A0 =A0 =A0165 =A0 =A0 =A0 =A0 mov ah, 0x02
> > =A0 =A0 =A0166 =A0 =A0 =A0 =A0 mov al, 59
> > =A0 =A0 =A0167 =A0 =A0 =A0 =A0 ;mov ch,0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; =
cylinder =3D 0
> > =A0 =A0 =A0168 =A0 =A0 =A0 =A0 mov ch, 0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; =
sector =3D 2 (starts at sector
> > 1 not 0)
> > =A0 =A0 =A0169 =A0 =A0 =A0 =A0 mov cl, 2
> > =A0 =A0 =A0170 =A0 =A0 =A0 =A0 mov dl,[bsDriveNumber] =A0; disk =3D wha=
t we booted from
> > =A0 =A0 =A0171 =A0 =A0 =A0 =A0 int 0x13 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
; read it
> > =A0 =A0 =A0172 =A0 =A0 =A0 =A0 jc read_me
> > =A0 =A0 =A0173 FIN:
>
> > This is the code. Please excuse the line numbers!
>
> > AH is the read function of INT 0x13
> > AL is the number of sectors to read.
> > CH is the cylinder or track of the floppy
> > CL is the location sector on floppy to start the floppy disk read.
> > DL is the drive number, DH is unknown to me at this point in time!
>
> DH =3D head number (0 or 1 for floppy, 0...255
> for HD)
>
> > Well, I know a carry is thrown on error. Hence the jc read_me to
> > attempt another read.
>
> If CF is set, AH holds the error code and AL
> the number of properly transferred sectors.
>
> > But, all in all, this works fine and boots my Kernel when it is 30208
> > bytes in size.
>
> 59 * 512 =3D 30208
>
> > How ever, the problem arose when the kernel grew to 30212 Bytes. It
> > wouldn't load any more.
>
> Four byte too much?
>
> > So, looking into the boot loader, I discovered the fact that I was
> > reading 59 sectors at once. _And_ it is not possible to read 60 at
> > once as it is not supported by my CPU.
>
> > This leads to the conclusion I require a simple boot loader example
> > that reads a single sector at a time, does not work with the FAT file
> > system but a flat binary file system, and basically explains the CHS
> > to me.
>
> > I also know about LBA (Large Block Mode) where this is different to
> > CHS, but, how?
>
> It allows larger capacities:
>
> CHS: 512 * 63 * 256 * 1,024 =3D =A0 =A0 8,455,716,864 byte
> LBA: 512 * 4,294,967,295 =A0 =A0=3D 2,199,023,255,040 byte
>
> CHS to LBA:
>
> LBA =3D (C * max_heads * max_sectors) + (H * max_sectors) + (S - 1)
>
> LBA to CHS:
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 LBA
> C =3D -----------------------
> =A0 =A0 =A0max_heads * max_sectors
>
> =A0 =A0 =A0LBA - (C * max_heads * max_sectors)
> H =3D -----------------------------------
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 max_sectors
>
> S =3D LBA - ((C * max_heads * max_sectors) + (H * max_sectors)) + 1
>
> <snip>
>
> > Weird I know, but, I want to use my _own_ file system format. Starting
> > with a 30212 byte kernel with 512 byte boot loader preceding the
> > kernel and boot from that in a Virtual Machine like I have been doing.
>
> Try this (FASM syntax):
>
> use 16
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 =A0 =A0 =A0; test LBA support - we refuse to work w.o.
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 =A0 =A0 =A0mov ax,0x4100 =A0 =A0 =A0 =A0 =A0 =A0 ; AL =3D 00, AH =
=3D 41
> =A0 =A0 =A0 =A0 =A0mov bx,0x55AA =A0 =A0 =A0 =A0 =A0 =A0 ; BX =3D 55AA
> =A0 =A0 =A0 =A0 =A0mov dx,0x80 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; DL =3D 0x00 =
/ 0x01 =A0 floppy
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0; =
=A0 =A0 =A00x80...0x87 =A0 HD
> =A0 =A0 =A0 =A0 =A0int 0x13 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0; are we w=
illing to continue?
> =A0 =A0 =A0 =A0 =A0jc .lba
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 =A0 =A0 =A0; set required segments and registers
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 =A0 =A0 =A0cli =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; mi =
=3D off
> =A0 =A0 =A0 =A0 =A0mov bx,0x3000 =A0 =A0 =A0 =A0 =A0 =A0 ; BX =3D 3000 (I=
BOOT code)
> =A0 =A0 =A0 =A0 =A0mov si,0x7BC0 =A0 =A0 =A0 =A0 =A0 =A0 ; SI =3D 7BC0 (L=
BA parameter block)
> =A0 =A0 =A0 =A0 =A0xor ax,ax =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; AX =3D 000=
0 (used to clear)
> =A0 =A0 =A0 =A0 =A0mov ds,bx =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; DS =3D 300=
0
> =A0 =A0 =A0 =A0 =A0mov es,bx =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; ES =3D 300=
0
> =A0 =A0 =A0 =A0 =A0mov ss,bx =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; SS =3D 300=
0
> =A0 =A0 =A0 =A0 =A0mov sp,0xFFFE =A0 =A0 =A0 =A0 =A0 =A0 ; SP =3D FFFE
> =A0 =A0 =A0 =A0 =A0sti =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; mi =
=3D on
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 =A0 =A0 =A0; load IBOOT
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 =A0 =A0 =A0mov [si], =A0 =A0 =A0 word 0x10 ; structure size
> =A0 =A0 =A0 =A0 =A0mov [si + 0x02],word 0x35 ; 53 sectors
> =A0 =A0 =A0 =A0 =A0mov [si + 0x04],ax =A0 =A0 =A0 =A0; buffer offset
> =A0 =A0 =A0 =A0 =A0mov [si + 0x06],word 0x03 ; =A0 =A0 =A0 =A0segment (0x=
00030000)
> =A0 =A0 =A0 =A0 =A0mov [si + 0x08],word 0x0A ; DQ LBA loDD low
> =A0 =A0 =A0 =A0 =A0mov [si + 0x0A],ax =A0 =A0 =A0 =A0; =A0 =A0 =A0 =A0 =
=A0 =A0 high
> =A0 =A0 =A0 =A0 =A0mov [si + 0x0C],ax =A0 =A0 =A0 =A0; =A0 =A0 =A0 =A0hiD=
D low
> =A0 =A0 =A0 =A0 =A0mov [si + 0x0E],ax =A0 =A0 =A0 =A0; =A0 =A0 =A0 =A0 =
=A0 =A0 high
> =A0 =A0 =A0 =A0 =A0mov dl,0x80 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; DL =3D 1st H=
D
> =A0 =A0 =A0 =A0 =A0mov ah,0x42 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; AH =3D read
> =A0 =A0 =A0 =A0 =A0int 0x13 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0; read sec=
tors
> =A0 =A0 =A0 =A0 =A0jc .rde
> =A0 =A0 =A0 =A0 =A0jmp 0x3000:0000 =A0 =A0 =A0 =A0 =A0 ; start boot manag=
er
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 =A0 =A0 =A0; error handling
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 .rde:mov si,err1 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; SI =3D 00[msg1]
> =A0 =A0 =A0 =A0 =A0jmp .msg
> =A0 =A0 .lba:mov si,err0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; SI =3D 00[msg0]
> =A0 =A0 .msg:lodsb =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; retrieve cha=
r
> =A0 =A0 =A0 =A0 =A0xor bx,bx =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; BX =3D 00 =
(ignored in text mode)
> =A0 =A0 =A0 =A0 =A0mov ah,0x0E =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; AH =3D 0E
> =A0 =A0 =A0 =A0 =A0test al,al =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0; string end=
?
> =A0 =A0 =A0 =A0 =A0je .hang
> =A0 =A0 =A0 =A0 =A0int 0x10 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0; write ch=
ar in TTY mode
> =A0 =A0 =A0 =A0 =A0jmp .msg
> =A0 =A0.hang:nop
> =A0 =A0 =A0 =A0 =A0jmp .hang =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; freeze
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 =A0 =A0 =A0; messages
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 err0:DB "IBOOT cannot run without LBA aware BIOS!"
> =A0 =A0 =A0 =A0 =A0DB 00
> =A0 =A0 err1:DB "Read error - cannot load IBOOT!"
> =A0 =A0 =A0 =A0 =A0DB 00
>
> INT13, function 42 requires a structure like
> this:
>
> 00 DB =A0 structure size in byte
> 01 DB =A0 must be zero
> 02 DW =A0 blocks to transfer
> 04 DD =A0 address transfer buffer
> 08 DQ =A0 first LBA to transfer
>
> AH =A0 =A0=3D 0x42 (extended read)
> DL =A0 =A0=3D drive number
> DS:SI =3D address where structure is stored
>
> The number of blocks to transfer (word 0x02)
> might be limited by the BIOS. If so, use the
> allowed number, then repeat until the entire
> code is transferred. Just add max_sectors to
> the (quad)word at 0x08 and reset AH to 0x42.
> Call int 0x13 as often as required. The word
> at 0x02 probably needs a correction prior to
> the last call (less blocks to read).
>
> Change addresses and parameters to suit your
> needs. The code occupies 172 byte (fits into
> a standard MBR with plenty of room for other
> data below the partition table).
>
> Greetings from Augsburg
>
> Bernhard Schornak

Thanks Mr Schornak!

Actually, I've just realised I _had_ all the the LBACHS code already
as part of my original boot loader, so I attempted to use it ~ and it
boots, sort of?

61 LBACHS:
     62           xor     dx, dx                              ;
prepare dx:ax for operation
     63           div     WORD [bpbSectorsPerTrack]           ;
calculate
     64           inc     dl                                  ; adjust
for sector 0
     65           mov     BYTE [absoluteSector], dl
     66           xor     dx, dx                              ;
prepare dx:ax for operation
     67           div     WORD [bpbHeadsPerCylinder]          ;
calculate
     68           mov     BYTE [absoluteHead], dl
     69           mov     BYTE [absoluteTrack], al
     70           ret
72 ReadSectors:
     73      .MAIN:
     74           mov     di, 0x0005                          ; five
retries for error
     75      .SECTORLOOP:
     76           push    ax
     77           push    bx
     78           push    cx
     79           call    LBACHS                              ;
convert starting sector to CHS
     80           mov     ah, 0x02                            ; BIOS
read sector
     81           mov     al, 0x01                            ; read
one sector
     82           mov     ch, BYTE [absoluteTrack]            ; track
     83           mov     cl, BYTE [absoluteSector]           ; sector
     84           mov     dh, BYTE [absoluteHead]             ; head
     85           mov     dl, BYTE [bsDriveNumber]            ; drive
     86           int     0x13                                ; invoke
BIOS
     87           jnc     .SUCCESS                            ; test
for read error
     88           xor     ax, ax                              ; BIOS
reset disk
     89           int     0x13                                ; invoke
BIOS
     90           dec     di                                  ;
decrement error counter
     91           pop     cx
     92           pop     bx
     93           pop     ax
     94           jnz     .SECTORLOOP                         ;
attempt to read again
     95           int     0x18
     96      .SUCCESS:
     97           mov     si, msgProgress
     98           call    Print
     99           pop     cx
    100           pop     bx
    101           pop     ax
    102           add     bx, WORD [bpbBytesPerSector]        ; queue
next buffer
    103           inc     ax                                  ; queue
next sector
    104           loop    .MAIN                               ; read
next sector
    105           ret

These are the two functions that are required for floppy disk access.

 159 ;       xor di, di
    160         xor ax, ax
    161         int 0x13
    162         mov cx, 59
    163         mov ax, 0x0050
    164         mov es, ax
    165         xor bx, bx
    166         mov ax, 1
    167         call ReadSectors
    168         jmp FIN

This is how I call the ReadSectors function.

Well, it boots the kernel, but I remain getting an reset when the
kernel advances beyond 30208 bytes?

There are two scenarios here. One where I use the ReadSectors thing to
read 59 bytes, and it will boot a 30208 kernel, but with more nops it
boots but resets at the end of the code run.

The second is where I load 60 sectors, and that just doesn't even boot
up. I see the dots go across the screen stating disk accesses, but
when it comes to the final JMP it doesn't work and I get an error
message.

Can you think as to why the boot loader code above will work with 59
sectors, and _not_ 60?

Is there something to do with loading the 30212 byte kernel into RAM
location 0x0050:0000? Am I colliding with something _else_ in RAM,
like the stack?

If you need to see any more of my Kernel.asm source just ask.

Kind regards,

Cat
0
Reply obrzut.alex (64) 5/29/2011 8:18:12 AM

On May 29, 8:42=A0am, Bernhard Schornak <schor...@nospicedham.web.de>
wrote:
> catcalls wrote:
>
> <snip>
>
>
>
>
>
>
>
>
>
> > Basically, the bootloader is an 0x13 INT ah 0x02 deal that reads 59
> > sectors at once, starting at sector 2.
>
> > =A0 =A0 =A0165 =A0 =A0 =A0 =A0 mov ah, 0x02
> > =A0 =A0 =A0166 =A0 =A0 =A0 =A0 mov al, 59
> > =A0 =A0 =A0167 =A0 =A0 =A0 =A0 ;mov ch,0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; =
cylinder =3D 0
> > =A0 =A0 =A0168 =A0 =A0 =A0 =A0 mov ch, 0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; =
sector =3D 2 (starts at sector
> > 1 not 0)
> > =A0 =A0 =A0169 =A0 =A0 =A0 =A0 mov cl, 2
> > =A0 =A0 =A0170 =A0 =A0 =A0 =A0 mov dl,[bsDriveNumber] =A0; disk =3D wha=
t we booted from
> > =A0 =A0 =A0171 =A0 =A0 =A0 =A0 int 0x13 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
; read it
> > =A0 =A0 =A0172 =A0 =A0 =A0 =A0 jc read_me
> > =A0 =A0 =A0173 FIN:
>
> > This is the code. Please excuse the line numbers!
>
> > AH is the read function of INT 0x13
> > AL is the number of sectors to read.
> > CH is the cylinder or track of the floppy
> > CL is the location sector on floppy to start the floppy disk read.
> > DL is the drive number, DH is unknown to me at this point in time!
>
> DH =3D head number (0 or 1 for floppy, 0...255
> for HD)
>
> > Well, I know a carry is thrown on error. Hence the jc read_me to
> > attempt another read.
>
> If CF is set, AH holds the error code and AL
> the number of properly transferred sectors.
>
> > But, all in all, this works fine and boots my Kernel when it is 30208
> > bytes in size.
>
> 59 * 512 =3D 30208
>
> > How ever, the problem arose when the kernel grew to 30212 Bytes. It
> > wouldn't load any more.
>
> Four byte too much?
>
> > So, looking into the boot loader, I discovered the fact that I was
> > reading 59 sectors at once. _And_ it is not possible to read 60 at
> > once as it is not supported by my CPU.
>
> > This leads to the conclusion I require a simple boot loader example
> > that reads a single sector at a time, does not work with the FAT file
> > system but a flat binary file system, and basically explains the CHS
> > to me.
>
> > I also know about LBA (Large Block Mode) where this is different to
> > CHS, but, how?
>
> It allows larger capacities:
>
> CHS: 512 * 63 * 256 * 1,024 =3D =A0 =A0 8,455,716,864 byte
> LBA: 512 * 4,294,967,295 =A0 =A0=3D 2,199,023,255,040 byte
>
> CHS to LBA:
>
> LBA =3D (C * max_heads * max_sectors) + (H * max_sectors) + (S - 1)
>
> LBA to CHS:
>
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 LBA
> C =3D -----------------------
> =A0 =A0 =A0max_heads * max_sectors
>
> =A0 =A0 =A0LBA - (C * max_heads * max_sectors)
> H =3D -----------------------------------
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 max_sectors
>
> S =3D LBA - ((C * max_heads * max_sectors) + (H * max_sectors)) + 1
>
> <snip>
>
> > Weird I know, but, I want to use my _own_ file system format. Starting
> > with a 30212 byte kernel with 512 byte boot loader preceding the
> > kernel and boot from that in a Virtual Machine like I have been doing.
>
> Try this (FASM syntax):
>
> use 16
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 =A0 =A0 =A0; test LBA support - we refuse to work w.o.
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 =A0 =A0 =A0mov ax,0x4100 =A0 =A0 =A0 =A0 =A0 =A0 ; AL =3D 00, AH =
=3D 41
> =A0 =A0 =A0 =A0 =A0mov bx,0x55AA =A0 =A0 =A0 =A0 =A0 =A0 ; BX =3D 55AA
> =A0 =A0 =A0 =A0 =A0mov dx,0x80 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; DL =3D 0x00 =
/ 0x01 =A0 floppy
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0; =
=A0 =A0 =A00x80...0x87 =A0 HD
> =A0 =A0 =A0 =A0 =A0int 0x13 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0; are we w=
illing to continue?
> =A0 =A0 =A0 =A0 =A0jc .lba
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 =A0 =A0 =A0; set required segments and registers
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 =A0 =A0 =A0cli =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; mi =
=3D off
> =A0 =A0 =A0 =A0 =A0mov bx,0x3000 =A0 =A0 =A0 =A0 =A0 =A0 ; BX =3D 3000 (I=
BOOT code)
> =A0 =A0 =A0 =A0 =A0mov si,0x7BC0 =A0 =A0 =A0 =A0 =A0 =A0 ; SI =3D 7BC0 (L=
BA parameter block)
> =A0 =A0 =A0 =A0 =A0xor ax,ax =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; AX =3D 000=
0 (used to clear)
> =A0 =A0 =A0 =A0 =A0mov ds,bx =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; DS =3D 300=
0
> =A0 =A0 =A0 =A0 =A0mov es,bx =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; ES =3D 300=
0
> =A0 =A0 =A0 =A0 =A0mov ss,bx =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; SS =3D 300=
0
> =A0 =A0 =A0 =A0 =A0mov sp,0xFFFE =A0 =A0 =A0 =A0 =A0 =A0 ; SP =3D FFFE
> =A0 =A0 =A0 =A0 =A0sti =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; mi =
=3D on
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 =A0 =A0 =A0; load IBOOT
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 =A0 =A0 =A0mov [si], =A0 =A0 =A0 word 0x10 ; structure size
> =A0 =A0 =A0 =A0 =A0mov [si + 0x02],word 0x35 ; 53 sectors
> =A0 =A0 =A0 =A0 =A0mov [si + 0x04],ax =A0 =A0 =A0 =A0; buffer offset
> =A0 =A0 =A0 =A0 =A0mov [si + 0x06],word 0x03 ; =A0 =A0 =A0 =A0segment (0x=
00030000)
> =A0 =A0 =A0 =A0 =A0mov [si + 0x08],word 0x0A ; DQ LBA loDD low
> =A0 =A0 =A0 =A0 =A0mov [si + 0x0A],ax =A0 =A0 =A0 =A0; =A0 =A0 =A0 =A0 =
=A0 =A0 high
> =A0 =A0 =A0 =A0 =A0mov [si + 0x0C],ax =A0 =A0 =A0 =A0; =A0 =A0 =A0 =A0hiD=
D low
> =A0 =A0 =A0 =A0 =A0mov [si + 0x0E],ax =A0 =A0 =A0 =A0; =A0 =A0 =A0 =A0 =
=A0 =A0 high
> =A0 =A0 =A0 =A0 =A0mov dl,0x80 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; DL =3D 1st H=
D
> =A0 =A0 =A0 =A0 =A0mov ah,0x42 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; AH =3D read
> =A0 =A0 =A0 =A0 =A0int 0x13 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0; read sec=
tors
> =A0 =A0 =A0 =A0 =A0jc .rde
> =A0 =A0 =A0 =A0 =A0jmp 0x3000:0000 =A0 =A0 =A0 =A0 =A0 ; start boot manag=
er
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 =A0 =A0 =A0; error handling
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 .rde:mov si,err1 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; SI =3D 00[msg1]
> =A0 =A0 =A0 =A0 =A0jmp .msg
> =A0 =A0 .lba:mov si,err0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; SI =3D 00[msg0]
> =A0 =A0 .msg:lodsb =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; retrieve cha=
r
> =A0 =A0 =A0 =A0 =A0xor bx,bx =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; BX =3D 00 =
(ignored in text mode)
> =A0 =A0 =A0 =A0 =A0mov ah,0x0E =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; AH =3D 0E
> =A0 =A0 =A0 =A0 =A0test al,al =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0; string end=
?
> =A0 =A0 =A0 =A0 =A0je .hang
> =A0 =A0 =A0 =A0 =A0int 0x10 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0; write ch=
ar in TTY mode
> =A0 =A0 =A0 =A0 =A0jmp .msg
> =A0 =A0.hang:nop
> =A0 =A0 =A0 =A0 =A0jmp .hang =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ; freeze
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 =A0 =A0 =A0; messages
> =A0 =A0 =A0 =A0 =A0; ------------------------------------------
> =A0 =A0 err0:DB "IBOOT cannot run without LBA aware BIOS!"
> =A0 =A0 =A0 =A0 =A0DB 00
> =A0 =A0 err1:DB "Read error - cannot load IBOOT!"
> =A0 =A0 =A0 =A0 =A0DB 00
>
> INT13, function 42 requires a structure like
> this:
>
> 00 DB =A0 structure size in byte
> 01 DB =A0 must be zero
> 02 DW =A0 blocks to transfer
> 04 DD =A0 address transfer buffer
> 08 DQ =A0 first LBA to transfer
>
> AH =A0 =A0=3D 0x42 (extended read)
> DL =A0 =A0=3D drive number
> DS:SI =3D address where structure is stored
>
> The number of blocks to transfer (word 0x02)
> might be limited by the BIOS. If so, use the
> allowed number, then repeat until the entire
> code is transferred. Just add max_sectors to
> the (quad)word at 0x08 and reset AH to 0x42.
> Call int 0x13 as often as required. The word
> at 0x02 probably needs a correction prior to
> the last call (less blocks to read).
>
> Change addresses and parameters to suit your
> needs. The code occupies 172 byte (fits into
> a standard MBR with plenty of room for other
> data below the partition table).
>
> Greetings from Augsburg
>
> Bernhard Schornak

Yes. I did take a look at the Extended Read Function from a Wiki
somewhere?

Nice to see some working code too.

I've yet to try your code, but this is what I think my code using your
code will look like;

mov [si],       word 0x10 ; structure size
         mov [si + 0x02],word 0x3C ; 60 sectors
         mov [si + 0x04],ax        ; buffer offset
         mov [si + 0x06],word 0x03 ;        segment (0x00030000)
         mov [si + 0x08],word 0x02 ; DQ LBA loDD low
         mov [si + 0x0A],ax        ;             high
         mov [si + 0x0C],ax        ;        hiDD low
         mov [si + 0x0E],ax        ;             high
         mov dl,0x80               ; DL =3D 1st HD
         mov ah,0x42               ; AH =3D read
         int 0x13                  ; read sectors

I can load at segment 0x00030000 but doesn't that effect the workings
of the OS? I heard OS'es have to be lined up in RAM in the beginning
for segmentation reasons? Or is that old facts gone wrong?

Do you know for sure that I can jump to that segment with a standard
kernel/os code?

I guess there is only one way to find that out I think...

O.K. ~ Please ignore my previous post. I'll def. try this new code
out. Perhaps it'll explains to me why the code is not successfully
working any more.

Kind regards as always,

Cat
0
Reply obrzut.alex (64) 5/29/2011 8:27:38 AM

31 Main:
     32          ; ------------------------------------------
     33          ; set required segments and registers
     34          ; ------------------------------------------
     35          cli                       ; mi = off
     36          mov bx,0x0050             ; BX = 3000 (IBOOT code)
     37          mov si,0x7BC0             ; SI = 7BC0 (LBA parameter
block)
     38          xor ax,ax                 ; AX = 0000 (used to clear)
     39          mov ds,bx                 ; DS = 3000
     40          mov es,bx                 ; ES = 3000
     41          mov ss,bx                 ; SS = 3000
     42          mov sp,0xFFFE             ; SP = FFFE
     43 ;        push dx
     44          sti                       ; mi = on
     45         push dx
     46 ;       call TestLBA
     47         ; ------------------------------------------
     48          ; load IBOOT
     49          ; ------------------------------------------
     50          mov [si],       word 0x10 ; structure size
     51          mov [si + 0x02],word 0x003b ; 60 sectors
     52          mov [si + 0x04],ax        ; buffer offset
     53          mov [si + 0x06],word 0x0050 ;        segment
(0x00030000)
     54          mov [si + 0x08],word 0x0001 ; DQ LBA loDD low
     55          mov [si + 0x0A],ax        ;             high
     56          mov [si + 0x0C],ax        ;        hiDD low
     57          mov [si + 0x0E],ax        ;             high
     58         pop dx
     59        ;  mov dl,0x80               ; DL = 1st HD
     60          mov ah,0x42               ; AH = read
     61          int 0x13                  ; read sectors
     62          jc Error.rde
     63            push    WORD 0x0050
     64            push    WORD 0x0000
     65            retf

This is your code that I modified. Can you see why it isn't loading?
This is really strange! Nothing happens on boot... I must be doing
something wrong :(

Cat
0
Reply obrzut.alex (64) 5/29/2011 8:46:46 AM

Bernhard Schornak answered catcalls:

right answer, and I may add to the confusion and refresh my
memory on CHS issues :)
....
>> I also know about LBA (Large Block Mode) where this is different to
>> CHS, but, how?

> It allows larger capacities:

> CHS: 512 * 63 * 256 * 1,024 =     8,455,716,864 byte

BIOS INT13 addressing in bit-format ie: READ_Sectors FN02h:

AH = 02        FN: read sectors
AL = bit 0..7  sectors to read (00 may not do anything)*
CH = bit 0..7  low 8 bits of Cylinder-number
CL = bit 0..5  Sector-Number (1..63 ;0 is illegal)
     bit 6,7   are bit 8 and 9 of Cylinder-Number
DH = bit 0..7  head number (0..255 on HD, but only 0 and 1 for FD)
DL = bit 0..6  BIOS-assigned DRIVE-Number
     bit 7     1 = fixed, 0 = removable media

I never understood why this BIOS INT13 format limits itself
to 24 address-bits and is that different to what the hardware
actually know (28 address bits in CHS and LBA mode) ie:
first master IDE HD in CHS mode:

port 01f0     16 or 32bits wide DATA-port
     01f1     wr features/rd error
     01f2     sector count  (1..255 "0=256" in opposition to BIOS*)
     01f3     sector number (1..255  0 is illegal)
     01f4     low 8 bits of cylinder number   ;also possible:
     01f5     high 8 bits of cylinder number  ;OUT word TrackNr
     01f6  b0..3   head number  (0..15)
           b4  = 0  drive (0=master 1=slave)
           b5  = 1
           b6  = 0   yet  MODE (0=CHS  1=LBA)
           b7  = 1
     01f7    wr COMMAND/rd STATUS (ie wr 20h for read sectors)

going the hardware way, CHS addressing allow access for

512 * 255 * 65536 * 16 = 136,902,082,560 = 127.5 GB

differences to the above for LBA28-mode:

    01f3         LBA bit 0..7   (LBA sector0 exists == CHS sector1)
    01f4         LBA bit 8..15
    01f5         LBA bit 16..23
    01f6  b0..3  LBA bit 24..27
          b4 = 0  master
          b5 = 1
          b6 = 1 for LBA-mode then
          b7 = 1

> LBA: 512 * 4,294,967,295    = 2,199,023,255,040 byte

Unfortunately we got only 28 LBA bits in standard LBA :)  == 128 GB
With LBA-48, which the BIOS may support or not, we got  128*1024 TB.

> CHS to LBA:
> LBA = (C * max_heads * max_sectors) + (H * max_sectors) + (S - 1)

> LBA to CHS:
>              LBA
> C = -----------------------
>     max_heads * max_sectors
>
>
>     LBA - (C * max_heads * max_sectors)
> H = -----------------------------------
>              max_sectors
>
> S = LBA - ((C * max_heads * max_sectors) + (H * max_sectors)) + 1

I never checked if this is correct, but my docs tell the same :)
__
wolfgang


0
Reply nowhere583 (184) 5/29/2011 11:03:47 AM

Hi Wolfgang,

This is my LBACHS routine now I've read your LBA2CHS formula...isn't
tested yet but prolly need work!

     61 LBACHS:
     62           push ax
     63           ; Now calculate Cylinder first (LBA /
(max_heads*max_sectors))
     64           mov bx, 2        ; max no. of heads
     65           mov ax, 18       ; max no. of sectors
     66           mul bx           ; mul > ax:dx
     67           push ax          ; store result
     68           pop bx           ; move result into bx
     69           pop ax           ; restore LBA
     70           push ax          ; store LBA
     71           div bx           ; div > ax:dx
     72           mov BYTE [absoluteTrack], al ; store Cylinder
     73           pop ax           ; restore LBA
     74           push ax          ; store LBA
     75           ; Now Calculate Head second (LBA -
(C*max_heads*max_sectors)/max_sectors)
     76           mov ax, 2        ; max no. of heads
     77           mov bx, 18       ; max. no. of sectors
     78           mul bx           ; mul > ax:dx
     79           xor bx, bx       ; zero bx
     80           mov bl, BYTE [absoluteTrack] ; move Cylinder into bl
     81           mul bx           ; mul > ax:dx
     82           mov bx, ax       ; move result into bx
     83
     84           pop ax           ; restore LBA
     85           push ax
     86           sub ax, bx       ; sub from LBA (C * max_heads *
max_sectors)
     87           xor     dx, dx   ; prepare dx:ax for operation
     88           div     WORD [bpbSectorsPerTrack]
     89           mov BYTE [absoluteHead], dl ; store Head
     90           ; Now calculate Sector last
(C*max_heads*max_sectors)
     91           mov ax, 2        ; max no. of heads
     92           mov bx, 18       ; max no. of sectors
     93           mul bx           ; mul > ax:dx
     94           xor bx, bx       ; zero bx
     95           mov bl, BYTE [absoluteTrack] ; move in bl Cylinder
     96           mul bx           ; mul > ax:dx
     97           push ax          ; store result
     98           ; Calculate (Head*max_sectors)+1
     99           xor ax, ax       ; zero ax
    100           mov al, BYTE [absoluteHead] ; move in al Head
    101           mov bx, 18       ; max no. of sectors
    102           mul bx           ; mul > ax:dx
    103           mov bx, ax       ; move result into bx
    104           pop ax           ; restore result of
(C*max_heads*max_sectors)
    105           add ax, bx       ; add together two results
    106           inc ax, 1        ; add one
    107           mov bx, ax       ; move sum into bx
    108           pop ax           ; restore LBA
    109           sub ax, bx       ; Calculate LBA -
((C*max_heads*max_sectors) + (H*max_sectors)) + 1
    110           mov BYTE [absoluteSector], al ; store Sector
    111           ret

The original looked like this;

     48 ;************************************************;
     49 ; Convert LBA to CHS
     50 ; AX=>LBA Address to convert
     51 ;
     52 ; absolute sector = (logical sector / sectors per track) + 1
     53 ; absolute head   = (logical sector / sectors per track) MOD
number of heads
     54 ; absolute track  = logical sector / (sectors per track *
number of heads)
     55 ;
     56 ;************************************************;
     57
     58 LBACHS:
     59           xor     dx, dx                              ;
prepare dx:ax for operation
     60           div     WORD [bpbSectorsPerTrack]           ;
calculate
     61           inc     dl                                  ; adjust
for sector 0
     62           mov     BYTE [absoluteSector], dl
     63           xor     dx, dx                              ;
prepare dx:ax for operation
     64           div     WORD [bpbHeadsPerCylinder]          ;
calculate
     65           mov     BYTE [absoluteHead], dl
     66           mov     BYTE [absoluteTrack], al
     67           ret

Surely that would not work!? For a start there are no multiplies?
Weird that its been working so far, eh?

Well, I'm off to test my asm...

Cat
0
Reply obrzut.alex (64) 5/29/2011 1:11:38 PM

Hi guys,

I have been following this thread a little.  I even posted
a reply to what I think might be happening, but for some
reason, it didn't get through.  I will attach my previous
post here:

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
"catcalls" <obrzut.alex@nospicedham.gmail.com> wrote in message
news:ba4c4b9e-127f-42fb-bc31-84a3b1ac6cba@s2g2000yql.googlegroups.com...
> [30208 May 28 12:33 kernel.sys] : This is the number of bytes that is
> _allowed_ with my boot loader. When I 'nop' the kernel to 30209 bytes
> or higher, the virtual machine resets. Why is this?
>
> My Operating System written in Assembler works great when it is 30208
> bytes in size, but one byte more, or one nop more, and boom! Reset.
>
> Totally baffles me. Does anyone here have any light to shed on the
> matter?
>
> Thank you sincerely in advance,

I had a similar situation one time.  Could not figure
it out.  However, once I looked at where my stack was,
it hit me.

Let's look at the registers.

If you have CS=DS=ES=SS = 0x0000 and SP = 0xFFFE and IP = 0x7C00
at boot start, and you have used a little bit of the stack, then
just before the read, let's say that your stack is now at
SS:SP = 0x0000:E800.  When you read the 53 sectors to 0x0000:7E00,
you now write to 0x0000:7E00 through 0x0000:E7FF.

Reading one more sector will now overwrite you stack and on return
from the read routine, your return will pull an invalid return address
off the now overwritten stack.
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


I don't know if that is your problem or not, but it is worth a
look.

Also, might I suggest that you post your binary image somewhere
so that we may look at the "whole picture".  Or at least, all
of the code and instructions on how to build it.

There are many sites that allow free uploads.

You can even send the binary to my email address and I will
have a look at it.  (instructions for email are below).

Also, if you don't mind, might I suggest that if the prevoius
post, the reply post with all the previous content to it, is
fairly long and is not immediately revelant to the new text,
please cut or <snip> a majority of it so that your new text
is not 500 lines to scroll.

Thank you,
Ben

-- 
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Forever Young Software
http://www.fysnet.net/index.htm
http://www.fysnet.net/collections.htm
To reply by email, please remove the zzzzzz's

Batteries not included, some assembly required.

0
Reply zfysz3716 (6) 5/29/2011 3:42:40 PM

catcalls wrote:


> Actually, I've just realised I _had_ all the the LBACHS code already
> as part of my original boot loader, so I attempted to use it ~ and it
> boots, sort of?
>
> LBACHS:
>             xor     dx, dx                              ; prepare dx:ax for operation
>             div     WORD [bpbSectorsPerTrack]           ; calculate
>             inc     dl                                  ; adjust for sector 0
>             mov     BYTE [absoluteSector], dl
>             xor     dx, dx                              ; prepare dx:ax for operation
>             div     WORD [bpbHeadsPerCylinder]          ; calculate
>             mov     BYTE [absoluteHead], dl
>             mov     BYTE [absoluteTrack], al
>             ret


CHS to LBA:

--------------
IN : nothing
OUT: EAX = LBA
--------------

xor   eax,eax                  ; better use dwords - saves
xor   ebx,ebx                  ; to clear the upper parts
xor   ecx,ecx                  ; of all registers
xor   edx,edx
xor   ebp,ebp
mov   bx,word[Head]            ; EBX = requested head
mov   cl,byte[Cylinder]        ; ECX =           cylinder
mov   dl,byte[Sector]          ; EDX =           sector
mov   bp,word[MaxHeads]        ; EBP = BIOS max_heads
mov   al,byte[MaxSectors]      ; EAX =      max_sectors
imul  ebp,eax                  ; EBP = sectors per  cylinder
imul  eax,ebx                  ; EAX = sectors this cylinder
imul  ecx,ebp                  ; ECX = sectors full cylinders
dec   edx                      ; EDX - 1 (zero based sector)
add   eax,ecx                  ; EAX = full + this cylinder
add   eax,edx                  ; EAX = LBA


LBA to CHS:

--------------
IN : EAX = LBA
OUT: EAX = H
      ECX = C
      EDX = S
--------------

xor   ebx,ebx
xor   ecx,ecx
xor   edx,edx                  ; div!
mov   cx,word[MaxHeads]        ; ECX = BIOS max_heads
mov   bl,byte[MaxSectors]      ; EAX =      max_sectors
imul  ecx,ebx                  ; ECX = sectors per cylinder
div   ecx                      ; LBA / sectors per cylinder
mov   ecx,eax                  ; ECX = C
mov   eax,edx                  ; EAX = remainder
xor   edx,edx                  ; div!
div   ebx                      ; remainder / max_sectors
inc   edx                      ; EAX = H
                                ; EDX = S (base one!)

> ReadSectors:
> .MAIN:
>             mov     di, 0x0005                          ; five retries for error
> .SECTORLOOP:
>             push    ax
>             push    bx
>             push    cx
>             call    LBACHS                              ; convert starting sector to CHS
>             mov     ah, 0x02                            ; BIOS read sector
>             mov     al, 0x01                            ; read one sector
>             mov     ch, BYTE [absoluteTrack]            ; track
>             mov     cl, BYTE [absoluteSector]           ; sector
>             mov     dh, BYTE [absoluteHead]             ; head
>             mov     dl, BYTE [bsDriveNumber]            ; drive
>             int     0x13                                ; invoke BIOS
>             jnc     .SUCCESS                            ; test for read error
>             xor     ax, ax                              ; BIOS reset disk
>             int     0x13                                ; invoke BIOS
>             dec     di                                  ; decrement error counter
>             pop     cx
>             pop     bx
>             pop     ax
>             jnz     .SECTORLOOP                         ; attempt to read again
>             int     0x18
> .SUCCESS:
>             mov     si, msgProgress
>             call    Print
>             pop     cx
>             pop     bx
>             pop     ax
>             add     bx, WORD [bpbBytesPerSector]        ; queue next buffer
>             inc     ax                                  ; queue next sector
>             loop    .MAIN                               ; read next sector
>             ret
>
> These are the two functions that are required for floppy disk access.
>
>             xor di, di
>             xor ax, ax
>             int 0x13
>             mov cx, 59
>             mov ax, 0x0050
>             mov es, ax
>             xor bx, bx
>             mov ax, 1
>             call ReadSectors
>             jmp FIN
>
> This is how I call the ReadSectors function.
>
> Well, it boots the kernel, but I remain getting an reset when the
> kernel advances beyond 30208 bytes?

Do you update the address of your transfer buffer
properly? Maybe you overwrite already transferred
parts with the last read sectors? I don't see any
address references in your snippets...

> There are two scenarios here. One where I use the ReadSectors thing to
> read 59 bytes, and it will boot a 30208 kernel, but with more nops it
> boots but resets at the end of the code run.
>
> The second is where I load 60 sectors, and that just doesn't even boot
> up. I see the dots go across the screen stating disk accesses, but
> when it comes to the final JMP it doesn't work and I get an error
> message.

Do you set all segment registers to the new start
of the loaded code? What about the SS:SP pair?

> Can you think as to why the boot loader code above will work with 59
> sectors, and _not_ 60?

Might be a hardware restriction to 59 sectors per
cylinder. AFAIK, the used interrupt does not read
data beyond cylinder boundaries.

> Is there something to do with loading the 30212 byte kernel into RAM
> location 0x0050:0000? Am I colliding with something _else_ in RAM,
> like the stack?

Memory below 0x0600:0000 holds several tables and
other important stuff! Use memory in the range of
0x1000:0000 ... 0x7000:FFFF for safety's sake.

You can set up your stack at any memory location,
but you should leave sufficient room below (stack
grows downwards).


Greetings from Augsburg

Bernhard Schornak
0
Reply schornak1 (82) 5/29/2011 4:52:11 PM

Hi Ben,

I am unsure how to edit my previous post. I am using Google Groups.

My stack is located at ss:0x9000 sp:0xFFFF inside the boot loader.

When I changed this to ss:0x0000 sp:0xFFFF I get a boot but I think
there might be issues with multi-tasking and making two JMP at the end
of the kernel to write out a 'H' and letter 'B' to the screen in two
separate routines jumping to one another. This causes some errors or
halts the runtime.

So, after all this time messing about with my boot code, it appears
Ben is correct with the stack issue.

At least now I can boot a 30211 kernel.sys image!

Oh, and the code _is_ for sale for =A39.95 ~ It is called Lita's OS and
can be found on Google.

Kind regards,

Cat
0
Reply obrzut.alex (64) 5/29/2011 4:52:13 PM

catcalls wrote:

....
> My stack is located at ss:0x9000 sp:0xFFFF inside the boot loader.
....
> Oh, and the code _is_ for sale for =A39.95 ~ It is called Lita's OS and
> can be found on Google.

I can't think of anything to say, suitable for a family NG.

Best,
Frank

0
Reply fbkotler9831 (124) 5/29/2011 5:15:06 PM

catcalls wrote:


<snip>

> I've yet to try your code, but this is what I think my code using your
> code will look like;
>
> mov [si],       word 0x10 ; structure size
>           mov [si + 0x02],word 0x3C ; 60 sectors
>           mov [si + 0x04],ax        ; buffer offset
>           mov [si + 0x06],word 0x03 ;        segment (0x00030000)
>           mov [si + 0x08],word 0x02 ; DQ LBA loDD low
>           mov [si + 0x0A],ax        ;             high
>           mov [si + 0x0C],ax        ;        hiDD low
>           mov [si + 0x0E],ax        ;             high
>           mov dl,0x80               ; DL = 1st HD
>           mov ah,0x42               ; AH = read
>           int 0x13                  ; read sectors

Does your image start at cylinder 0, head 0, sector 3
(used LBA translated to CHS) on your first HD?

> I can load at segment 0x00030000 but doesn't that effect the workings
> of the OS? I heard OS'es have to be lined up in RAM in the beginning
> for segmentation reasons? Or is that old facts gone wrong?

Depends on the size of your kernel. If it is -larger-
than 393,216 byte, use a lower start address. My code
(as a boot manager) stores partition info below. Feel
free to change the location to whatever you want, but
don't forget to update your segment registers to that
address, as well!

> Do you know for sure that I can jump to that segment with a standard
> kernel/os code?

Depends on your design. Most recent operating systems
sit above the first MB. Memory below just is used for
the first stage (set up tables, switch to protected /
long mode, load second stage somewhere above 1 MB and
finally jump to that code).


Greetings from Augsburg

Bernhard Schornak
0
Reply schornak1 (82) 5/29/2011 5:37:33 PM

"catcalls" posted:

> Hi Wolfgang,

Hello,

> This is my LBACHS routine now I've read your LBA2CHS formula...isn't
> tested yet but prolly need work!

this formula posted by Bernhard is part of the docs (so not mine).

Your code snips seem to lack on correct size of LBA-range (28/48 bit),
and it seems to be for floppies where LBA isn't supported at all,
neither in BIOS nor by hardware, even DMA setup needs a linear range.

Modern HDs got a fake geometry to satisfy low end BIOS needs
with 63 sectors/track and a faked head-number up to 255 which
actually became translated into cylinder-bits if above 15.

18 sectors, 2 heads and 80 tracks may fit one certain MFM FD-format,
but there are many others as well, including C64-like variable
sectors/track (innermost got lesser sectors).

x86 BIOS may support FD formats:
single/double 160k 180k 320k 360k 720k 760k 1.44M 2.88M and more,
but emulated disk sizes will need a special loader to translate it.

__
wolfgang


0
Reply nowhere583 (184) 5/29/2011 6:23:33 PM

wolfgang kern wrote:


> Bernhard Schornak answered catcalls:
>
> right answer, and I may add to the confusion and refresh my
> memory on CHS issues :)
> ...
>>> I also know about LBA (Large Block Mode) where this is different to
>>> CHS, but, how?
>
>> It allows larger capacities:
>
>> CHS: 512 * 63 * 256 * 1,024 =     8,455,716,864 byte
>
> BIOS INT13 addressing in bit-format ie: READ_Sectors FN02h:
>
> AH = 02        FN: read sectors
> AL = bit 0..7  sectors to read (00 may not do anything)*
> CH = bit 0..7  low 8 bits of Cylinder-number
> CL = bit 0..5  Sector-Number (1..63 ;0 is illegal)
>       bit 6,7   are bit 8 and 9 of Cylinder-Number
> DH = bit 0..7  head number (0..255 on HD, but only 0 and 1 for FD)
> DL = bit 0..6  BIOS-assigned DRIVE-Number
>       bit 7     1 = fixed, 0 = removable media

Seems, I missed the bit 7 stuff in DL... ;)

> I never understood why this BIOS INT13 format limits itself
> to 24 address-bits and is that different to what the hardware
> actually know (28 address bits in CHS and LBA mode) ie:
> first master IDE HD in CHS mode:
>
> port 01f0     16 or 32bits wide DATA-port
>       01f1     wr features/rd error
>       01f2     sector count  (1..255 "0=256" in opposition to BIOS*)
>       01f3     sector number (1..255  0 is illegal)
>       01f4     low 8 bits of cylinder number   ;also possible:
>       01f5     high 8 bits of cylinder number  ;OUT word TrackNr
>       01f6  b0..3   head number  (0..15)
>             b4  = 0  drive (0=master 1=slave)
>             b5  = 1
>             b6  = 0   yet  MODE (0=CHS  1=LBA)
>             b7  = 1
>       01f7    wr COMMAND/rd STATUS (ie wr 20h for read sectors)
>
> going the hardware way, CHS addressing allow access for
>
> 512 * 255 * 65536 * 16 = 136,902,082,560 = 127.5 GB
>
> differences to the above for LBA28-mode:
>
>      01f3         LBA bit 0..7   (LBA sector0 exists == CHS sector1)
>      01f4         LBA bit 8..15
>      01f5         LBA bit 16..23
>      01f6  b0..3  LBA bit 24..27
>            b4 = 0  master
>            b5 = 1
>            b6 = 1 for LBA-mode then
>            b7 = 1
>
>> LBA: 512 * 4,294,967,295    = 2,199,023,255,040 byte
>
> Unfortunately we got only 28 LBA bits in standard LBA :)  == 128 GB
> With LBA-48, which the BIOS may support or not, we got  128*1024 TB.

Probably an issue of sparse room in the MBR's
partition record. If you write FEFFFF to both
encoded CHS entries, LBA entries 0x08 (start)
and 0x0C (size) determine start and size of a
partition.

Do you remember the huge 10 MB harddisks sold
with the first XT? Back in those times, every
byte stored on mass media was quite expensive
and valuable, so it makes sense if they tried
to save as much space as possible.

>> CHS to LBA:
>> LBA = (C * max_heads * max_sectors) + (H * max_sectors) + (S - 1)
>
>> LBA to CHS:
>>               LBA
>> C = -----------------------
>>      max_heads * max_sectors
>>
>>
>>      LBA - (C * max_heads * max_sectors)
>> H = -----------------------------------
>>               max_sectors
>>
>> S = LBA - ((C * max_heads * max_sectors) + (H * max_sectors)) + 1
>
> I never checked if this is correct, but my docs tell the same :)

Part of some "disktools" I had to write after
Windoze changed the geometry of my boot drive
to funny values. Unfortunately, OS/2 couldn't
be booted with them. I had to write some code
to restore the original geometry (CHS values)
to be able to boot OS/2, again... ;)


Greetings from Augsburg

Bernhard Schornak
0
Reply schornak1 (82) 5/29/2011 6:32:24 PM

catcalls offered:

....
|Oh, and the code _is_ for sale for �9.95 ~ It is called Lita's OS and
|can be found on Google.

OMG, Bill Gates can learn a lot from you !
First sell it and lateron develope and debug it !
I doubt that you achieve any earnings on your primature attempts :)
__
wolfgang


0
Reply nowhere583 (184) 5/29/2011 6:34:55 PM

Bernhard Schornak repiled:
....
>> DL = bit 0..6  BIOS-assigned DRIVE-Number
>>       bit 7     1 = fixed, 0 = removable media

> Seems, I missed the bit 7 stuff in DL... ;)

It's from older specification, we now see also CD/DVD reported
with drive numbers above 7fh/


>> I never understood why this BIOS INT13 format limits itself
>> to 24 address-bits
....
> Probably an issue of sparse room in the MBR's
> partition record. If you write FEFFFF to both
> encoded CHS entries, LBA entries 0x08 (start)
> and 0x0C (size) determine start and size of a
> partition.

Yeah, that may have once been the cause for the restriced addressing.

> Do you remember the huge 10 MB harddisks sold
> with the first XT? Back in those times, every
> byte stored on mass media was quite expensive
> and valuable, so it makes sense if they tried
> to save as much space as possible.

right, OTOH partition entries were 32 bytes 'large' since I know
about, but it wouldn't have hurt from the very begin to renounce
of the double featured CHS and LBA entries for start/end/size.

>>> CHS to LBA:
.....
>> I never checked if this is correct, but my docs tell the same :)

> Part of some "disktools" I had to write after
> Windoze changed the geometry of my boot drive
> to funny values. Unfortunately, OS/2 couldn't
> be booted with them. I had to write some code
> to restore the original geometry (CHS values)
> to be able to boot OS/2, again... ;)

I'm glad for I can ignore all CHS info since a while,
HD geometry became a fiction since long anyway,
even USB-FD-images can be treated in a linear matter.
__
wolfgang


0
Reply nowhere583 (184) 5/29/2011 7:03:21 PM

"wolfgang kern" wrote in message

> I'm glad for I can ignore all CHS info since a while,
> HD geometry became a fiction since long anyway,
> even USB-FD-images can be treated in a linear matter.

On most PC's with a fairly recent BIOS this will be the case.
However on some BIOS/version where the UFD is BIOS emulated as FD
the BIOS does not provide LBA access for drive identifier "0".
Some BIOS/version will BIOS emulate a UFD under 1GB as FD, while
the same BIOS/version will BIOS emulate a UFD 1GB and above as HD.
Even with UFD BIOS emulation as HD a FD image can be accessed
with the correct CHS provided by INT 13h, function 8 - Get Drive
Parameters or with the INT 13h extensions if available.


Mike Gonta
look and see - many look but few see

http://aeBIOS.com


0
Reply mikegonta3947 (9) 5/29/2011 7:58:30 PM

wolfgang kern's worte:


> Bernhard Schornak repiled:
> ...
>>> DL = bit 0..6  BIOS-assigned DRIVE-Number
>>>        bit 7     1 = fixed, 0 = removable media
>
>> Seems, I missed the bit 7 stuff in DL... ;)
>
> It's from older specification, we now see also CD/DVD reported
> with drive numbers above 7fh/

Probably forgotten with often changing hardware
standards... ;)

>>> I never understood why this BIOS INT13 format limits itself
>>> to 24 address-bits
> ...
>> Probably an issue of sparse room in the MBR's
>> partition record. If you write FEFFFF to both
>> encoded CHS entries, LBA entries 0x08 (start)
>> and 0x0C (size) determine start and size of a
>> partition.
>
> Yeah, that may have once been the cause for the restriced addressing.
>
>> Do you remember the huge 10 MB harddisks sold
>> with the first XT? Back in those times, every
>> byte stored on mass media was quite expensive
>> and valuable, so it makes sense if they tried
>> to save as much space as possible.
>
> right, OTOH partition entries were 32 bytes 'large' since I know
> about, but it wouldn't have hurt from the very begin to renounce
> of the double featured CHS and LBA entries for start/end/size.

32 byte entries? Which platform? Surely not IBM
or any other 'compatible' PC. GPT uses 128 byte
entries, where 32 byte are wasted for two GUIDs
(global user identifiers), plus another 72 byte
for a (very important!) partition name. Mere 24
byte hold real information - one DQ for the 1st
and one DQ for the last LBA (so we have to cal-
culate the size on our own...), one more DQ for
up to 64 'attributes'. Short sighted. Those who
followed the rapid evolution of mass media caps
can foresee how far we will get with 64 bit LBA
addressing.

>>>> CHS to LBA:
> ....
>>> I never checked if this is correct, but my docs tell the same :)
>
>> Part of some "disktools" I had to write after
>> Windoze changed the geometry of my boot drive
>> to funny values. Unfortunately, OS/2 couldn't
>> be booted with them. I had to write some code
>> to restore the original geometry (CHS values)
>> to be able to boot OS/2, again... ;)
>
> I'm glad for I can ignore all CHS info since a while,
> HD geometry became a fiction since long anyway,
> even USB-FD-images can be treated in a linear matter.

Unfortunately, the first stage of any boot code
has to use CHS until basic I/O is passed to its
own functions. I think it's an advantage if you
still know how to translate CHS to LBA and vice
versa.

IDEOS treats mass storage as 'extended memory'.
Using 128 bit LBAs / addresses should keep pace
with upcoming hardware for a couple of years.

Still some days until bulldozer lifts off. I am
curious how fast it really is... ;)


Greetings from Augsburg

Bernhard Schornak
0
Reply schornak1 (82) 5/29/2011 9:33:34 PM

On May 29, 7:34=A0pm, "wolfgang kern" <nowh...@never.at> wrote:
> catcalls offered:
>
> ...
> |Oh, and the code _is_ for sale for =A39.95 ~ It is called Lita's OS and
> |can be found on Google.
>
> OMG, Bill Gates can learn a lot from you !
> First sell it and lateron develope and debug it !
> I doubt that you achieve any earnings on your primature attempts :)
> __
> wolfgang

Hi Wolfgang,

I read a book on Extreme Programming (XP) Practices. It basically said
release early and release often. That has been my philosophy with Lita
OS. Also, in this market of OS development, many people are developing
their own Operating Systems. My favourite is Menuet OS. This is
similar to my own OS. An 32-bit Assembler OS. They even give it away
for free under the GPL along with their source code.

Well, I intend to sell Lita OS for a small sum of money (Roughly =A310 a
copy). But, I also intend to market the OS to local business as a
custom in-house development. This means, I can install the OS on a
specific PC, and develop custom software for use with the OS for the
business. It could be a data base software for keeping accounts or
sales stuff like that...but it will run on Lita OS.

I intend to make it highly compatible with the Virtual Machine market
as well as the Intel platform.

And please understand that even though the OS _is_ proprietary
software I do release the source code with each sale. Also, I have
released a lot of code on the Forums here, code we've all worked on
and become public domain that has made it into Lita's OS.

This time when I asked for help, I received a confirmation of my own
suspicions ~ that my boot loader had a memory collision!

As soon as I moved the stack, things seemed to pick up and start
working again :)

But, now I'm faced with the daunting task of multi-tasking two
functions...Which isn't easy!

Okies, thank you for all the support on the OS,

Cat
0
Reply obrzut.alex (64) 5/30/2011 4:33:18 AM

Bernhard Schornak wrote:
....
>> right, OTOH partition entries were 32 bytes 'large' since I know
>> about, but it wouldn't have hurt from the very begin to renounce
>> of the double featured CHS and LBA entries for start/end/size.

> 32 byte entries? Which platform? Surely not IBM
> or any other 'compatible' PC. GPT uses 128 byte
> entries, where 32 byte are wasted for two GUIDs
> (global user identifiers), plus another 72 byte
> for a (very important!) partition name. Mere 24
> byte hold real information - one DQ for the 1st
> and one DQ for the last LBA (so we have to cal-
> culate the size on our own...), one more DQ for
> up to 64 'attributes'. Short sighted. Those who
> followed the rapid evolution of mass media caps
> can foresee how far we will get with 64 bit LBA
> addressing.

sorry, 16 byte if course. My brain just saw two MBRs at once yet,
which is almost standard for all my HDs.

>>>>> CHS to LBA:
>> ....
>>>> I never checked if this is correct, but my docs tell the same :)

>>> Part of some "disktools" I had to write after
>>> Windoze changed the geometry of my boot drive
>>> to funny values. Unfortunately, OS/2 couldn't
>>> be booted with them. I had to write some code
>>> to restore the original geometry (CHS values)
>>> to be able to boot OS/2, again... ;)

>> I'm glad for I can ignore all CHS info since a while,
>> HD geometry became a fiction since long anyway,
>> even USB-FD-images can be treated in a linear matter.

> Unfortunately, the first stage of any boot code
> has to use CHS until basic I/O is passed to its
> own functions. I think it's an advantage if you
> still know how to translate CHS to LBA and vice
> versa.

I still have CHS<>SHT and LBA<>SHT conversions in my OS
(I named the hardware CHS format "SectorHeadTrack"), but this
routines became dead code meanwhile because I wont boot from
FDs anymore and my bootcode checks already in the MBR-sector on
INT13-41 and -48 to load next sectors via INT13-42 in LBA-mode.
All my CHS-drives are gone to the recycler many years ago.

> IDEOS treats mass storage as 'extended memory'.
> Using 128 bit LBAs / addresses should keep pace
> with upcoming hardware for a couple of years.

sure, 340e36 * 512 is a huge range indeed and together
with 4kB sectors this 128-bit addressing may be enough
for some centuries :)

> Still some days until bulldozer lifts off. I am
> curious how fast it really is... ;)

me too like to see it and check on all the opcodes missing
in my Phenom II yet.
__
wolfgang


0
Reply nowhere583 (184) 5/30/2011 8:20:13 AM

Mike Gonta replied:

>> I'm glad for I can ignore all CHS info since a while,
>> HD geometry became a fiction since long anyway,
>> even USB-FD-images can be treated in a linear matter.

> On most PC's with a fairly recent BIOS this will be the case.
> However on some BIOS/version where the UFD is BIOS emulated as FD
> the BIOS does not provide LBA access for drive identifier "0".
> Some BIOS/version will BIOS emulate a UFD under 1GB as FD, while
> the same BIOS/version will BIOS emulate a UFD 1GB and above as HD.
> Even with UFD BIOS emulation as HD a FD image can be accessed
> with the correct CHS provided by INT 13h, function 8 - Get Drive
> Parameters or with the INT 13h extensions if available.

Got it, thanks.

btw: I always tried to bypass BIOS after initial loading my code,
     but that way I may miss a few present hardware items.
Beside a check on standard legacy ports, I scan the whole PCI-bus
and get an almost complete picture of what's inside the machine.
But there could be more which I may never figure. So my question is: 
where/what in the BIOS could I search in addition ?
or could it help to go this damned PlugnPlay-detours ?

__
wolfgang



0
Reply nowhere583 (184) 5/30/2011 9:02:26 AM

MOV  AX, 09000h
	MOV  ES, AX
	XOR  DI, DI
	MOV  AX, 7C0h
	MOV  DS, AX
	XOR  SI, SI
	MOV  CX, 512
    REP  MOVSB

	; Now we jump UP to where we moved it.

	MOV AX, 09000h		;Segment
	PUSH AX
	MOV AX, 110h			;Offset to new location
	PUSH AX
	RETF

Hi, this is the code that fixed the problem with loading a kernel
larger than 30208 bytes into RAM from floppy disk.

In a nutshell, the boot loader was being over-written by the loaded
Kernel ~ and causing all sorts of crashes.

There fore, I simply rep movsb the bootloader out the way high up in
RAM where nothing really matters. And, in the future, I will be moving
the kernel to the top of RAM as well. But, for now, it works!

Yes, a few minutes ago, I actually booted up a 30211 byte kernel with
the boot sector loading 60 sectors from floppy. That 60 sector thing
would always cause a crash prior to relocating the 512 byte boot code.

Nice...now I can take Bank Holiday Monday off!

Cat
0
Reply obrzut.alex (64) 5/30/2011 11:34:44 AM

wolfgang kern wrote:


> Bernhard Schornak wrote:

<snip>

>>> I'm glad for I can ignore all CHS info since a while,
>>> HD geometry became a fiction since long anyway,
>>> even USB-FD-images can be treated in a linear matter.
>
>> Unfortunately, the first stage of any boot code
>> has to use CHS until basic I/O is passed to its
>> own functions. I think it's an advantage if you
>> still know how to translate CHS to LBA and vice
>> versa.
>
> I still have CHS<>SHT and LBA<>SHT conversions in my OS
> (I named the hardware CHS format "SectorHeadTrack"), but this
> routines became dead code meanwhile because I wont boot from
> FDs anymore and my bootcode checks already in the MBR-sector on
> INT13-41 and -48 to load next sectors via INT13-42 in LBA-mode.
> All my CHS-drives are gone to the recycler many years ago.

Okay. I had my boot manager in mind, where translations
between CHS, SHT and LBA still are crucial. Simple boot
loaders can be written without them (see my sample - it
denies to work without LBA support).

>> IDEOS treats mass storage as 'extended memory'.
>> Using 128 bit LBAs / addresses should keep pace
>> with upcoming hardware for a couple of years.
>
> sure, 340e36 * 512 is a huge range indeed and together
> with 4kB sectors this 128-bit addressing may be enough
> for some centuries :)

Less than three decades, I guess.

>> Still some days until bulldozer lifts off. I am
>> curious how fast it really is... ;)
>
> me too like to see it and check on all the opcodes missing
> in my Phenom II yet.

They are listed in the latest optimisation guide. Still
no "CMOVcc reg,imm", but YMM registers and quite point-
less functions. Seeing the 'details', it's not an eight
core, but four times 'two cores with shared instruction
decoder / scheduler, eight integer and two 128 bit wide
floating point pipes which are coupled for 256 bit ops'
- neither convincing nor impressing. Nevertheless: I am
eager to get one... ;)


Greetings from Augsburg

Bernhard Schornak
0
Reply schornak1 (82) 5/30/2011 8:54:34 PM

On May 30, 4:20=A0pm, "wolfgang kern" <nowh...@never.at> wrote:
> I still have CHS<>SHT and LBA<>SHT conversions in my OS
> (I named the hardware CHS format "SectorHeadTrack"), but this
> routines became dead code meanwhile because I wont boot from
> FDs anymore and my bootcode checks already in the MBR-sector on
> INT13-41 and -48 to load next sectors via INT13-42 in LBA-mode.
> All my CHS-drives are gone to the recycler many years ago.
>
> __
> wolfgang

However for traditional partition table, volume geometry are still
stored as CHS.
For my volume boot code I still need to translate that geometry once
to get the LBA of first sector within the volume.

I guess unless you drop support of old fashion partition table and
move to GUID (which use LBA), you still need the translation at least
once.
Or, perhaps you have a method to get away with it?
0
Reply nospam.calvin (6) 5/30/2011 9:33:58 PM

"Bluemoon" wrote in message
> However for traditional partition table, volume geometry are still
> stored as CHS.

But not needed.
Offset 8 of the partition record is a 32 bit LBA of the first absolute
sector of the partition.
Offset 12 of the partition record is a 32 bit number of sectors in the
partition.
http://en.wikipedia.org/wiki/Master_boot_record


Mike Gonta
look and see - many look but few see

http://aeBIOS.com


0
Reply mikegonta3947 (9) 5/30/2011 10:02:29 PM

Bluemoon wrote:

> I still have CHS<>SHT and LBA<>SHT conversions in my OS
> (I named the hardware CHS format "SectorHeadTrack"), but this
> routines became dead code meanwhile because I wont boot from
> FDs anymore and my bootcode checks already in the MBR-sector on
> INT13-41 and -48 to load next sectors via INT13-42 in LBA-mode.
> All my CHS-drives are gone to the recycler many years ago.

|However for traditional partition table, volume geometry are still
|stored as CHS.
|For my volume boot code I still need to translate that geometry once
|to get the LBA of first sector within the volume.

Bios wont care partition entries anyway.

|I guess unless you drop support of old fashion partition table and
|move to GUID (which use LBA), you still need the translation at least
|once.
|Or, perhaps you have a method to get away with it?

The method just is to write FEFFFFh into the CHS regions of partitions
and have start in LBA-form at offset 08h and size 0Ch.
Windoze eat that without ranting and I think even Loonix may understand.
__
wolfgang


0
Reply nowhere583 (184) 5/31/2011 3:23:47 PM

On Tue, 31 May 2011 17:23:47 +0200
"wolfgang kern" <nowhere@never.at> wrote:

> |However for traditional partition table, volume geometry are still
> |stored as CHS.
> |For my volume boot code I still need to translate that geometry once
> |to get the LBA of first sector within the volume.
> 
> Bios wont care partition entries anyway.

Not always true. I've seen a machine whose BIOS would refuse to invoke
the MBR unless at least one of the partitions on the drive had its
Bootable flag turned on. This confused me for a while, since it was a
Linux box using GRUB which couldn't care less about the partition flags.

Chris
0
Reply chead6946 (6) 6/1/2011 4:50:13 AM

On Tue, 2011-05-31 at 21:50 -0700, Christopher Head wrote:
> > Bios wont care partition entries anyway.
>=20
> Not always true. I've seen a machine whose BIOS would refuse to invoke
> the MBR unless at least one of the partitions on the drive had its
> Bootable flag turned on. This confused me for a while, since it was a
> Linux box using GRUB which couldn't care less about the partition
> flags.=20

Coincidentally I just had the exact same problem on my old laptop a few
days ago. =20
--=20
Tactical Nuclear Kittens

0
Reply alex.buell (44) 6/1/2011 7:43:32 AM

Christopher Head replied

> I wrote:

>> |However for traditional partition table, volume geometry are still
>> |stored as CHS.
>> |For my volume boot code I still need to translate that geometry once
>> |to get the LBA of first sector within the volume.

>> Bios wont care partition entries anyway.

> Not always true. I've seen a machine whose BIOS would refuse to invoke
> the MBR unless at least one of the partitions on the drive had its
> Bootable flag turned on. This confused me for a while, since it was a
> Linux box using GRUB which couldn't care less about the partition flags.

That's interesting, even I can't confirm it for my various machines.
All I figured is that the BIOS load and execute the very first 512
bytes from a HD(CD,DVD) if it finds 55 AA at the end regardless if
there are partition entries at all.
Otherwise it wouldn't boot my OS which show some msg-text there :)
__
wolfgang


0
Reply nowhere583 (184) 6/2/2011 8:12:53 AM

34 Replies
32 Views

(page loaded in 0.18 seconds)

Similiar Articles:









7/27/2012 10:42:11 AM


Reply: