flat assembler
Message board for the users of flat assembler.

Index > OS Construction > [ask] How to access memory more than 1 MB in pmode

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
christiandy



Joined: 03 Mar 2011
Posts: 25
Location: 101
christiandy
Hello there, i want to ask how to access memory more than 1 MB in Pmode. I still don't understand how GDT, LDT and IDT works.
In real mode we can access whole 1 MB memory with segment:offset.
this is still works in Pmode? and can we multitasking in real mode?
Post 26 May 2011, 17:05
View user's profile Send private message AIM Address Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
In Pmode, your segment registers hold "selector" instead of segment_base/16. "selector" is index to "descriptor table". "Descriptor table" (global or local, GDT or LDT) is table of "Descriptors" located somewhere in memory. "Descriptor" is a structure that describes a segment. One of fields in descriptor is "segment base address".

So if for example DS contains selector 8, descriptor at index 8 in GDT has segment base address 1000h, then address "DS:20h" corresponds to linear address 1020h, address DS:0 corresponds to 1000h, etc.


Last edited by vid on 26 May 2011, 19:46; edited 4 times in total
Post 26 May 2011, 18:11
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji

vid is absolutely right in his comment ...
but just a small typo.
(it's not to show off, really, but this typo hurts my eyes Razz )

if segment selector = 8
then his index in GDT = 1

Image

_________________
I am not young enough to know everything (Oscar Wilde)- Image
Post 26 May 2011, 19:11
View user's profile Send private message Send e-mail Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
yep, I was aware of that, I just simplified things a bit
Post 26 May 2011, 19:43
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji

I Knew that! (of course)
but I could not help myself Embarassed

_________________
I am not young enough to know everything (Oscar Wilde)- Image
Post 26 May 2011, 20:10
View user's profile Send private message Send e-mail Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
Sure, no problem
Post 26 May 2011, 20:31
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji
Quote:
can we multitasking in real mode?
one can't use multitasking in real mode, because there is no protected memory management.
The multitasking is possible only in protected mode ..
this is the first goal of protected mode.

_________________
I am not young enough to know everything (Oscar Wilde)- Image
Post 26 May 2011, 20:39
View user's profile Send private message Send e-mail Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Although not advised because of what it was pointed out above, as long as the programs cooperate with the system integrity (keep memory accesses to their own areas only, don't access hardware directly, and don't access the interrupt vector table nor any other stuff that should be controlled by the OS), multitasking should work (even in preemptive mode).
Post 26 May 2011, 21:59
View user's profile Send private message Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji

with these conditions multitasking is possible With DOS Wink

_________________
I am not young enough to know everything (Oscar Wilde)- Image
Post 26 May 2011, 22:23
View user's profile Send private message Send e-mail Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
This is a demo of multi-tasking in realmode, that needs no OS, as it fits into boot sector of floppy.
It won the first 512byte compo, that we ran on the fasm forum.
Code:
;
; ==============
;  Nano OS v2.1    copyright by Viktor Peter Kovacs (KVP)
; ==============  for the fasm 512 byte os contest of 2004
;
; This is a demo os, written to show some os design
; methods, and to proove that it's possible to put
; a simple multitasking os into 512 bytes...
;

; ---- constants ----

TIMER_IRQN equ (8)                                     ; hw. timer interrupt number
IRQ_BIT    equ (512)                                   ; 'irq enable' bit in the flags register

TS_FREE    equ (0)                                     ; task states
TS_READY   equ (1)
TS_SEND    equ (2)
TS_RECV    equ (3)
TS_PUTC    equ (4)
TS_GETC    equ (5)

E_TIDLIMIT equ (0ffffh)                                ; error code for task resource limit error

TID_NUM    equ (8)                                     ; maximal number of tasks allowed
TID_STACK  equ (512)                                   ; default task stack size

; ---- startup code ----

start0:                                                ; needed for compatibility
    jmp    start1
    nop
start1:
    jmp    07c0h:start2                                ; code segment alignement
start2:
    cli
    mov    ax, cs
    mov    ds, ax
    mov    es, ax
    mov    ss, ax
    mov    sp, stack_top
    cld
    mov    di, _bss_start                              ; zero the bss
    mov    cx, _bss_end-_bss_start
    xor    ax, ax
    rep    stosb

    push   es                                          ; change the irq vector table
    xor    bx, bx
    mov    es, bx
    mov    ax, [es:TIMER_IRQN*4]
    mov    [timer0l], ax
    mov    ax, [es:TIMER_IRQN*4+2]
    mov    [timer0h], ax
    mov    ax, timer_irq
    mov    [es:TIMER_IRQN*4], ax
    mov    ax, cs
    mov    [es:TIMER_IRQN*4+2], ax
    pop    es

    mov    cx, idle_task                               ; start idle task
    call   sys_exec
    mov    cx, prg1                                    ; start program 1 (rpc demo - data source)
    call   sys_exec
    mov    cx, prg3                                    ; start program 3 (hello world)
    call   sys_exec

    mov    ax, (TID_NUM-1)*2                           ; setup and enable the scheduler
    mov    [ctid], ax
    sti
idle_task:
    jmp    idle_task                                   ; the idle task

; ---- kernel code ----

timer_irq:
    push   bp                                          ; save task context
    push   di
    push   si
    push   dx
    push   cx
    push   bx
    push   ax

    mov    ax, [irqflg]                                ; kernel lock check
    or     ax, ax
    jz     timer_irq1
timer_irq0:
    pop    ax                                          ; restore task context
    pop    bx
    pop    cx
    pop    dx
    pop    si
    pop    di
    pop    bp
           db 0eah                                     ; jmp far to old handler (for compatibility)
timer0l    dw 00000h
timer0h    dw 00000h

timer_irq1:
    mov    ax, 1                                       ; lock kernel
    mov    [irqflg], ax

    mov    bx, [ctid]
    mov    ax, [tstate+bx]
timer_cmd1:
    cmp    ax, TS_SEND                                 ; ipc message send (blocking ipc)
    jnz    timer_cmd2
    mov    si, [msgtid+bx]
    mov    ax, [tstate+si]
    cmp    ax, TS_RECV
    jnz    timer_next
    mov    ax, [msgdat+bx]
    mov    [msgdat+si], ax
    mov    [msgtid+si], bx
    mov    ax, TS_READY
    mov    [tstate+si], ax
    jmp    timer_cmd_ok
timer_cmd2:
    cmp    ax, TS_PUTC                                 ; terminal write
    jnz    timer_cmd3
    mov    ax, [msgdat+bx]
    call   bios_putc
    jmp    timer_cmd_ok
timer_cmd3:
    cmp    ax, TS_GETC                                 ; terminal read
    jnz    timer_next
    call   bios_getc
    mov    [msgdat+bx], ax
    or     ax, ax
    jz     timer_next
timer_cmd_ok:                                          ; resume task
    mov    ax, TS_READY
    mov    [tstate+bx], ax
timer_next:

;; prints task states (see:TS_* constants; red=current task)
;; (used for testing, removed to save code space)
;    push   es
;    mov    ax, 0b800h
;    mov    es, ax
;    xor    di, di
;    mov    si, tstate
;debug_print:
;    lodsw
;    mov    ah, 15
;    add    al, '0'
;    stosw
;    cmp    si, tstate+TID_NUM*2
;    jnz    debug_print
;    mov    di, [ctid]
;    inc    di
;    mov    al, 12
;    stosb
;    pop    es

timer_next0:
    mov    bx, [ctid]                                  ; hard realtime round robin scheduler
    mov    [tstack+bx], sp
timer_next1:
    add    bx, 2
    and    bx, (TID_NUM-1)*2
    mov    [ctid], bx
    mov    ax, [tstate+bx]
    cmp    ax, TS_FREE
    jz     timer_next1
    mov    sp, [tstack+bx]

    xor    ax, ax                                      ; unlock kernel
    mov    [irqflg], ax
    jmp    timer_irq0

;
; <-
;  ax : char
;
bios_putc:                                             ; device i/o function (called internally)
    push   bp
    push   bx
    mov    ah, 00eh
    mov    bx, 00007h
    int    010h
    cmp    al, 13
    jnz    bios_putc1
    mov    al, 10
    int    010h
bios_putc1:
    pop    bx
    pop    bp
    ret

;
; ->
;  ax : char (0=no char)
;
bios_getc:                                             ; device i/o function (called internally)
    mov    ax, 00100h
    int    016h
    jnz    bios_getc1
    xor    ax, ax
    ret
bios_getc1:
    mov    ax, 00000h
    int    016h
    xor    ah, ah
    ret

; ---- standard library ----

;
; EXEC: Starts a new task
;
; <-
;  cx : code offset
; (ax, si)
; ->
;  bx : new tid (E_TIDLIMIT=out of task slots)
;
sys_exec:
    pushf                                              ; task table resource lock
    cli
    xor    bx, bx
sys_exec1:
    mov    ax, [tstate+bx]                             ; looks for a free task slot
    cmp    ax, TS_FREE
    jz     sys_exec2
    add    bx, 2
    cmp    bx, TID_NUM*2
    jnz    sys_exec1
    mov    bx, E_TIDLIMIT                              ; return error code
    popf
    ret
sys_exec2:
    mov    dx, bx
    mov    dh, dl
    xor    dl, dl
    mov    si, tstacks+TID_STACK-10*2                  ; allocate task stack
    add    si, dx
    mov    [tstack+bx], si
    mov    [si+7*2], cx                                ; set task startup context (cs:ip,flg)
    mov    ax, cs
    mov    [si+8*2], ax
    pushf
    pop    ax
    or     ax, IRQ_BIT
    mov    [si+9*2], ax
    mov    ax, TS_READY
    mov    [tstate+bx], ax                             ; activate new task
    shr    bx, 1
    popf                                               ; release task table lock
    ret

;
; EXIT: Exits a task
;
sys_exit:
    mov    bx, [ctid]
    mov    ax, TS_FREE
    mov    [tstate+bx], ax
    jmp    $

;
; SEND: Sends an ipc message
;
; <-
;  ax : msg
;  bx : dst
; (cx, bp)
;
sys_send:
    shl    bx, 1
    mov    cx, TS_SEND
sys_send0:
    mov    bp, [ctid]
    mov    [msgdat+bp], ax
    mov    [msgtid+bp], bx
    mov    [tstate+bp], cx
sys_send1:
    mov    ax, [tstate+bp]
    cmp    ax, TS_READY
    jnz    sys_send1
    ret

;
; RECV: Receives an ipc message
;
; ->
;  ax : msg
;  bx : dst
; (cx, bp)
;
sys_recv:
    mov    cx, TS_RECV
sys_recv0:
    mov    bp, [ctid]
    mov    [tstate+bp], cx
sys_recv1:
    mov    ax, [tstate+bp]
    cmp    ax, TS_READY
    jnz    sys_recv1
    mov    ax, [msgdat+bp]
    mov    bx, [msgtid+bp]
    shr    bx, 1
    ret

;
; PUTC: Outputs a character to the console
;
; <-
;  ax : chr
; (bx, cx, bp)
;
sys_putc:
    mov    cx, TS_PUTC
    jmp    sys_send0

;
; GETC: Inputs a character from the console
;
; (bx, cx, bp)
; ->
;  ax : chr (0=no char)
;
sys_getc:
    mov    cx, TS_GETC
    jmp    sys_recv0

; ---- application code ----

;; prg1 v1.0
;prg1:
;    call   sys_getc
;    or     ax, ax
;    jz     prg1
;    cmp    al, 'H'
;    je     prg1_1
;    call   sys_putc    
;    jmp    prg1
;prg1_1:
;    mov    cx, prg2
;    call   sys_exec
;    jmp    prg1

;
; prg1 v2.0
;  -on startup, starts a listerner task
;  -gets a character from the console and sends it via ipc
;  -on the 'H' key, starts a new 'hello world' process
;
prg1:
    mov    cx, prg2
    call   sys_exec
    mov    di, bx
prg1_0:
    call   sys_getc
    or     ax, ax
    jz     prg1_0
    cmp    al, 'H'
    je     prg1_1
    mov    bx, di
    call   sys_send
    jmp    prg1_0
prg1_1:
    mov    cx, prg3
    call   sys_exec
    jmp    prg1_0

;
; prg2 v1.0
;  -waits for incoming messages via ipc
;  -prints the message content on the console
;
prg2:
    call   sys_recv
    call   sys_putc
    jmp    prg2

;
; hello world v1.1
;  -prints the text 'Hello World!' on the console
;  -exits on completition
;
prg3:
     mov    si, prg3_str_hello
prg3_1:
     lodsb
     or     al, al
     jz     prg3_3
     call   sys_putc
     jmp    prg3_1
prg3_3:
     call   sys_exit

prg3_str_hello db 'Hello World!',13,0

; ---- boot flags ----
rb  510-$
dw  0aa55h

; ---- boot stack ----
rb  512
stack_top:

_bss_start:                                            ; uninitialized data area (cleared to 0 on start)

; ---- kernel data ----
irqflg rw 1                                            ; kernel lock
ctid   rw 1                                            ; current task

tstate rw TID_NUM                                      ; task states
tstack rw TID_NUM                                      ; task stack pointers
msgtid rw TID_NUM                                      ; message destination task ids
msgdat rw TID_NUM                                      ; message data

; ---- application data ----


; ---- task stacks ----

rb (512*4)-$

tstacks:
rb (TID_STACK*TID_NUM)

_bss_end:
                                                       
    
Post 26 May 2011, 22:52
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
Yep, and in fact TSRs provide some sort of multitasking (I think that even there were some MOD players capable of playing music in the background)

Also, I couldn't find reliable sources actually, but didn't Windows 1.0 and 2.0 work under 8086?
Post 26 May 2011, 23:04
View user's profile Send private message Reply with quote
ouadji



Joined: 24 Dec 2008
Posts: 1081
Location: Belgium
ouadji

nice piece of code Dex4u !

_________________
I am not young enough to know everything (Oscar Wilde)- Image
Post 26 May 2011, 23:18
View user's profile Send private message Send e-mail Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
ouadji wrote:

nice piece of code Dex4u !
I did not write it, my entry came second (i was called ASHLEY4 then).
You can get most of the entry's here:
http://board.flatassembler.net/topic.php?p=98270#98270
Post 26 May 2011, 23:44
View user's profile Send private message Reply with quote
christiandy



Joined: 03 Mar 2011
Posts: 25
Location: 101
christiandy
vid wrote:
In Pmode, your segment registers hold "selector" instead of segment_base/16. "selector" is index to "descriptor table". "Descriptor table" (global or local, GDT or LDT) is table of "Descriptors" located somewhere in memory. "Descriptor" is a structure that describes a segment. One of fields in descriptor is "segment base address".

So if for example DS contains selector 8, descriptor at index 8 in GDT has segment base address 1000h, then address "DS:20h" corresponds to linear address 1020h, address DS:0 corresponds to 1000h, etc.


Thanks all for replying. Can you give me an example like how to access memory 1fffffff ?
Post 27 May 2011, 04:43
View user's profile Send private message AIM Address Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville
christiandy wrote:
Can you give me an example like how to access memory 1fffffff ?
Code:
push 0
pop ds
mov al,[1fffffffh]    

Its that easy if you set up unreal mode or flat real mode first. You don't need pmode.

_________________
FAMOS - the first memory operating system
Post 27 May 2011, 09:20
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
Quote:
Its that easy if you set up unreal mode or flat real mode first. You don't need pmode.

Or doing things "the right way", you need to create descriptor with base address 0, load selector of that descriptor to DS, and then use "ds:1fffffffh". As for format of descriptor structure, you really should read CPU manuals, it's bit too messy to explain here quickly.
Post 27 May 2011, 09:48
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Mike Gonta



Joined: 26 Dec 2010
Posts: 238
Location: the-ideom
Mike Gonta
neville wrote:
christiandy wrote:
Can you give me an example like how to access memory 1fffffff ?
Code:
push 0
pop ds
mov al,[1fffffffh]    

Its that easy if you set up unreal mode or flat real mode first. You don't need pmode.
Code:
mov al,[1fffffffh]    
It's even easier if you setup 32 bit protected mode first (no setup required). You don't need real mode.

_________________
Mike Gonta
the-ideom - now you know how to compile

https://mikegonta.com


Last edited by Mike Gonta on 11 Feb 2012, 14:10; edited 1 time in total
Post 27 May 2011, 09:56
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
guys, question was about accessing RAM in protected mode, not about accessing RAM in whatever esoteric mode you find easiest to use.
Post 27 May 2011, 10:34
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Mike Gonta



Joined: 26 Dec 2010
Posts: 238
Location: the-ideom
Mike Gonta
vid wrote:
guys, question was about accessing RAM in protected mode, not about accessing RAM in whatever esoteric mode you find easiest to use.
Exactly.
You'll notice that in real mode the questions are not about real mode. It's there, you just use it. You don't have
to mess with the A20, remap the PIC, build an IDT and stuff a bunch of registers. All of which is necessary
but not OS. The BIOS takes care of it.
You'll notice that in protected mode the questions are about protected mode. It's not there, you can't just use it.
You have to mess with the A20, remap the PIC, build an IDT and stuff a bunch of registers. All of which is necessary
but not OS.

_________________
Mike Gonta
the-ideom - now you know how to compile

https://mikegonta.com
Post 27 May 2011, 18:18
View user's profile Send private message Visit poster's website Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
Basic boot to pmode
Code:
;************************************
; By Dex
; Assemble with fasm 
; c:\fasm pmode.asm pmode.bin
;
org 0x7C00 

use16
;****************************
; Realmode startup code.
;****************************
start:
        xor   ax,ax
        mov   ds,ax
        mov   es,ax
        mov   ss,ax
        mov   sp,0x7C00 
;****************************
; A20
;****************************
  cli                                    
     mov   al,255                           
     out   0xa1,al
       out   0x21,al
l.5:       in    al,0x64                          
     test  al,2                             
     jnz   l.5                              
     mov   al,0xD1                          
     out   0x64,al                          
l.6:     in    al,0x64                          
     test  al,2
  jnz   l.6                              
     mov   al,0xDF                          
     out   0x60,al                          
     mov   cx,14h
l.7:                                               
     out   0edh,ax                          
     loop  l.7       
;*****************************
; Small delay.
;*****************************                 
     mov   ecx,0xffff                                  
  A20_delay:                                            
  nop                                               
  nop                                               
  loop  A20_delay                           
;*****************************
; Setting up, to enter pmode.
;*****************************
        
        lgdt  [gdtr]
        
        mov   eax, cr0
        or    al,0x1 
        mov   cr0,eax
 
        jmp   0x10: protected

;*****************************
; Pmode. Wink
;*****************************
use32
protected:
        mov   ax,0x8 
        mov   ds,ax
        mov   es,ax
        mov   ss,ax
;*****************************
; Turn floppy off.
;*****************************

        mov   dx,3F2h
        mov   al,0
        out   dx,al

        mov   edi,0x1fffffff
        mov   eax,1
        stosb
Letsloop:
        hlt
        jmp   Letsloop

;*************************************
; GDT. 
;*************************************

gdt:        dw    0x0000, 0x0000, 0x0000, 0x0000
sys_data:   dw    0xFFFF, 0x0000, 0x9200, 0x00CF
sys_code:   dw    0xFFFF, 0x0000, 0x9a00, 0x00CF
gdt_end:

gdtr:       dw gdt_end - gdt - 1                                          
            dd gdt 

            
times 510- ($-start)  db 0  
dw 0xaa55
                                      
    


Last edited by Dex4u on 29 May 2011, 00:00; edited 6 times in total
Post 27 May 2011, 18:27
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.