News:

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

Memory Map

Started by zak100, February 19, 2010, 06:21:07 PM

Previous topic - Next topic

dedndave

right - he probably doesn't need to go through all the trouble i was going through
i wanted to see the driver in memory before COMMAND.COM was loaded
that is why i went that route

zak100

Hi,
Sorry, is this exercise going to help me to get around with int 15h problem
during Debugging?

I am using a floppy disk in which I am storing the bootloader &
the kernel. I have got following Questions:
i) Do I have to use another floppy?
ii) Do I have to change my config.sys and autoexec.bat?
iii)I dont know if I have Dos 6.2. When I type ver, its telling
me the version of OS & not DOS?
iv)If i change my config.sys & Autoexec.bat with the listing provided by
Steve, is it going to do everything, I mean setup the RAM disk & load the
Debug.

Thanks for telling me this new thing.

Zulfi.

FORTRANS

Hi Zulfi,

   Since your code is working for me in DEBUG, I will redo it
as a boot loader to see if anything changes.  But that may
take a while.

Quote from: zak100 on June 09, 2010, 04:32:05 AM
Hi,
Sorry, is this exercise going to help me to get around with int 15h problem
during Debugging?

   Well, that was the idea.  But of course it may not work.  Or
you can procede as you are doing now.

Quote
I am using a floppy disk in which I am storing the bootloader &
the kernel. I have got following Questions:
i) Do I have to use another floppy?

   Probably a very good idea to do so, but not required.

Quote
ii) Do I have to change my config.sys and autoexec.bat?

   If you mean reusing the CONFIG.SYS and AUTOEXEC.BAT
from a Windows system, then yes you cannot use that on a
DOS floppy.

Quote
iii)I dont know if I have Dos 6.2. When I type ver, its telling
me the version of OS & not DOS?

   Right, you probably do not have MS-DOS 6.2.  You can get
"FreeDOS" or another real-mode MS-DOS clone if you don't
have access to a DOS or Windows 9x system.  From what
you have said, you probably have some version of NT style
Windows.

www.freedos.org/

Quote
iv)If i change my config.sys & Autoexec.bat with the listing provided by
Steve, is it going to do everything, I mean setup the RAM disk & load the
Debug.

   You will have to format a bootable DOS diskette.  Then copy
the RAM Disk driver, DEBUG, DOSKEY, your code, an _old_
version of MASM, and LINK16 to the disk.  Then you can use
the CONFIG.SYS and AUTOEXEC.BAT I posted assuming you
put everything in the same places I did.  You don't need to
worry about the RAM drive, that is just an extra I use. Oh,
EXE2BIN will be needed for making a COM style executable.
And you may want an editor.

   The basic idea was to avoid rebooting after each modification
of the code.  That drove me nuts.  I had/have computers set
up with DOS so things were fairly simple for me to switch over
from a boot loader to DEBUG.  The computer I mostly used
for this is no longer usable, so things are going a bit slower
now.

HTH,

Steve N.

FORTRANS

Hi,

   Okay, another failure mode found.  My version of this code
assembles to longer than 512 bytes for the boot loader binary.
So I had to modify the boot sector to load two sectors.  Or
it's silently off to la-la land.  And at least it now works as an
independent boot.

Regards,

Steve N.

zak100

Hi Steve and Dave (and everybody else who has helped me with this problem),
I have decided to continue my work on memory map. I am working on Debug related stuff in another thread. I have completed the code (using the downloaded stuff), but its not giving me any results. It hangs up after printing character 'A'.



;               Entire code of MemMap: Printing the base address and length in a loop
;-------------------------------------------------------------
;ml /c memMp4.asm
;link16 /tiny memMp4.obj,memMp4.bin;
;DEBUG Btl3p_3.BIN
;-w 100 0 0 1
;-q

;DEBUG memMp4.BIN
;-w 100 0 1 1
;-q

.MODEL  TINY
.386

print_mesg macro offsetStr, offsetScr, msgSize
       LOCAL xlat0

       mov     ax,cs
       mov     ds,ax
       push    ax
       mov     ax,xlat0
       push    ax
       retf


;display the message at B800:50h

xlat0: mov     ax,0B800h     
       mov     es,ax
       mov     di, offsetScr
       mov     si, offsetStr
       cld
       mov     ah,1Fh
       mov     cx,msgSize
endm



.CODE

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

LoadOfs EQU     0               ;must match the value in the bootloader source file
LoadSeg EQU     1000h

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

;---------------------- initialize ES segment register

        ORG     0

Start:  push    cs
        pop     ds
       
;-----------clear screen
mov ax, 3
int 10h

   
;---------------------- writing a message on screen at startup, character by character- we can't use int 21h
overdata:
       
        xor di, di
        mov ax, 0B800h
        mov es, ax
        mov si, offset msg0+LoadOfs
       mov ah, 41h; attribute byte
       cld;
msgloop:
        lodsb; loads al with a byte of data pted by ds:si
        or al, al
        jz TimerMesg
        stosw; transfers the contents of al to mem location ptd by es:di
        jmp msgloop
       
;---------------------- done - halt; NOT A CLK PROG
TimerMesg:

        xor di, di
        mov ax, 0B820h
        mov es, ax
        mov si, offset msgA+LoadOfs
       mov ah, 41h; attribute byte
       cld;
msgAloop:
        lodsb; loads al with a byte of data pted by ds:si
        or al, al
        ;jz RTime
        jz mem
        stosw; transfers the contents of al to mem location ptd by es:di
        jmp msgAloop
        mov cx, 1000
;DISPLAY_TIMER:
;-------------Find Total Memory
mem:        cld
        ;call    FindTotalMem    ;calculate total memory (sets the SI register)
        mov     ah,7            ;display attribute
        mov     di,0            ;display position
        ;call    Dsply           ;display total memory
        call do_e820_Step1
        ;call Qw2Hex by Dave (instead using code provided by Fortran or Steve)

Halt0: hlt
jmp     Halt0


Msg0    db      "We be bootin234!",0
msgA db 'Total minutes elapsed since Kernel start is',0
clkcounter db 0
secs db 0
mins db 0
hrs  db 0
cnt  db 0; Its value represents the digits of Timer
s    db 0; selector for secs minutes and hrs used in displayCnt
arr  db 16 dup(0)
VAL1 db 0
VAL2 db 0
ScrCoord dw 50h ;dx stores the screen location for displaying Base address & region length
                ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Macro argument
AscBuf  db      8 dup (0),' Kb Total Memory',0
mmap_ent dw ?
end_of_list db 1
MyArg   EQU     <offset arr+LoadOfs>

       
MMap_Descriptor STRUCT
  BaseAddress   DQ      ?       ; * First qword = Base address
  ByteLength    DQ      ?       ; * Second qword = Length of "region"
  RangeType     DW      ?       ; * Next dword = Region "type"
  ACPI_Attrib   DW      ?       ; * Next dword = ACPI 3.0 Extended Attri
MMap_Descriptor ENDS

Call15_1        MMap_Descriptor <>      ; Set DI to point to the first one, and
Call15_2        MMap_Descriptor <>      ; increment by 24  to point to second.
Call15_3        MMap_Descriptor <>
Call15_4        MMap_Descriptor <>
Call15_5        MMap_Descriptor <>


;---------------do_e820_Step1
do_e820_Step1:
        push es
        push cs
        pop es
        mov di, offset call15_1+LoadOfs
xor ebx, ebx ; ebx must be 0 to start
xor bp, bp ; keep an entry count in bp
mov edx,0534D4150h ; Place "SMAP" into edx
mov eax, 0e820h
mov dword ptr es:[di + 20],  1 ; force a valid ACPI 3.X entry. This reqd to set last
                                ;dword to 1 before each call
mov ecx, 24 ; ask for 24 bytes
int 15h
jc short failed         ; carry set on first call means "unsupported function"
mov edx, 0534D4150h ; Some BIOSes apparently trash this register?
cmp eax, edx ; on success, eax must have been reset to "SMAP"
jne short failed
test ebx, ebx ; ebx = 0 implies list is only 1 entry long (worthless)
je short failed
jmp short jmpin
e8201p:
        mov eax, 0e820h
        mov dword ptr es:[di + 20], 1
        mov ecx, 24
        int 24h
        jc short e820f
        mov edx, 0534D4150h
jmpin:
jcxz skipent ; skip any 0 length entries
cmp cl, 20 ; got a 24 byte ACPI 3.X response?
jbe short skipent
test byte ptr es:[di + 20], 1 ; if so: is the "ignore this data" bit clear?
                                ;Bit 0 of the extended Attributes indicates if the entire
                                ; entry should be ignored
je short skipent
        mov ecx, dword ptr es:[di+8]; get lower dword of memory region length; i.e from 8 to 11
        test ecx, ecx;          ; is the qword=0????
        jne short goodent
        mov ecx, dword ptr es:[di+12];i.e from 12 to 15
        jecxz skipent
goodent:
        inc bp
        ;---------------------------    ;NOTE QW2HEX$ converts to Hex & prints using Macro
                 
        call QW2Hex$            ;Displaying the base address
       
;## You are not pausing after showing the first value before showing the second.
;## And they both print at the same location on screen.
        MOV     AX,0    ;## Pause?
        INT     16H
       
        push di
        add di, 8               ;Length of region starts 15 bytes from current val
                                ;In the procedure we adding 7 to di
        call QW2Hex$            ;Displaying the length of region 
        pop di
        add di, 24
         
skipent:
test ebx, ebx ; if ebx resets to 0, list is complete
jne short e8201p
     
;-------------------------
       
e820f:
mov mmap_ent, bp ; store the entry count
        pop es
        ret

failed:
stc ; "function unsupported" error exit
        pop es
ret

QW2Hex$:
        PUSH    DI      ; Save registers used by routine.
        PUSH    AX
        PUSH    CX
        PUSH    ES

        STD             ; String instructions decrement.

        ADD     DI,7    ; Point to last byte, (Intel big end).
                        ; When called 1st DI=0. Now DI =7. So print from 7 to 0. So it pints the Base address
                        ; When called 2nd time DI=8. After adding DI=15. So it prints the length of region

        mov si ,offset arr+LoadOfs
        MOV     CX,8    ; Number of bytes to print. QWORD = 8 bytes
                        ;
QW_1:
        MOV     AL,ES:[DI]      ; Get a byte
        DEC     DI
       
        CALL TOASCII    ; Display as hex.
        mov  dl, VAL1
        mov  [si], dl   ; store the values in array and display array later
        inc si
        mov  dl, VAL2
        mov  [si], dl
        inc si
        LOOP    QW_1
;---------------------------Calling Macro with the screen coordinates
       
        ;print_mesg MyArg, 50h, 16;
        print_mesg MyArg, ScrCoord, 16;<------------------
        nextval: lodsb
                 stosw
        loop nextval
       
        POP     ES
        POP     CX
        POP     AX
        POP     DI

        RET
;---------------------------------------------------
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;    This routine converts the one byte binary number in the
; AL register into its hexadecimal ASCII representation and
; prints these two bytes to the standard output or console.
; 4 March 2010,
;   Changed TOASCII routine to use AAM varient instead of MOV,
; AND, and SHR codes on nybbles.

TOASCII:
        PUSH    AX      ; Make safer for debugging.
        PUSH    DX

        XOR     AH,AH   ; Clear AH for AAM using base 16.
DB      0D4H, 10H       ; Isolates high nybble in AH and low
                        ; nybble in AL.
        PUSH    AX      ; Save low nybble.
        MOV     AL,AH   ; And process high digit first.

        CMP     AL,10   ; Convert to ASCII hex using "magic".
        SBB     AL,69H
        DAS

        MOV     DL,AL
        mov     VAL1, al
        ;CALL ConOutByte ; DOS Fn 2 or BIOS 10H Fn 0EH (or whatever).

        POP     AX      ; Retrieve low digit in AL.

        CMP     AL,10   ; Convert to ASCII hex.
        SBB     AL,69H
        DAS

        MOV     DL,AL
        mov     VAL2,al
;        CALL ConOutByte

        POP     DX
        POP     AX

        RET

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



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

        END     Start







Can anybody check the problem?

Zulfi.

FORTRANS

Hi,

   Did you make the changes suggested in Reply #93?  I made
only minor changes to your code and it is working for me.  Alter
the boot sector to load two sectors instead of one.  And of course
write out two sectors from DEBUG.

   If you did make those changes, I would add a failure message
for the test for a "good interrupt".


failed:
     : Write a message to the screen. "INT E820 not supported".
stc ; "function unsupported" error exit
        pop es
ret

zak100

Thanks. I read your reply again and now its clear to me. I would try to do the required changes. I have not checked the size of my binary yet.

Zulfi.

zak100

Hi Steve, Dave ( and every person who is helping me with this code),
I have modified the boot sector program. I dont know whether its correct or not so I want to get some comment  from you people.
The code is given below:
 
;*
;ml /c btl3p_4.asm
;link16 /tiny btl3P_4.obj,btl3P_4.bin;
;
;DEBUG btlder3P_4.BIN
;-w 100 0 0 1
;-q

;DEBUG sect4_2.BIN
;-w 100 0 1 1
;-q
;*

.MODEL  TINY
        .CODE
;----------------------------------------------------------------------------------

LoadOfs EQU     0
LoadSeg EQU     1000h

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

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

        ORG     0

Boot0:  jmp short Boot1
nop
;---------------------- OEM identifier

        ORG     3

        DB      "Zulfi OS"

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

        ORG     0Bh

bpbBytesPerSector    DW 512
bpbSectorsPerCluster DB 2; 1
bpbReservedSectors   DW 1
bpbNumberOfFATs      DB 2
bpbRootEntries       DW 112; 224
bpbTotalSectors      DW 1440; 2880
bpbMedia             DB 0F9H; 0F0h
bpbSectorsPerFAT     DW 3; 9
bpbSectorsPerTrack   DW 9; 18; different (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   "
SectorNum            DB  1
LoadOfsvar      DW  LoadOfs

;---------------------- 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 bootloader
ReadSectorLoop:
        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,LoadOfsVar

        call    ReadSectors
        pop     cx
        jnc     PreReadNextSector
        loop    Reset0
        jc      ReadError   ;After 5th try display error message
        jmp     Exec0
PreReadNextSector:
        inc     SectorNum
        cmp     SectorNum, 3; ---------------reading first 2 sectors
        jz      Exec0
        add     LoadOfsVar, 512
        jmp     ReadSectorLoop

;---------------------- failed 5 times - halt
;---display 'F' character  to show the failure occured
ReadError:
mov ax, 0B800h
mov es, ax
mov Di,4
mov ax, 9c46h
stosw


Halt0:  hlt
      jmp     Halt0
;----------------------
ReadSectors:
      mov ax, 201h ;ah=2 function, al=1 (read 1 sector only)
      mov ch,0; Track
      mov cl, sectorNum ;Sector start with 1 not 0
      xor dx, dx; Head 0, drive 0
      int 13h
      ret

;---------------------- 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



About the Kernel, do I have to break it into two separate executable programs? Kindly advise me how to break the Kernel?

Zulfi.

FORTRANS

Hi,

QuoteAbout the Kernel, do I have to break it into two separate executable programs?

   I didn't.  I did a little less work with my version.  Here is
what I did.


COMMENT * Original code by dedndave on MASM32 Forum.  Modifications,
additions, tpyos, and corrections FORTRANS (Steve) on MASM32 Forum.
27 November 2009
10 June 2010 load two sectors.

REM Create BooSect.BIN, NOT sure about ML switches.
\MASM32\BIN\ML /AT /c /Fl /Fm BootSect.ASM
\MASM32\BIN\LINK16 BootSect.OBJ;
EXE2BIN BootSect.EXE

11/27/2009  04:02p                  40 BOOTLOAD.BIN
11/27/2009  04:02p                 512 BOOTSECT.BIN
06/09/2010  03:24p                 548 TEST22.BIN

DEBUG BootSect.BIN
-w 100 0 0 1
-q

DEBUG BootLoad.BIN
-w 100 0 1 2
-q

TODO:  Use a different sector to write/read BootLoad.BIN to.
       Convert to hexadecimal and display contents of CS and IP.
       Fix up messages...
*

        .MODEL  TINY
        .CODE

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

LoadOfs EQU     0
LoadSeg EQU     1000h

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

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

        ORG     0

Boot0:  jmp short Boot1
        NOP     ; - - - Mods to deadndave's code: Win2K error fix,
                ; - - - original was a zero.

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

        ORG     3

        DB      "Steve OS"

;---------------------- BIOS parameter block for 1.44 Mb floppy disk
; - - - Mod to 720K - - -

        ORG     0Bh

bpbBytesPerSector    DW 512
bpbSectorsPerCluster DB 1 ; 2 ; 1   Mods to deadndave's code: Cluster size,
                             ; may/may not have caused a problem?  He was okay?
bpbReservedSectors   DW 1
bpbNumberOfFATs      DB 2
bpbRootEntries       DW 112  ; 224    Mods to deadndave's code: 720 K
bpbTotalSectors      DW 1440 ; 2880   diskette instead of 1.44 M
bpbMedia             DB 0F9H ; 0F0h
bpbSectorsPerFAT     DW 3    ; 9
bpbSectorsPerTrack   DW 9    ; 18
bpbHeadsPerCylinder  DW 2
bpbHiddenSectors     DD 0
bpbTotalSectorsBig   DD 0
bsDriveNumber        DB 0
bsUnused             DB 0
bsExtBootSignature   DB 29h
bsSerialNumber       DD 0DeadBeefH
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       ; CGA text memory segment
        mov     es,ax
        mov     ax,1F41h
        stosw                   ; Store character and attribute.

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

        mov     ah,0            ; Keboard BIOS wait for character.
        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 (1 based)
        xor     dx,dx           ;head 0, drive 0
        mov     ax,202h         ;read 2 sectors
        int     13h
        pop     cx
        jnc     Exec0

        loop    Reset0

;---------------------- failed 5 times - halt
; - - - Display 'F' character - - -
; - - - to show the failure occured.

        mov     ax,0B800h
        mov     es,ax
        mov     DI,4    ; Move a bit to avoid the 'A',
        mov     ax,9C46h; 9C attribute should be ugly.
        stosw

Halt0:  HLT
        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

zak100

Hi,
Thanks for your help. The boot sector code is working. But my kernel is still showing only the base address & region length of only the first region. I posted its (kernel) code on June 14, 2010. Can somebody please guide me with this?

Zulfi.

sinsi


e8201p:
        mov eax, 0e820h
        mov dword ptr es:[di + 20], 1
        mov ecx, 24
        int 24h

int 24h? Maybe try int 15h.
Light travels faster than sound, that's why some people seem bright until you hear them.

zak100

Hi,
Thanks for your help sinsi. In my opinion it should work but now I am not even getting the base address and length of 1st region. However I am getting 'A' and all the string messages. Kindly provide me more guidance on this.

Zulfi.

FORTRANS

Hi,

Quote from: zak100 on June 19, 2010, 06:14:41 PM
Thanks for your help. The boot sector code is working. But my kernel is still showing only the base address & region length of only the first region. I posted its (kernel) code on June 14, 2010. Can somebody please guide me with this?

   Well, one of the things you should do is preserve the contents of
EBX to do another Int 15H.  The 0E820H function wants the value
it returned from the last call to allow it to get the next region.  The
OSDev Wiki code does this, but your printing the values changes
it.  That code was intended to store all the regions and let the user
process them afterwards.  And in debugging the code I found that
you can get very strange errors sometimes if you have an invalid
value in EBX.

   MichaelW's MemMap code process each region after the interrupt,
like you are doing.  So you may want to look at his code to see how
and where he uses EBX.  I am using the Wiki code as you started
with, but process all the regions afterward.  This lets me sort the
entries as suggested in the Wiki article.  A bit of warning, if you store
the values in an array, you should count the regions returned so you
don't overflow your array.  That was messy on one of my machines.

   Just to show the effect of the sort, I'll post the output of my program
and MichaelW's.

Regards,

Steve N.


SRN's MemTest

   Memory Map returned by system interrupt 15H Function E820H:

      Base       Length   Usable Size    Type
    00000000    0009FC00      654336    Usable (normal) RAM.
    0009FC00    00000400           0    Reserved, not available.
    000F0000    00010000           0    Reserved, not available.
    00100000    0FEF0000   267321344    Usable (normal) RAM.
    0FFF0000    00003000           0    ACPI NVS memory.
    0FFF3000    0000D000           0    ACPI reclaimable memory.
    FFFF0000    00010000           0    Reserved, not available.
    --------    --------  -----------
    Total Usable Memory:   267975680

MichaelW's MemMap.exe

Memory Map returned by Interrupt 15h Function E820h:

BASE=00000000h LENGTH=0009FC00h (654336)TYPE=AVAILABLE
BASE=0009FC00h LENGTH=00000400h (1024)TYPE=RESERVED
BASE=000F0000h LENGTH=00010000h (65536)TYPE=RESERVED
BASE=FFFF0000h LENGTH=00010000h (65536)TYPE=RESERVED
BASE=00100000h LENGTH=0FEF0000h (267321344)TYPE=AVAILABLE
BASE=0FFF3000h LENGTH=0000D000h (53248)TYPE=ACPI_RECLAIM
------------------------------------------------------------
TOTAL LENGTH          0FFBD000h (268161024)

Extended Memory size returned by Interrupt 15h Function 88h = 0 bytes

Extended Memory size from CMOS RAM = 67043328 bytes

Press any normal key to exit...

zak100

Hi,
I tried to search MichealW's code on this forum but I am not lucky in this regard. Can you people provide me a link for his code?

Zulfi.

MichaelW

eschew obfuscation