News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Not able to jmp to kernel at sect2

Started by zak100, November 15, 2009, 03:23:52 PM

Previous topic - Next topic

zak100

Hi,
I have written a simple bootloader which prints 'A' and copies the code at sect2 to mem at 1000:0h. The bootloader is
given below:

   
;creates a boot loader and jumps to kernel



.MODEL  TINY
.CODE
ORG     0

bpbBytesPerSector  DW 512
bpbSectorsPerCluster DB 1
bpbReservedSectors DW 1
bpbNumberOfFATs DB 2
bpbRootEntries         DW 224
bpbTotalSectors DW 2880
bpbMedia         DB 0F0h
bpbSectorsPerFAT DW 9
bpbSectorsPerTrack DW 18
bpbHeadsPerCylinder DW 2
bpbHiddenSectors        DD 0
bpbTotalSectorsBig      DD 0
bsDriveNumber         DB 0
bsUnused                DB 0
bsExtBootSignature DB 29h
bsSerialNumber         DD 0a0a1a2a3h
bsVolumeLabel         DB "MOS FLOPPY "
bsFileSystem         DB "FAT12   "

;code branch

boot0:  jmp short boot1

boot1: cli                     ;disable maskable interrupts
       xor     di,di
       mov     ss,di
       mov     sp,7C00h        ;SS:SP = 0000:7C00
       
       sti
;---------------------- displays a character 'A'
    cld
    mov ax,0B800h
    mov es,ax
    xor di,di
    mov ax,1F41h
    stosw
;-----------------------
    mov ah, 0
    int 16h
;-----------------reset floppy
Reset:
      mov ah,0; reset floppy disk function
      mov dl, 0
      int 13h
      jc Reset; If carry set, error. Try again
;---------------
     mov ax, 1000h; read sector into address 0x1000:0
     mov es, ax
     xor bx, bx
     mov ah, 2; read sector function
     mov al, 1; read 1 sector
     mov ch,1;
     mov cl,2; reading 2nd sector
     mov dh, 0
     mov dl, 0
     int 13h
; --------------
     db      0EAh    ;JMP FAR
     dw      0       ;offset
     dw      1000h   ;segment

     
     



ORG 1FEH


        dw      0AA55h

;----------------------------------------------------------------------------------

        END     boot0





The kernel code which is stored at sect2 is given below:


   
.model tiny
.data
msg db "We be bootin2'!",0
.code
start:
;org 1000h:0;

    call overdata    ; Call? WTF? Don't worry, we pop the.
                     ; return address off to get initial IP.
                     ; Note that "call" is longer than

;----------------------------writing a mesg on screen at startup. We cant use int 21h


overdata:
    xor di,di
     mov ds,di
    mov cs,di
   
;----------------------------

   mov bp,offset msg
   mov ah,013h     ; Fn 13h of int 10h writes a whole string on screen
   mov al,00     ; bit 0 determines cursor pos,0->point to start after          
                    ; function call,1->point to last position written
   mov bx,0007h     ; bh -> screen page ie 0,bl = 07 ie white on black
   mov cx,020h     ; Length of string here 32
   mov dx,00000     ; dh->start cursor row,dl->start cursor column
   int 010h     ; call bios interrupt 10h
        ; Return to calling routin
hlt

end start



I am using partcopy program from web to copy the kernel to sect2.

The partcopy command is given below:
   
partcopy test.bin 0 2C -f0 200



Can somebody guide me how to solve this prob. plz?

Zulfi.

dedndave

well - at the org 0, there are 3 bytes reserved for a branch to code - THEN 8 characters for the name - THEN the BPB
http://www.ntfs.com/ntfs-partition-boot-sector.htm

zak100

;creates a boot loader and jumps to kernel


             

.MODEL  TINY
.CODE
ORG     0
boot0:  jmp short boot1

       ORG     3

;OEM identifier


.STACK 2048; removes the stack warning

ORG     0Bh

bpbBytesPerSector  DW 512
bpbSectorsPerCluster DB 1
bpbReservedSectors DW 1
bpbNumberOfFATs DB 2
bpbRootEntries         DW 224
bpbTotalSectors DW 2880
bpbMedia         DB 0F0h
bpbSectorsPerFAT DW 9
bpbSectorsPerTrack DW 18
bpbHeadsPerCylinder DW 2
bpbHiddenSectors        DD 0
bpbTotalSectorsBig      DD 0
bsDriveNumber         DB 0
bsUnused                DB 0
bsExtBootSignature DB 29h
bsSerialNumber         DD 0a0a1a2a3h
bsVolumeLabel         DB "MOS FLOPPY "
bsFileSystem         DB "FAT12   "

;code branch



boot1: cli                     ;disable maskable interrupts
       xor     di,di
       mov     ss,di
       mov     sp,7C00h        ;SS:SP = 0000:7C00
       
       sti
;---------------------- displays a character 'A'
    cld
    mov ax,0B800h
    mov es,ax
    xor di,di
    mov ax,1F41h
    stosw
;-----------------------
    mov ah, 0
    int 16h
;-----------------reset floppy
Reset:
      mov ah,0; reset floppy disk function
      mov dl, 0
      int 13h
      jc Reset; If carry set, error. Try again
;---------------
     mov ax, 1000h; read sector into address 0x1000:0
     mov es, ax
     xor bx, bx
     mov ah, 2; read sector function
     mov al, 1; read 1 sector
     mov ch,1;
     mov cl,2; reading 2nd sector
     mov dh, 0
     mov dl, 0
     int 13h
; --------------
     db      0EAh    ;JMP FAR
     dw      0       ;offset
     dw      1000h   ;segment

     
     



ORG 1FEH


        dw      0AA55h

;----------------------------------------------------------------------------------

        END     boot0


Thanks for your tips but still the above code is not working. I need some more guidance on this.

Zulfi.


MichaelW

Using ORG 0 instead of ORG 7C00h will work only for a boot sector that does not access its own data. For a boot sector that does access its own data, ORG 0 will cause ML to encode the instructions that access the data with addresses that will not match the actual addresses of the data in memory at runtime.

.model tiny
.stack
.code
org 0
start:
    ;-------------------------------------------
    ; The near ptr forces ML to encode a 3-byte
    ; near jump instead of a 2-byte short jump.
    ;-------------------------------------------
    jmp near ptr @F
    junk dw 1234h
@@:
    mov ax, junk
org 510
  dw 0AA55h
end start


D:\MASMDOS\morebootcode>if exist bt.bin del bt.bin

D:\MASMDOS\morebootcode>rename bt.com bt.bin

D:\MASMDOS\morebootcode>debug
-n bt.bin
-l 7c00
-u 7c00
0B10:7C00 E90200        JMP     7C05
0B10:7C03 3412          XOR     AL,12
0B10:7C05 A10300        MOV     AX,[0003]


.model tiny
.stack
.code
org 7c00h
start:
    ;-------------------------------------------
    ; The near ptr forces ML to encode a 3-byte
    ; near jump instead of a 2-byte short jump.
    ;-------------------------------------------
    jmp near ptr @F
    junk dw 1234h
@@:
    mov ax, junk
org 7c00h + 510
  dw 0AA55h
end start


D:\MASMDOS\morebootcode>if exist bt.bin del bt.bin

D:\MASMDOS\morebootcode>rename bt.com bt.bin

D:\MASMDOS\morebootcode>debug
-n bt.bin
-l 7c00
-u 7c00
0B10:7C00 E90200        JMP     7C05
0B10:7C03 3412          XOR     AL,12
0B10:7C05 A1037C        MOV     AX,[7C03]


Also, in your kernel code there are some obvious problems:

call overdata
overdata:
xor di,di
mov ds,di
mov cs,di


Your far jump to the code set CS, and the code is trying to reset it to 0, using an invalid instruction (you cannot load CS with a MOV instruction). Instead of setting DS to 0 it should probably be set to the value of CS, and you should probably do the same for SS, and then set SP to a workable value (for this code I would start with 1000h).
eschew obfuscation

zak100

Thanks for your reply. It would take sometime for me to improve my code.

Zulfi.

zak100

Hi,
I have done all the changes but still its not working.

Zulfi.
Bootloader program:



;creates a boot loader and jumps to kernel



.MODEL  TINY
.CODE
ORG     7C00H
boot0:  jmp short boot1

       ORG     7C00h+3

;OEM identifier


.STACK 2048; removes the stack warning

ORG     7C00H+0Bh

bpbBytesPerSector  DW 512
bpbSectorsPerCluster DB 1
bpbReservedSectors DW 1
bpbNumberOfFATs DB 2
bpbRootEntries         DW 224
bpbTotalSectors DW 2880
bpbMedia         DB 0F0h
bpbSectorsPerFAT DW 9
bpbSectorsPerTrack DW 18
bpbHeadsPerCylinder DW 2
bpbHiddenSectors        DD 0
bpbTotalSectorsBig      DD 0
bsDriveNumber         DB 0
bsUnused                DB 0
bsExtBootSignature DB 29h
bsSerialNumber         DD 0a0a1a2a3h
bsVolumeLabel         DB "MOS FLOPPY "
bsFileSystem         DB "FAT12   "

;code branch



boot1: cli                     ;disable maskable interrupts
       xor     di,di
       mov     ss,di
       mov     sp,7C00h        ;SS:SP = 0000:7C00
       
       sti
;---------------------- displays a character 'A'
    cld
    mov ax,0B800h
    mov es,ax
    xor di,di
    mov ax,1F41h
    stosw
;-----------------------
    mov ah, 0
    int 16h
;-----------------reset floppy
Reset:
      mov ah,0; reset floppy disk function
      mov dl, 0
      int 13h
      jc Reset; If carry set, error. Try again
;---------------
     mov ax, 1000h; read sector into address 0x1000:0
     mov es, ax
     xor bx, bx
     mov ah, 2; read sector function
     mov al, 1; read 1 sector
     mov ch,1;
     mov cl,2; reading 2nd sector
     mov dh, 0
     mov dl, 0
     int 13h
; --------------
     db      0EAh    ;JMP FAR
     dw      0       ;offset
     dw      1000h   ;segment

     
     



ORG 1FEH


        dw      0AA55h

;----------------------------------------------------------------------------------

        END     boot0








sect2.asm (kernel)


;partcopy sect2.bin 0 2C -f0 200

;USING INT 10 H for Printing Mesg
;------------------------------------
.model tiny
.data
msg db "We be bootin2'!",0
.code
start:
;org 1000h:0;

    call overdata    ; Call? WTF? Don't worry, we pop the.
                     ; return address off to get initial IP.
                     ; Note that "call" is longer than

;----------------------------writing a mesg on screen at startup. We cant use int 21h


overdata:
    mov ax,1000h; Note CS is already 1000h
     mov ds,ax
    mov ss,ax
   
;----------------------------

   mov bp,offset msg
   mov ah,013h     ; Fn 13h of int 10h writes a whole string on screen
   mov al,00     ; bit 0 determines cursor pos,0->point to start after          
                    ; function call,1->point to last position written
   mov bx,0007h     ; bh -> screen page ie 0,bl = 07 ie white on black
   mov cx,0Ch     ; Length of string here 13
   mov dx,00000     ; dh->start cursor row,dl->start cursor column
   int 010h     ; call bios interrupt 10h
        ; Return to calling routin
hlt

end start






I still need some more help on this.

sinsi

You define a new 2Kb segment (.stack) after your code (.code) and then continue your code.
"mov ch,1;" makes you read track 1
After the jump to overdata you initialise SS but not SP (not fatal here, but they usually go in tandem).
'hlt' will only halt the cpu until an interrupt, and the timer goes off 18-odd times a second. Use 'cli, hlt' or even 'jmp $'
If you are writing code to the 2nd sector then you don't need to have a BPB, since that should be the first FAT sector.
I'm pretty sure that the int 10 call needs the string address in ES:BP. I realise you made it 1000 for the disk read, but it could be a gotcha later.
Light travels faster than sound, that's why some people seem bright until you hear them.

MichaelW

You forgot to change the ORG 1FEH. My suggestions regarding the SS and SP values were not right. I think for now you should leave SS and SP as you set them up in the boot sector code.
eschew obfuscation

zak100

Hi,
I have changed the sector 2 code but still its not clicked.
Kindly give me more guidance how to solve this problem?

Zulfi.



.model small
.data
msg db "We be bootin2'!",0
.code
start:
;org 1000h:0;

    call overdata    ; Call? WTF? Don't worry, we pop the.
                     ; return address off to get initial IP.
                     ; Note that "call" is longer than

;----------------------------writing a mesg on screen at startup. We cant use int 21h


overdata:
    mov ax,1000h; Note CS is already 1000h
     mov ds,ax
    ;mov ss,ax
   mov ax,@data
   mov es, ax
   
;----------------------------

   mov bp,offset msg
   mov ah,013h     ; Fn 13h of int 10h writes a whole string on screen
   mov al,00     ; bit 0 determines cursor pos,0->point to start after          
                    ; function call,1->point to last position written
   mov bx,0007h     ; bh -> screen page ie 0,bl = 07 ie white on black
   mov cx,0Ch     ; Length of string here 13
   mov dx,00000     ; dh->start cursor row,dl->start cursor column
   int 010h     ; call bios interrupt 10h
        ; Return to calling routin
cli
hlt

end start



dedndave

well - i have not been keeping up with this thread, Zulfi
if you want to make life easier, though, just use the CS register to get the current code segment into DS and ES

        push    cs       ;4 byte version
        pop     ds
        push    cs
        pop     es

or...

        mov     ax,cs    ;6 byte version
        mov     ds,ax
        mov     es,ax

that way, the segments are local, no matter where the boot sector places the code

zak100

Hi,
I would try your suggestion but in the previous mesg sinsi told me that:
"I'm pretty sure that the int 10 call needs the string address in ES:BP" so es should point to data segement. However I would change ds to point to cs.

Zulfi.

dedndave

at this point in the boot process, there is no need to have a seperate data segment
because all the code and data can easily fit into one 64 Kb segment
so, put the strings, as well as all the other data, in the code segment

zak100

Hi,
No change. Its just printing 'A' and not going to kernel code.
Is this a prob.?

"LINK : warning L4055: start address not equal to 0x100 for /TINY"

Zulfi.

.model tiny
.code
msg db "We be bootin2'!",0

start:
;org 1000h:0;

    call overdata    ; Call? WTF? Don't worry, we pop the.
                     ; return address off to get initial IP.
                     ; Note that "call" is longer than

;----------------------------writing a mesg on screen at startup. We cant use int 21h


overdata:
    mov ax,cs; Note CS is already 1000h
     mov ds,ax
    ;mov ss,ax
   ;mov ax,@data
   mov es, ax
   
;----------------------------

   mov bp,offset msg
   mov ah,013h     ; Fn 13h of int 10h writes a whole string on screen
   mov al,00     ; bit 0 determines cursor pos,0->point to start after          
                    ; function call,1->point to last position written
   mov bx,0007h     ; bh -> screen page ie 0,bl = 07 ie white on black
   mov cx,0Ch     ; Length of string here 13
   mov dx,00000     ; dh->start cursor row,dl->start cursor column
   int 010h     ; call bios interrupt 10h
        ; Return to calling routin
cli
hlt

end start

dedndave

no - you can ignore the ORG warning, as well as the STACK warning (should be no stack segment for tiny)
both of those warnings tell you that you are doing it right
i am playing with the code - give me a few minutes

dedndave

ok - here is the boot sector code
i am not sure why you want to load at 1000:0000
i think i would load at 0000:7E00
i put those values in EQUates so it is easy to change
give me a few more minutes for the bootloader

        .MODEL  TINY
        .CODE

;----------------------------------------------------------------------------------

LoadOfs EQU     0
LoadSeg EQU     1000h

;----------------------------------------------------------------------------------

;---------------------- branch to executable code

        ORG     0

Boot0:  jmp short Boot1

;---------------------- OEM identifier

        ORG     3

        DB      "Zulfi OS"

;---------------------- BIOS parameter block for 1.44 Mb floppy disk

        ORG     0Bh

bpbBytesPerSector    DW 512
bpbSectorsPerCluster DB 1
bpbReservedSectors   DW 1
bpbNumberOfFATs      DB 2
bpbRootEntries       DW 224
bpbTotalSectors      DW 2880
bpbMedia             DB 0F0h
bpbSectorsPerFAT     DW 9
bpbSectorsPerTrack   DW 18
bpbHeadsPerCylinder  DW 2
bpbHiddenSectors     DD 0
bpbTotalSectorsBig   DD 0
bsDriveNumber        DB 0
bsUnused             DB 0
bsExtBootSignature   DB 29h
bsSerialNumber       DD 0a0a1a2a3h
bsVolumeLabel        DB "MOS FLOPPY "
bsFileSystem         DB "FAT12   "

;---------------------- initialize SS:SP

Boot1:  cli                     ;disable maskable interrupts
        xor     di,di
        mov     ss,di
        mov     sp,7C00h        ;SS:SP = 0000:7C00
        sti                     ;enable maskable interrupts

;---------------------- display 'A' character

        cld
        mov     ax,0B800h
        mov     es,ax
        mov     ax,1F41h
        stosw

;---------------------- wait for a keypress

        mov     ah,0
        int     16h

;---------------------- read the bootloader code

        mov     cx,5            ;retry count

Reset0: push    cx
        mov     ah,0            ;reset floppy disk function
        mov     dl,0            ;drive A:
        int     13h

        mov     ax,LoadSeg      ;read sector into address LoadSeg:LoadOfs
        mov     es,ax
        mov     bx,LoadOfs

        mov     cx,2            ;cylinder 0, sector 2
        xor     dx,dx           ;head 0, drive 0
        mov     ax,201h         ;read 1 sector
        int     13h
        pop     cx
        jnc     Exec0

        loop    Reset0

;---------------------- failed 5 times - halt

Halt0:  jmp     Halt0

;---------------------- execute the bootloader code

Exec0:
        db      0EAh            ;JMP FAR instruction
        dw      LoadOfs         ;offset
        dw      LoadSeg         ;segment

;---------------------- boot sector signature

        ORG     1FEh

        dw      0AA55h

;----------------------------------------------------------------------------------

        END     Boot0

you should disassemble a DOS boot sector - they use the BPB values to find the first real data sector and load from there