flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > Entering long mode - simple examples Goto page 1, 2 Next |
Author |
|
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.
|
|||||||||||
18 Nov 2006, 16:16 |
|
cod3b453 19 Nov 2006, 02:58
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 |
|||
19 Nov 2006, 02:58 |
|
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 |
|||
19 Nov 2006, 20:55 |
|
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. |
|||
19 Nov 2006, 21:00 |
|
Mac2004 19 Nov 2006, 21:05
Should ms-dos load com programs always to 100h?
regards, Mac2004 |
|||
19 Nov 2006, 21:05 |
|
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. |
|||
19 Nov 2006, 21:14 |
|
Mac2004 20 Nov 2006, 05:00
Oh, I see there's the catch.
Thanx for the enlightement! regards, Mac2004 |
|||
20 Nov 2006, 05:00 |
|
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 |
|||
26 Nov 2006, 20:56 |
|
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? |
|||
26 Jun 2007, 09:06 |
|
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 |
|||
26 Jun 2007, 18:09 |
|
LocoDelAssembly 26 Jun 2007, 18:38
I think he means the redundant "mov al,10001b" below "out 20h,al".
|
|||
26 Jun 2007, 18:38 |
|
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. 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 |
|||
26 Jun 2007, 20:46 |
|
Mac2004 27 Jun 2007, 07:15
Adam Kachwalla: You're right! I can see your point.
|
|||
27 Jun 2007, 07:15 |
|
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 |
|||
27 Jun 2007, 08:40 |
|
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.
|
|||
27 Jun 2007, 09:31 |
|
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! |
|||
27 Jun 2007, 21:38 |
|
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) |
|||
27 Jun 2007, 21:49 |
|
Octavio 27 Jun 2007, 22:44
Adam Kachwalla wrote:
Yes, thats why some programs have millions of lines of code ) |
|||
27 Jun 2007, 22:44 |
|
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).
|
|||
28 Jun 2007, 06:06 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.