2

I am using BIOS and want to make a self made operation system.

I am using the LBA method (int 0x13, ah=0x42) and successfully made it work on QEMU. But, when I let it work on a real PC, it does not work. It can only read 512bytes from USB.

When I used int 0x10 to show the problem, I finally figured out the problem. The memory does not move to referenced memory at all. My code is written below.

[bits 16]
[ORG 0x7c00]
        ;; BPB Structure                                                                                                                     
JMP     entry           ;BS_jmpBoot
NOP                                                                                                  
BS_OEMName      DB "HARIBOTE"
BPB_BytsPerSec  DW 0x0200
BPB_SecPerClus  DB 0x01
BPB_RsvdSecCnt  DW 0x0001
BPB_NumFATs     DB 0x02
BPB_RootEntCnt  DW 0x0000
BPB_TotSec16    DW 0x0000
BPB_Media       DB 0xf8
BPB_FATSz16     DW 0x0000
BPB_SecPerTrk   DW 0xffff
BPB_NumHeads    DW 0x0001
BPB_HiDDSec     DD 0x00000000
BPB_TotSec32    DD 0x00ee5000
BPB_FATSz32     DD 0x000000ed
BPB_ExtFlags    DW 0x0000
BPB_FSVer       DW 0x0000
BPB_RootClus    DD 0x00000000
BPB_FSInfo      DW 0x0001
BPB_BkBootSec   DW 0x0000
        times   12      DB 0    ;BPB_Reserverd                                                                                               
BS_DrvNum       DB 0x80
BS_Reserved1    DB 0x00
BS_BootSig      DB 0x29
BS_VolID        DD 0xa0a615c
BS_VolLab       DB "ISHIHA BOOT"
BS_FileSysType  DB "FAT32   "



entry:  
    CLI

        MOV AX, 0 
        MOV DS, AX
        MOV ES, AX
        MOV BX, AX
    MOV CX, AX
    MOV SP, 0x7c00
prepare:
        PUSH    CS
        POP     DS
        PUSH    CS
        POP     ES
    STI
    mov ah, 0x41                ; Set Function 0x41
        mov word bx, 0x55AA          
        push dx                     ; Save old Drive Identifier
        mov dl, 0x80                ; Load 'Active' ID Into dl, commented out to keep bios setting of dl (should be active drive)
        int 0x13                    ; Call Interupt
        jc unsupported        ; If Extentions aren't Supported, Jump
        xor ax, ax
        add ax, 1                   ; clear carry flag
    XOR EDI, EDI

    MOV AH, 0x45
    MOV AL, 0x01
    MOV DL, 0x80
    INT 0x13

loop:
    MOV CL, 0
retry:
    PUSH DS
    PUSHAD
        MOV DL, 0x80
        MOV AH, 0x42
    MOV AL, 0x00
        MOV SI, DAPS
        INT 0x13
        JNC next

        ADD CL, 1
        MOV DL, 0x80 
        MOV AH, 0x00
        INT 0x13
        CMP CL, 6
        JAE error
        JMP retry
next:

    XOR EAX, EAX
    XOR EBX, EBX
    XOR ECX, ECX

    ADD EDI, 1
    MOV ECX, lba0
    MOV [ECX], EDI

    XOR EAX, EAX
    XOR ECX, ECX
    XOR EBP, EBP

    MOV AX, [addr]
    MOV ECX, addr
    MOV EBX, segm
    ADD AX, 0x200
    ADC BP, 0
    SHL BP, 12
    ADD BP, [segm]
    MOV [EBX], BP


    MOV [ECX], AX
    MOV [EBX], BP

    CMP EDI, 0x16a
    JB loop

    MOV ECX, 0xc200
    JMP check
interrupt:
    MOV EAX, 0x0000
    MOV EBX, EAX
    MOV EDX, EAX
    MOV EBP, EAX
    MOV ESI, EAX
    MOV EDI, EAX

    MOV CH, 10
    MOV [0x0ff0], CH

    MOV ECX, EAX
        JMP 0xc200
error:
    POPAD
    POP DS
        MOV     SI,msg
putloop:
        MOV     AL,[SI]
        ADD     SI,1            
        CMP     AL,0
        JE      fin
        MOV     AH,0x0e         
        MOV     BX,15       
        INT     0x10           
        JMP     putloop
fin:
        HLT                     
        JMP     fin            
msg:
        DB      0x0a, 0x0a      
        DB      "load error"
        DB      0x0a            
        DB      0
msg1:
        DB      0x0a, 0x0a      
        DB      "not supported"
        DB      0x0a            
        DB      0

unsupported:
    MOV SI, msg1
    JMP putloop

drv:    DB 0x80
DAPS:   DB 0x10               ; Size of Structure (16 bytes, always this for DAPS)
        DB 0                  ; Always 0
        DB 1                  ; Number of Sectors to Read (1x512)
        DB 0                  ; Always 0 
addr:   DW 0x8000             ; Target Location for Reading To (0x8000 = 0x0800:0x0000)  
segm:   DW 0x0000             ; Page Table (0, Disabled)
lba0:   DD 1                  ; Read from 2nd block (code I want to load)
    DD 0                  ; Large LBAs, dunno what this does
check:
    MOV AH, 0x0e
    MOV AL, [ECX]
    ADD AL, 48
    MOV BX, 0
    INT 0x10
    ADD ECX, 1
    CMP ECX, 0xc400
    JNE  check

    JMP interrupt


        RESB    0x01fe-($-$$)       
        DW 0AA55h

So my question is:
Is BIOS access memory restricted during certain periods?
My BIOS is SMBIOS 3.0.0 and the model is ASUS x540la.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
石原秀一
  • 55
  • 2
  • 9
  • Your code probably has a bug in it, it could also be a difference in sector sizes of the media (not all media has 512 byte sectors). To determine sector size (INT 13h AH=48h: Extended Read Drive Parameters). Another possibility could be how you ar ebooting with USB (USB floppy or USB Hard Drive emulation). If using USB FDD (Floppy) emulation with USB you may need a BPB (BIOS parameter block) to avoid the BIOS potentially over writing code in your bootloader. There really isn't enough to go on here to give any definitive answer. – Michael Petch Apr 17 '18 at 21:36
  • Michael Petch, because the code is same, I did not put it on main comments.I put my code below.my usb is indeed 512byte per sector.The problem is, in qemu, the address seccessfully load 360sectors after 0x8000, but when I use int 0x10, I find it does not move to reference address at all in real machine. – 石原秀一 Apr 18 '18 at 04:23
  • The problem is in QEMU? Your questions says it works in QEMU. – Michael Petch Apr 18 '18 at 04:35
  • yes, In qemu, it works fine, but it does not work on real machine. – 石原秀一 Apr 18 '18 at 05:08
  • BTW, My usb is BUFFALO USB3.0 8GB RUF3-K8GA-BK/N.It does not even load data to reference place at all int "real machine". – 石原秀一 Apr 18 '18 at 05:30
  • sorry i have just edited the question – 石原秀一 Apr 18 '18 at 06:37
  • 1
    The code in your old question is not the code you posted in the now deleted answer. In particular your newer code relies on 32-bit registers in 16-bit mode. Why don't you post the code you are actually using in this question? – Michael Petch Apr 18 '18 at 06:49
  • You do realize that if you add 32 (decimal) to a segment that is the same as moving 512 bytes forward in memory (32*16=512). – Michael Petch Apr 18 '18 at 06:58
  • You set _SP_ but you don't actually set _SS_ to 0 – Michael Petch Apr 18 '18 at 07:00
  • I have just made it, set ss as 0, but it still doesn't work – 石原秀一 Apr 18 '18 at 08:14
  • Yes, here above is my new code.but it still does not work.SS has been setted to 0 already. – 石原秀一 Apr 20 '18 at 06:49
  • Humour me. What happens if you modify `JMP 0xc200` to be `JMP 0x0000:0xc200` (this will explicitly set CS to 0 as well as set IP to the offset 0xc200) – Michael Petch Apr 20 '18 at 07:30
  • I have changed to the code above, jmp 0x0000:c200, but it stlll does not work.it returns "000000...............00000000".Sorry, I am not pc engineer stuents and I am very very interested in pc skill.I dreamed to built my own os for several years and finally know how to use nasm 1 month ago.So what my question seems rediculous to you.sorry. – 石原秀一 Apr 20 '18 at 07:53
  • sorry for asking you too mucn, sorry for my poor englis – 石原秀一 Apr 20 '18 at 13:36
  • Remove these lines `prepare: PUSH CS POP DS PUSH CS POP ES` . You set DS and ES to 0 and then clobber those values by setting them to the value in CS. Prolem is on real hardware CS may not be 0 (some BIOSes use CS=0x07c0, IP=0x0000 to transfer control to your bootloader rather than 0x0000:0x7c00) – Michael Petch Apr 20 '18 at 14:20
  • Another problem with your code is that it always seems to assume the boot drive is 0x80. On some BIOSes USB Boot may not be drive 0x80. When control is transferred to your bootloader _DL_ contains the drive number that was booted from already. You should be using that value, rather than hard coding 0x80. – Michael Petch Apr 20 '18 at 14:42
  • I've marked this as a duplicate of a couple other answers. They are all related. I have written a set of general bootloader tips in this [SO answer](https://stackoverflow.com/a/32705076/3857942) that explains that you really can't rely on the segment registers to be what you are expecting so you really have to set them yourself. – Michael Petch Apr 20 '18 at 18:55

1 Answers1

0
   [bits 16]
[ORG 0x7c00]
        ;; BPB Structure                                                                                                                     
JMP     entry           ;BS_jmpBoot
NOP                                                                                                  
BS_OEMName      DB "HARIBOTE"
BPB_BytsPerSec  DW 0x0200
BPB_SecPerClus  DB 0x01
BPB_RsvdSecCnt  DW 0x0001
BPB_NumFATs     DB 0x02
BPB_RootEntCnt  DW 0x0000
BPB_TotSec16    DW 0x0000
BPB_Media       DB 0xf8
BPB_FATSz16     DW 0x0000
BPB_SecPerTrk   DW 0xffff
BPB_NumHeads    DW 0x0001
BPB_HiDDSec     DD 0x00000000
BPB_TotSec32    DD 0x00ee5000
BPB_FATSz32     DD 0x000000ed
BPB_ExtFlags    DW 0x0000
BPB_FSVer       DW 0x0000
BPB_RootClus    DD 0x00000000
BPB_FSInfo      DW 0x0001
BPB_BkBootSec   DW 0x0000
        times   12      DB 0    ;BPB_Reserverd                                                                                               
BS_DrvNum       DB 0x80
BS_Reserved1    DB 0x00
BS_BootSig      DB 0x29
BS_VolID        DD 0xa0a615c
BS_VolLab       DB "ISHIHA BOOT"
BS_FileSysType  DB "FAT32   "



entry:  
    CLI

        MOV AX, 0
        MOV DS, AX
    MOV SS, AX
        MOV ES, AX
        MOV BX, AX
    MOV CX, AX
    MOV SP, 0x7c00
prepare:
    STI
    MOV [drv], DL
        CMP     DL, 0x80
        JB      unsupported    ; HDD系デバイスでなければエラー

    MOV AH, 0x0e
    MOV AL, [drv]
    MOV BX, 0
    INT 0x10

    mov ah, 0x41                ; Set Function 0x41
        mov word bx, 0x55aa          
        int 0x13                   ; Call Interupt
        jc unsupported        ; If Extentions aren't Supported, Jump




        xor ax, ax
        add ax, 1                   ; clear carry flag
    XOR EDI, EDI

    MOV AH, 0x45
    MOV AL, 0x01
    MOV DL, 0x80
    INT 0x13

    MOV AX, 0
    MOV DS, AX

loop:
    MOV CL, 0
retry:
    PUSH DS
    PUSHAD
        MOV DL, [drv]
        MOV AH, 0x42
    MOV AL, 0x00
        MOV SI, DAPS
        INT 0x13
        JNC next

        ADD CL, 1
        MOV DL, 0x80 
        MOV AH, 0x00
        INT 0x13
        CMP CL, 6
        JAE error
        JMP retry
next:

    XOR EAX, EAX
    XOR EBX, EBX
    XOR ECX, ECX

    ADD EDI, 1
    MOV ECX, lba0
    MOV [ECX], EDI

    XOR EAX, EAX
    XOR ECX, ECX
    XOR EBP, EBP

    MOV AX, [addr]
    MOV ECX, addr
    MOV EBX, segm
    ADD AX, 0x200
    ADC BP, 0
    SHL BP, 12
    ADD BP, [segm]
    MOV [EBX], BP


    MOV [ECX], AX
    MOV [EBX], BP

    CMP EDI, 0x16a
    JB loop

    MOV ECX, 0xc200
    JMP check
interrupt:
    MOV EAX, 0x0000
    MOV EBX, EAX
    MOV EDX, EAX
    MOV EBP, EAX
    MOV ESI, EAX
    MOV EDI, EAX

    MOV CH, 10
    MOV [0x0ff0], CH

    MOV ECX, EAX
        JMP 0x0000:0xc200
error:
    POPAD
    POP DS
        MOV     SI,msg
putloop:
        MOV     AL,[SI]
        ADD     SI,1            
        CMP     AL,0
        JE      fin
        MOV     AH,0x0e         
        MOV     BX,0       
        INT     0x10           
        JMP     putloop
fin:
        HLT                     
        JMP     fin            
msg:
        DB      0x0a, 0x0a      
        DB      "load error"
        DB      0x0a            
        DB      0
msg1:
        DB      0x0a, 0x0a      
        DB      "not supported"
        DB      0x0a            
        DB      0

unsupported:
    MOV SI, msg1
    JMP putloop

drv:    DB 0x80
DAPS:   DB 0x10               ; Size of Structure (16 bytes, always this for DAPS)
        DB 0                  ; Always 0
        DB 1                  ; Number of Sectors to Read (1x512)
        DB 0                  ; Always 0 
addr:   DW 0x8000             ; Target Location for Reading To (0x8000 = 0x0800:0x0000)  
segm:   DW 0x0000             ; Page Table (0, Disabled)
lba0:   DD 1                  ; Read from 2nd block (code I want to load)
    DD 0                  ; Large LBAs, dunno what this does
check:
    MOV AH, 0x0e
    MOV AL, [ECX]
    ADD AL, 48
    MOV BX, 0
    INT 0x10
    ADD ECX, 1
    CMP ECX, 0xc400
    JNE  check

    JMP interrupt


        RESB    0x01fe-($-$$)       
        DW 0AA55h

Thank you, I finally figure out why.When I execute code above, it returned "not supported".It seems my bios does not support pure usb-hdd boot and my bios is usb-fdd emulator.All the question has been solved, thank you.

石原秀一
  • 55
  • 2
  • 9