but it didnt word i have used bochs for testing bochs didnt gave me an error message he puts the dots('.') and then he did nothing... please help me... THANK YOU!!!
SORRY for my double post .... my browser tztz
Post edited by: hazelnoot, at: 2006/04/26 14:42
| | The administrator has disabled public write access.
OSDEV Community
Advertisement
gaf
User Platinum Osdever
Posts: 153
Karma: 10
Re:BOOTLOADER - 2006/04/27 14:08Hello hazelnoot, from what I can tell your code seems to completly ignore the head-number. It should actually be stored in the DH register when the interrupt is called, but your code always sets it to zero. The result is that the wrong sectors are accessed and your kernel only gets partially loaded.
For a detailed explanation of LBA -> CHS conversations you can have a look at DRF's tutorial at bonafide (image of a disk). Basically it can however all be boiled-down to the following three formulas:
The CHS sector number is an offset in the track. As there're 18 sectors per track, the sector number must be between 1 and 18 (both numbers included)
For both, cylinder and head-number one first has to divide the LBA by the number of sectors per track. The result could be called a 'virtual track number' as it tells us in which continuous track the sector is located.
To calculate the actual cylinder number, one has to divide the virtual track number by the number of heads. Example: 0/2 = 0, 1/2 = 0, 2/2 = 1, 3/2 = 1, 4/2 = 2, 5/2 = 2, etc
The remainer of the integer division is the head number. Example: 0/2 = 0, 1/2 = 1, 2/2 = 0, 3/2 = 1, 4/2 = 0, 5/2 = 2, etc
As you can see there are always two CHS tracks that have the same track-number, but differ in their head-number. To access two continuous cylinders one would thus have to switch the head. A floppy drive always stores even track numbers on head0 and uneven tracks on head1.
To fix this bug you probably have to change your set_null procedure, aswell as line 61 where the DX register gets set to zero.
Apart from that I found some minor bugs that I'll just enlist:
line 22: If I were you I'd leave the interrupts disable until the kernel is fully initialized. After all you don't want a timer IRQ to occure before you can handle it..
line 48: I think that the sector number should actually be 19 and not 18. The number might be somewhere between 1 and 18, and you want to call set_null once the 18th sector was read and the value increased to 19.
line 55: This line is useless as the value in the AX register gets overwritten in lines 57 and 58.
line 70: The segment base shouldn't have to be increased unless your kernel image grows above the 64kb mark. I would thus leave it static for the moment. If you for whatever reason want to change the base you mustn't change the offset from zero (-> line 72). Increasing both is not a good idea..
regards,
gaf
Post edited by: gaf, at: 2006/04/29 09:44
| | The administrator has disabled public write access.
hazelnoot
User Junior Osdever
Posts: 5
Karma: 0
Re:BOOTLOADER - 2006/04/29 04:02hi i have followed your directions and have written the code new with a better LSN to CHS convert.
but it also didnt work i am really hopeless PLEASE PLEASE take again a look at my code...
Code:
[BITS 16] ; We need 16-bit intructions for Real mode
[ORG 0x7C00] ; The BIOS loads the boot sector into memory location 0x7C00
%define LOOPS_1 bp-2
%define LSN bp-4
%define CYLINDER bp-6
%define SECTOR bp-8
%define HEAD bp-10
%define OFFSET bp-12
sub sp, 12
mov cx, 76 ;numers of sectors to read
mov [LOOPS_1], cx ;storage this number in LOOPS_1
mov ax, 2 ;start sector is 2
mov [LSN], ax ;storage this in LSN for transformation to CHS for the int 13
mov ax, 0
mov [OFFSET], ax
reset_drive:
mov ah, 0 ; RESET-command
int 13h ; Call interrupt 13h
or ah, ah ; Check for error code
jnz reset_drive ; Try again if ah != 0
mov ax, 0x1000
mov es, ax
read_again:
mov ax, [LSN]
;calculate the sector from the logical sector number
xor dx, dx
mov bx, 18
div bx
inc dx
mov [SECTOR], dx
;calculate the cylinder and head
xor dx, dx
mov bx, 36
div bx
mov [CYLINDER], ax
mov [HEAD], dx
mov bx, [OFFSET]
mov ah, 02h ; READ SECTOR-command
mov al, 1 ; Number of sectors to read = 1
mov ch, [CYLINDER] ; Cylinder = [LSN] / 36
mov cl, [SECTOR] ; Sector = ([LSN] % 18) +1
mov dh, [HEAD] ; Head = ([LSN] / 18) % 2
int 13h ; Call interrupt 13h
or ah, ah ; Check for error code
jnz reset_drive ; Try again if ah != 0
mov cx, [LOOPS_1] ;save back the nubers of the loops
mov dx, 1 ;load dx with the sectors to add
add [LSN], dx ;add dx to LSN
mov dx, 512
add [OFFSET], dx
LOOP read_again
jmp 0x1000:0
when i test this code with bochs, it works(bochs takes no error message to me) but my kernel will not be loadet (((
Please help me!!
thanks!!
| | The administrator has disabled public write access.
gaf
User Platinum Osdever
Posts: 153
Karma: 10
Re:BOOTLOADER - 2006/04/29 10:20Hello, your updated code looks much better too me, and there are actually only two smaller bugs I found: As Pyr0Mathic already mentioned at mega-tokyo you really should initialize BP with the stack address before using it. Otherwise it might happen that some crucial data-structures gets overwritten. The real problem however is that you tried to combine the two divisions that are needed to calculate the head- and cylinder numbers. This might work for the cylinders, but not for the head's as (LBA/SecsPerTrack)%NumHeads is not the same as LBA%(SecsPerTrack*NumHeads). Apart from that you forgot to reload the LBA sector number before the division:
Code:
;calculate the cylinder and head
mov ax, [LSN] ; reload the sector number
xor dx, dx
mov bx, 18
div bx ; ax = LSN/18
xor dx, dx
mov bx, 2 ; divide the result by two
div bx
mov [CYLINDER], ax ; cylinder = (LSN/18)/2
mov [HEAD], dx ; cylinder = (LSN/18)%2
If it stil doesn't work you should in my opinion also make sure that the kernel you're trying to load doesn work as expected..
regards,
gaf
My 100th post on this board
| | The administrator has disabled public write access.
100 posts shows some real dedication. (or a sign of too much spare time ) but I'm sure in this case it's just dedication.
hazelnoot, I think gaf has pointed out all the problems. If you can't get the conversion to work I seem to remember putting a functioning example of a LBA to CHS function at the end of the tutorial (if not get in touch and I can dig one up for you). So feel free to cut and paste that code in to check if the rest of your bootloader works and come back to writing your own LBA/CHS procedure once you've got the other bugs sorted out.
Daniel
| | The administrator has disabled public write access.
gaf
User Platinum Osdever
Posts: 153
Karma: 10
Re:BOOTLOADER - 2006/05/11 10:24Hello DRF, good to see you once again - it's been some time..
100 posts shows some real dedication. (or a sign of too much spare time) but I'm sure in this case it's just dedication.
Don't mention spare-time to me, I still wallow in self-pity due to all the tests I have to write at school at the moment. Keeps me from doing something more usefull on the weekends..
By the way: From you posting as a 'guest' it seems as if I were not the only one who has some problems with the new auto-logout feature. Maybe it would be a good idea to choose a somewhat higher time-limit, root ?
cheers, gaf
| | The administrator has disabled public write access.