[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)
|