flat assembler
Message board for the users of flat assembler.

flat assembler > OS Construction > Entering long mode - simple examples

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


Joined: 16 Jun 2003
Posts: 6865
Location: Kraków, Poland
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: 222 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
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: 617
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: 313
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
Assembly Artist


Joined: 16 Jun 2003
Posts: 6865
Location: Kraków, Poland
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: 313
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
Assembly Artist


Joined: 16 Jun 2003
Posts: 6865
Location: Kraków, Poland
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: 313
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: 313
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
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: 313
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: 4634
Location: Argentina
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
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: 313
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
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
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
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: 7109
Location: Slovakia
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
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
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 © 2004-2018, Tomasz Grysztar.

Powered by rwasa.