flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Entering long mode - simple examples

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



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 18 Nov 2006, 16:16
While playing with the 64-bit machine I wrote some samples that may be the simplest available examples of entering the long mode. Below I provide the smallest one, which enters long mode without re-enabling interrupts and thus saves on setting up the IDT. The attachment contains the extended version of this sample, which sets up the interrupts and alters two characters on the screen according to the clock and keyboard events, to show that everything's working (and reboots on the Esc key).

To run those samples it's enough to load them somehow at 0:1600h address and jump there (also some other zero-based address may be used, it's enough to alter the ORG directive in the beginning of sources). The PetroffHeroj's FAT12 boot loader (available in the Examples section of this website) is a simple option if you want to boot from floppy.

Oh, and by the way, the color text mode has to be enabled (you may just add "mov ax,3"/"int 10h" at the beginning of code to ensure this). The samples are also not caring about disabling NMI et caetera - they should not interfere in normal environment.

OK, here goes the shortest sample:
Code:
        ORG     1600h

        USE16

        cli                             ; disable the interrupts, just in
                                        ; case they are not disabled yet

        lgdt    [cs:GDTR]               ; load GDT register

        mov     eax,cr0                 ; switch to protected mode
        or      al,1
        mov     cr0,eax

        jmp     CODE_SELECTOR:pm_start


NULL_SELECTOR = 0
DATA_SELECTOR = 1 shl 3                 ; flat data selector (ring 0)
CODE_SELECTOR = 2 shl 3                 ; 32-bit code selector (ring 0)
LONG_SELECTOR = 3 shl 3                 ; 64-bit code selector (ring 0)

GDTR:                                   ; Global Descriptors Table Register
  dw 4*8-1                              ; limit of GDT (size minus one)
  dq GDT                                ; linear address of GDT

GDT rw 4                                ; null desciptor
    dw 0FFFFh,0,9200h,08Fh              ; flat data desciptor
    dw 0FFFFh,0,9A00h,0CFh              ; 32-bit code desciptor
    dw 0FFFFh,0,9A00h,0AFh              ; 64-bit code desciptor

        USE32

pm_start:

        mov     eax,DATA_SELECTOR       ; load 4 GB data descriptor
        mov     ds,ax                   ; to all data segment registers
        mov     es,ax
        mov     fs,ax
        mov     gs,ax
        mov     ss,ax

        mov     eax,cr4
        or      eax,1 shl 5
        mov     cr4,eax                 ; enable physical-address extensions

        mov     edi,70000h
        mov     ecx,4000h shr 2
        xor     eax,eax
        rep     stosd                   ; clear the page tables

        mov     dword [70000h],71000h + 111b ; first PDP table
        mov     dword [71000h],72000h + 111b ; first page directory
        mov     dword [72000h],73000h + 111b ; first page table

        mov     edi,73000h              ; address of first page table
        mov     eax,0 + 111b
        mov     ecx,256                 ; number of pages to map (1 MB)
  make_page_entries:
        stosd
        add     edi,4
        add     eax,1000h
        loop    make_page_entries

        mov     eax,70000h
        mov     cr3,eax                 ; load page-map level-4 base

        mov     ecx,0C0000080h          ; EFER MSR
        rdmsr
        or      eax,1 shl 8             ; enable long mode
        wrmsr

        mov     eax,cr0
        or      eax,1 shl 31
        mov     cr0,eax                 ; enable paging

        jmp     LONG_SELECTOR:long_start

        USE64

long_start:

        mov     rax,'L O N G '
        mov     [0B8000h],rax

        jmp     long_start    


If you find it useful, I may put into Examples section, too.


Description: Entering long mode and interrupt handling - simple example.
Download
Filename: basecode.asm
Filesize: 3.8 KB
Downloaded: 1324 Time(s)

Post 18 Nov 2006, 16:16
View user's profile Send private message Visit poster's website Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u 18 Nov 2006, 17:12
Thanks alot Tomasz Grysztar Cool, these are the simplest and cleanest example i have seen to enter long mode.
I and alot of other people will find them very usesfull.
Thanks again.
Post 18 Nov 2006, 17:12
View user's profile Send private message Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 19 Nov 2006, 02:58
Shocked And I thought PMode was crazy...

Thanks very much for the example, now I can read up on all these bits and try and make sense of it all! Then there's the minor technicality of acquiring a 64bit CPU Confused Laughing
Post 19 Nov 2006, 02:58
View user's profile Send private message Reply with quote
Mac2004



Joined: 15 Dec 2003
Posts: 314
Mac2004 19 Nov 2006, 20:55
Hi Tomazs!

I tried to compile your example as .com file by changing the org directive from 1600h to 100h, but it didn't work. Computer just resets when I try to run the com under ms-dos. I have got AMD64 3500.

regards,
Mac2004
Post 19 Nov 2006, 20:55
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 19 Nov 2006, 21:00
It must be loaded at the physical address defined by ORG - thus if you use "org 100h" you must load it at address 0:100h and then jump to it.

To run it from DOS (without changing the default "org 1600h"), you can make a wrapper-loader like:
Code:
        org     100h

        cli

        push    0
        pop     es

        mov     di,1600h
        mov     si,basecode
        mov     cx,basecode_length
        rep     movsb

        jmp     0:1600h

basecode file 'BASECODE.BIN'
basecode_length = $ - basecode    

where BASECODE.BIN must be a file assembled from the example source posted above.
Post 19 Nov 2006, 21:00
View user's profile Send private message Visit poster's website Reply with quote
Mac2004



Joined: 15 Dec 2003
Posts: 314
Mac2004 19 Nov 2006, 21:05
Should ms-dos load com programs always to 100h?

regards,
Mac2004
Post 19 Nov 2006, 21:05
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 19 Nov 2006, 21:14
MS-DOS loads program into an allocated segment, and within that segment the offset of program code is always 100h for the .com programs, however it never will be the 0 segment, as this memory area is already used.

For example if DOS allocates the segment 300h for you, it creates the 256-byte PSP for your program at 300h:0 and loads the code of your program at 300h:100h. However the flat linear address that corresponds to 300h:100h is 300h*16+100h=30100h, not 100h.
Post 19 Nov 2006, 21:14
View user's profile Send private message Visit poster's website Reply with quote
Mac2004



Joined: 15 Dec 2003
Posts: 314
Mac2004 20 Nov 2006, 05:00
Oh, I see there's the catch.

Thanx for the enlightement!

regards,
Mac2004
Post 20 Nov 2006, 05:00
View user's profile Send private message Reply with quote
Mac2004



Joined: 15 Dec 2003
Posts: 314
Mac2004 26 Nov 2006, 20:56
Hi Tomasz!

I think you should add these long mode examples to the examples section. Very fine examples indeed. I got them working now. It's not a trivial task to write protected mode or long mode setup code from scratch. One easily ends up with tripple faulting code.

regards Mac2004
Post 26 Nov 2006, 20:56
View user's profile Send private message Reply with quote
Adam Kachwalla



Joined: 01 Apr 2006
Posts: 150
Adam Kachwalla 26 Jun 2007, 09:06
Why have you MOVed the same data twice (when nothing is being done to it after):

Code:
mov     al,10001b               ; begin PIC 1 initialization
out     20h,al
mov     al,10001b               ; begin PIC 2 initialization
out     0A0h,al    


Here, you are moving 10001b into AL after the OUT 20h,AL instruction, even though nothing is being done to modify AL. Why is this?
Post 26 Jun 2007, 09:06
View user's profile Send private message Reply with quote
Mac2004



Joined: 15 Dec 2003
Posts: 314
Mac2004 26 Jun 2007, 18:09
Adam Kachwalla: There are 2 PIC's (ports 20h and 0a0h) needed to be initialized. It's not enough to initialize 1st PIC only and then use interrupts under 2nd PIC.

regards,
Mac2004
Post 26 Jun 2007, 18:09
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 26 Jun 2007, 18:38
I think he means the redundant "mov al,10001b" below "out 20h,al".
Post 26 Jun 2007, 18:38
View user's profile Send private message Reply with quote
Adam Kachwalla



Joined: 01 Apr 2006
Posts: 150
Adam Kachwalla 26 Jun 2007, 20:46
Quote:
Adam Kachwalla: There are 2 PIC's (ports 20h and 0a0h) needed to be initialized. It's not enough to initialize 1st PIC only and then use interrupts under 2nd PIC.

regards,
Mac2004


I was not saying anything about the PICs.

Quote:
I think he means the redundant "mov al,10001b" below "out 20h,al".


That is exactly what I mean. Why not clean up the code like this:

Code:
MOV     AL,10001b
OUT     0x20,AL
OUT     0x0A0,AL    
Post 26 Jun 2007, 20:46
View user's profile Send private message Reply with quote
Mac2004



Joined: 15 Dec 2003
Posts: 314
Mac2004 27 Jun 2007, 07:15
Adam Kachwalla: You're right! I can see your point. Smile
Post 27 Jun 2007, 07:15
View user's profile Send private message Reply with quote
Adam Kachwalla



Joined: 01 Apr 2006
Posts: 150
Adam Kachwalla 27 Jun 2007, 08:40
BTW, I'm not the most experienced person in the world when it comes to 64-bit systems: Does this snippet print out the text "L O N G "?

Code:
MOV     RAX,'L O N G '
MOV     [0x0B8000],RAX
    


If so, if I wanted to print the word "Pneumonoultramicroscopicsilicovolcanoconiosis", will this work?

[code]MOV RAX,"Pneumono"
MOV [0x0B8000],RAX
MOV RAX,"ultramic"
MOV [0x0B8000],RAX
MOV RAX,"roscopic"
MOV [0x0B8000],RAX
MOV RAX,"silicovo"
MOV [0x0B8000],RAX
MOV RAX,"lcanocon"
MOV [0x0B8000],RAX
MOV RAX,"iosis "
MOV [0x0B8000],RAX[/code
Post 27 Jun 2007, 08:40
View user's profile Send private message Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u 27 Jun 2007, 09:31
No, as first you can see theres space in the "L O N G ", these are for text/bg color, also you are adding them to the same address.
Post 27 Jun 2007, 09:31
View user's profile Send private message Reply with quote
Adam Kachwalla



Joined: 01 Apr 2006
Posts: 150
Adam Kachwalla 27 Jun 2007, 21:38
Code:
MOV RAX,"P n e u "
MOV [0x0B8000],RAX
MOV RAX,"m o n o "
MOV [0x0B8008],RAX
MOV RAX,"u l t r "
MOV [0x0B8010]
MOV RAX,"a m i c "
MOV [0x0B8018],RAX
MOV RAX,"r o s c "
MOV [0x0B8020],RAX
MOV RAX,"o p i c "
MOV [0x0B8010],RAX
MOV RAX,"s i l i "
MOV [0x0B8018],RAX
MOV RAX,"c o v o "
MOV [0x0B8020],RAX
MOV RAX,"l c a n "
MOV [0x0B8028],RAX
MOV RAX,"o c o n "
MOV [0x0B8030],RAX
MOV RAX,"i o s i "
MOV [0x0B8038],RAX
MOV RAX,"s "
MOV [0x0B8040],RAX    


Crikey! Writing one word takes up 24 lines of code... Imagine writing a Sentence, Paragraph, Essay or Thesis!
Post 27 Jun 2007, 21:38
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 27 Jun 2007, 21:49
still not. only every second byte is letter. Every other byte is character color (lower 4 bits) and background color (upper 4 bits)

EDIT: sorry, you responded before i posted. Your last example is okay, but you should undestand color of text will be 20h (which is space character)
Post 27 Jun 2007, 21:49
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Octavio



Joined: 21 Jun 2003
Posts: 366
Location: Spain
Octavio 27 Jun 2007, 22:44
Adam Kachwalla wrote:

Crikey! Writing one word takes up 24 lines of code... Imagine writing a Sentence, Paragraph, Essay or Thesis!

Yes, thats why some programs have millions of lines of code Smile)
Post 27 Jun 2007, 22:44
View user's profile Send private message Visit poster's website Reply with quote
Adam Kachwalla



Joined: 01 Apr 2006
Posts: 150
Adam Kachwalla 28 Jun 2007, 06:06
Hang on a sec... Where's the instruction that actually prints the text? I cannot get it to work under QEMU. It hangs where it is (nothing is printed).
Post 28 Jun 2007, 06:06
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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.