what's wrong? why?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
wentong

what's wrong? why?

Post by wentong »

BEGIN: ; NOW AT 0000:7C00, RELOCATE
   CLI ;disable int's
   XOR AX,AX ;set stack seg to 0000
   MOV SS,AX
   MOV SP,0x7C00 ;set stack ptr to 7c00
   MOV SI,SP ;SI now 7c00
   PUSH AX
   POP ES ;ES now 0000:7c00
   PUSH AX
   POP DS ;DS now 0000:7c00
   STI ;allow int's
   CLD ;clear direction
   MOV DI,0x600 ;DI now 0600
   MOV CX,0x100 ;move 256 words (512 bytes)
   REPNZ ;move MBR from 0000:7c00
   MOVSW ; to 0000:0600
   JMP 0000:start   ;jmp to NEW_LOCATION


start:
;clear screen
   mov ax,0xb800
   mov es,ax
   xor di,di
   mov ax,0x0720
   mov cx,80*25   
   cld
   rep stosw

   cli
   hlt

times 510-($-$$) db 0x90
dw 0xAA55


//this is the code for boot
//512byte
//it's fine when i assblemly useing NASM
//but wrong when i useing bochs to emulate
//why?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:what's wrong? why?

Post by Pype.Clicker »

first, don't forget to put an ORG command so that you define the addresses generated by your assembler

bad jump to 0000:start ...

start has been set as an offset from 7c00 (the start of your bootsector), and now you're trying to access it at 6000 with your 7c00-related offset...
try

Code: Select all

jmp 0000:0x6000 + start - begin
wentong

Re:what's wrong? why?

Post by wentong »

thanks for your answer,but i still can't work in bochs

here is my step after i change the code view by ndisasmw and test by bochs.

=====================
the code
=====================

ORG 0x7C00
BEGIN: ; NOW AT 0000:7C00, RELOCATE
   CLI ;disable int's
   XOR AX,AX ;set stack seg to 0000
   MOV SS,AX
   MOV SP,0x7C00 ;set stack ptr to 7c00
   MOV SI,SP ;SI now 7c00
   PUSH AX
   POP ES ;ES now 0000:7c00
   PUSH AX
   POP DS ;DS now 0000:7c00
   STI ;allow int's
   CLD ;clear direction
   MOV DI,0x600 ;DI now 0600
   MOV CX,0x100 ;move 256 words (512 bytes)
   REPNZ ;move MBR from 0000:7c00
   MOVSW ; to 0000:0600
   JMP 0000:0x6000+ start - BEGIN    ;jmp to NEW_LOCATION


start:

   mov ax,0xb800
   mov es,ax
   xor di,di
   mov ax,0x0720
   mov cx,80*25   
   cld
   rep stosw

   cli
   hlt

times 510-($-$$) db 0x90
dw 0xAA55

=====================
disassembly by ndisasmw
=====================
00000000 FA cli
00000001 31C0 xor ax,ax
00000003 8ED0 mov ss,ax
00000005 BC007C mov sp,0x7c00
00000008 89E6 mov si,sp
0000000A 50 push ax
0000000B 07 pop es
0000000C 50 push ax
0000000D 1F pop ds
0000000E FB sti
0000000F FC cld
00000010 BF0006 mov di,0x600
00000013 B90001 mov cx,0x100
00000016 F2A5 repne movsw
00000018 EA1D600000 jmp 0x0:0x601d
0000001D B800B8 mov ax,0xb800
00000020 8EC0 mov es,ax
00000022 31FF xor di,di
00000024 B82007 mov ax,0x720
00000027 B9D007 mov cx,0x7d0
0000002A FC cld
0000002B F3AB rep stosw
0000002D FA cli
0000002E F4 hlt
0000002F 90 nop
00000030 90 nop
00000031 90 nop
00000032 90 nop
*
*
*
*
*
000001FD 90 nop
000001FE 55 push bp
000001FF AA stosb


=======================
here is the error by bochs output
but just little part of the output
=======================

00000377825i[CPU ] BxError: instruction with op1=0xff
00000377825i[CPU ] nnn was 7
00000377825i[CPU ] WARNING: Encountered an unknown instruction (signalling ille
gal instruction):
GertFaller

Re:what's wrong? why?

Post by GertFaller »

Maybe some mistakes with addresses.
Try

Code: Select all

ORG 0x7C00
BEGIN:                  ;    NOW AT 0000:7C00, RELOCATE
   CLI                    ;disable int's
   XOR    AX,AX          ;set stack seg to 0000
   MOV    SS,AX
   MOV    SP,0x7C00        ;set stack ptr to 7c00
   MOV    SI,start;      ;SI now start
   PUSH    AX
   POP    ES              ;ES now 0000
   PUSH    AX
   POP    DS              ;DS now 0000
   STI                    ;allow int's
   CLD                    ;clear direction
   MOV    DI,0x600        ;I want 0x0600
   MOV    CX,0x100        ;move 256 words (512 bytes)
  REPNZ                  ;move start code
  MOVSW                  ;  to 0000:0600
   JMP    0x0000:0x600    ;jmp to NEW_LOCATION


start:

   mov ax,0xb800
   mov es,ax
   xor di,di
   mov ax,0x0720
   mov cx,80*25   
   cld
   rep stosw

   cli
   hlt

times 510-($-$$) db 0x90
dw 0xAA55
Tom

Re:what's wrong? why?

Post by Tom »

You need the times and the dw directive to set correctly the bootsector.

The BIOS loads exactly 512 bytes of code, and needs that dw 0xAA55 to tell the BIOS that this is bootable code.
Curufir

Re:what's wrong? why?

Post by Curufir »

Actually the BIOS loads 1 sector, the 0xAA55 just has to appear at 511-512 bytes offset into the bootsector to make it recognised as bootable.

Only pointing this out because if you're booting from a hardrive sectors can be 1024 bytes or more, which gives you a whole lot more room to play with (Almost enough for a fat12/16/32/e2fs loader in one go...hmm...new project :)). At least that's the way I read the manuals, could be wrong of course.

Curufir
Tom

Re:what's wrong? why?

Post by Tom »

Did adding the times and 0xaa55 work?
Tim

Re:what's wrong? why?

Post by Tim »

Only pointing this out because if you're booting from a hardrive sectors can be 1024 bytes or more
Not on any standard PC architecture. All sectors on all disks are 512 bytes in size, except CD-ROMs (and presumably DVDs) and certain disks on Japanese NEC PC98 systems, which are 2048 bytes.

In other words, any device with a boot sector will have 512-byte sectors.
Tom

Re:what's wrong? why?

Post by Tom »

That's good....you can write portable ( or media portable ) bootsectors...with little modifications :)
Schol-R-LEA

Re:what's wrong? why?

Post by Schol-R-LEA »

Tim Robinson wrote:
Only pointing this out because if you're booting from a hardrive sectors can be 1024 bytes or more
Not on any standard PC architecture. All sectors on all disks are 512 bytes in size, except CD-ROMs (and presumably DVDs) and certain disks on Japanese NEC PC98 systems, which are 2048 bytes.

In other words, any device with a boot sector will have 512-byte sectors.
Technically, Tom, Curfir is correct; the standard floppy and IDE controllers both have options for selecting the sector size, as a matter of fact. The sizes available for floppy disks are 128b, 256b, 512b, 1024b, and 4096b, if memory serves.

However, 512-byte sectors are the standard, and most BIOSes will have trouble booting from anything other than that. Furthermore, nearly all modern hard drives are hard-sectored to match a reference platter (which is why these drives have an odd number of heads - one of the r/w heads is replaced by the reference head, which is used to correct the alignment of the others) and cannot be reformatted to a different sector size. While it may seem an appealing way to increase the size of the boot sector size, it is really a very poor idea to use large sectors.
Dave_Hunt

Re:what's wrong? why?

Post by Dave_Hunt »

I think GertFaller has hit on the solution.

wentong's first attempt relocated the code to 0x0600, but then he essentially jumped to 0x7XXX. His attempted fix relocated to 0x0600, but attempted to jump to 0x6XXX (instead of 0x06XX). GertFaller's code fixes that.

Another potential gotcha here is the assumption that the boot code was loaded at 0x0000:0x7c00. Depending on the version of Bochs (or the BIOS of the target machine), it may have been loaded at 0x07C0:0x0000.

I know that when I upgraded Bochs at one point, my boot code stopped working. I found that the BIOS supplied with the newer version (don't remember which version it was), was loading at 0x07C0:0x0000.
Schol-R-LEA

Re:what's wrong? why?

Post by Schol-R-LEA »

This has been brought up before; while 0000:7C00 is the most common segment:offset pair, it is hardly universal. The usual recommendation is to start the boot loader with a far JMP to reset the segment base, which ensures that later code matches the origin:

Code: Select all

[ORG 0x0000]

StartBase   EQU 0x07C0

entry: 
    JMP StartBase:Start

Start:
    ...
This will work equally well if you change the origin to 0x7C00 and StartBase to 0x0000; which you should use is a personal choice.

Note that this would have to come after the short JMP that is used to bypass the BPB in FAT disks. Not only is there insufficient room before the BPB (three bytes) to hold a far jump, but Windows supposedly checks the first byte of a disk for the short jump opcode (0xEB) before trying to read a FAT disk and rejects it if there isn't one. This was done, allegedly, to penalize users of DR DOS, which used to uses a near jump, as the MS DOS did before v. 2.0. If you wanted your disk readable by DOS or Windows - a major reason for implementing FAT, esp. FAT12 - you have to use a short jump.
Tom

Re:what's wrong? why?

Post by Tom »

wentong's first attempt relocated the code to 0x0600
Why relocate the code?
wentong

Re:what's wrong? why?

Post by wentong »

thanks for everyone.

finally,i test my code sucessful by plus the following code under the top of [ORG 0]


========================
[org 0]
jmp short begin
nop


osname db 'xxxxxxxx'   
bytespersector dw 0x200   
sectorspercluster db 1
reservedsectors dw 1
numberoffats db 2
rootdirectoryentries dw 0x00E0
totalsectors dw 0x0B40
mediadescriptor db 0xF0
sectorsperfat dw 2
sectorspertrack dw 0x12
numberofheads dw 2
hiddensectors dd 0
totalsectorshuge dd 0
drivenumber db 0
reserved db 0
signature db 0x29
volumeid dd 0
volumename db 'xxxxxxxx'
filesystemtype db 'FAT12 '
            
begin:

*
*
*
*
*


this is the FAT bootable format ,i don't know why,but it can work. weird
   
Tom

Re:what's wrong? why?

Post by Tom »

id you try bootf.asm's code? [ John Fine's ]
Post Reply