Home arrow Forums
OSDEV Forums  


hazelnoot
User

Junior Osdever
Posts: 5
graphgraph
Karma: 0  
BOOTLOADER - 2006/04/26 13:41 HI!!

i have a big problem: i have written some code:
Code:

  [BITS 16] [ORG 0x7C00] KERNEL_SIZE equ 76 KERNEL_SEGMENT equ 0x1000 KERNEL_START equ 1 %define   LOOPS_1       bp-2 %define   CYLINDER   bp-4 %define   offs      bp-6 %define   SECTORZ     bp-8 %define   LOGICAL    bp-10 %define seg      bp-12 SUB sp12 CLI                      XOR axax MOV ssax MOV sp0x7C00 MOV dsax STI    MOV axKERNEL_SEGMENT MOV esax MOV [seg], ax MOV bx0 MOV [offs], bx MOV cxKERNEL_SIZE MOV [LOOPS_1], cx MOV ax2           ;start at sector2 MOV [LOGICAL], ax MOV [SECTORZ], ax MOV ax0 MOV [CYLINDER], ax main_loop:     MOV [LOOPS_1], cx       ;take the loopvar to the logical sector number     ;MOV ax, [LOGICAL]   ;Cylinder     ;MOV bx36     ;MOV dx0     ;DIV bx     ;MOV [CYLINDER], ax     MOV dx18        ;set TRACK 0 if TRACK is 18     CMP dx, [SECTORZ]     JE  set_null fail:          ;read the sector     MOV ax, [seg]     MOV bx, [offs]     MOV ah2     MOV al1     MOV ch, [CYLINDER]     MOV cl, [SECTORZ]     MOV dx0     INT 0x13     JC  fail     MOV cx, [LOOPS_1]     MOV al1      ADD [LOGICAL], al     ADD [SECTORZ], al     MOV al32     ADD [seg], al     MOV ax512     ADD [offs], al     LOOP main_loop; JMP KERNEL_SEGMENT:0x0000 set_null     mov ah0x0e     mov al'.'    mov bx0x0004    int 0x10     MOV dx1     MOV [SECTORZ], dx     ADD [CYLINDER], dx JMP fail



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
graph
Karma: 10  
Re:BOOTLOADER - 2006/04/27 14:08 Hello 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:
Code:

  Sector   = (LBA%SecsPerTrack) + 1 Cylinder = (LBA/SecsPerTrack)/NumHeads Head     = (LBA/SecsPerTrack)%NumHeads



Now what do these equantions mean:
  • 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
graphgraph
Karma: 0  
Re:BOOTLOADER - 2006/04/29 04:02 hi 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 sp12         mov cx76              ;numers of sectors to read         mov [LOOPS_1], cx       ;storage this number in LOOPS_1         mov ax2               ;start sector is 2         mov [LSN], ax           ;storage this in LSN for transformation to CHS for the int 13         mov ax0         mov [OFFSET], ax reset_drive:         mov ah0               RESET-command         int 13h                 Call interrupt 13h         or ahah               Check for error code         jnz reset_drive         ; Try again if ah != 0         mov ax0x1000         mov esax          read_again:         mov ax, [LSN]         ;calculate the sector from the logical sector number         xor dxdx         mov bx18         div bx         inc dx         mov [SECTOR], dx                  ;calculate the cylinder and head         xor dxdx         mov bx36         div bx         mov [CYLINDER], ax         mov [HEAD], dx                  mov bx, [OFFSET]         mov ah02h             READ SECTOR-command         mov al1               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 ahah               Check for error code         jnz reset_drive         ; Try again if ah != 0                  mov cx, [LOOPS_1]       ;save back the nubers of the loops         mov dx1               ;load dx with the sectors to add         add [LSN], dx           ;add dx to LSN         mov dx512         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
graph
Karma: 10  
Re:BOOTLOADER - 2006/04/29 10:20 Hello,
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 dxdx mov bx18 div bx             ax LSN/18 xor dxdx mov bx2          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.
DRF
Visitor
 
Re:BOOTLOADER - 2006/05/09 08:08 Congratulations gaf!

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
graph
Karma: 10  
Re:BOOTLOADER - 2006/05/11 10:24 Hello 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.

A WebArticles site. Sponsored by Evoleto. Motorola V525 / Business Directory / Delaware Incorporation / Home Made Bazaar