flat assembler
Message board for the users of flat assembler.
Index
> OS Construction > Directly from realmode to longmode Goto page Previous 1, 2 |
Author |
|
revolution 05 Jun 2008, 13:49
Do you mean 16bit RM mode? I think the normal BIOS is expecting RM mode. This would mean that you have no control over the interrupt flag once you relinquish execution to an RM task. The RM task may enable interrupts, or change some hardware configuration that requires you to remap all your virtual pages on the PM side. It could be very tricky. One way around it is to go to 32bit PM mode and run a v8086 task inside that to catch any unwanted activity with the interrupt flag and things. That could also be tricky.
|
|||
05 Jun 2008, 13:49 |
|
f0dder 05 Jun 2008, 14:41
revolution: I think sinsi is talking about the VESA "protected mode interface", which is 16bit PM code that you call by copying the code and calling it's entry-point, not by issuing an INT.
Personally, I'd probably go the emulation way and emulate the 16bit rm INTs, it's a decent amount of work, but it feels "safer". It's what 64bit windows does, as vid found out. |
|||
05 Jun 2008, 14:41 |
|
revolution 05 Jun 2008, 15:10
f0dder wrote: revolution: I think sinsi is talking about the VESA "protected mode interface", which is 16bit PM code that you call by copying the code and calling it's entry-point, not by issuing an INT. f0dder wrote: Personally, I'd probably go the emulation way and emulate the 16bit rm INTs, it's a decent amount of work, but it feels "safer". It's what 64bit windows does, as vid found out. |
|||
05 Jun 2008, 15:10 |
|
sinsi 06 Jun 2008, 07:23
f0dder wrote: It's what 64bit windows does, as vid found out. Can you give me a link to that? I just cannot search this forum with *any* degree of success... |
|||
06 Jun 2008, 07:23 |
|
MazeGen 06 Jun 2008, 09:47
|
|||
06 Jun 2008, 09:47 |
|
sinsi 06 Jun 2008, 09:55
Cheers mate!
|
|||
06 Jun 2008, 09:55 |
|
neville 19 Jul 2008, 05:12
sinsi wrote: I'm just starting to play with 64-bit and long mode and was wondering if there's any problem with going straight to long mode without the protected mode part. The code in the attachment works in qemu and a real computer booting from a floppy. Um, sorry, but how do you see attachments??? _________________ FAMOS - the first memory operating system |
|||
19 Jul 2008, 05:12 |
|
neville 19 Jul 2008, 05:17
Hey, thats weird....
After I wrote that last post, I refreshed the page and then there was a paperclip next to sinsi's first post, and sure enough - an attachment! I swear it wasn't there before ..... honest! I wonder why??? |
|||
19 Jul 2008, 05:17 |
|
LocoDelAssembly 19 Jul 2008, 05:38
Perhaps you wasn't logged in when you saw the first page of this thread?
|
|||
19 Jul 2008, 05:38 |
|
neville 20 Jul 2008, 00:14
LocoDelAssembly wrote: Perhaps you wasn't logged in when you saw the first page of this thread? I've only been on this board a week so I guess I'm still getting used to it. The other weird thing is I had logged on, but by the time I went to post a message it said I was logged off again... Anyway thanks _________________ FAMOS - the first memory operating system |
|||
20 Jul 2008, 00:14 |
|
neville 20 Jul 2008, 00:19
I noticed sinsi uses org 7C00h in the bootloader.
Beware that not all BIOS's do a Far jmp to 0000:7C00h (setting CS=0, IP=7C00h) when they pass control to the bootloader. Early in my FAMOS development days (5 years ago now!) I discovered some BIOS's do a Far jmp to 07C0h:0000 which of course is still the same linear address 00007C00h. But if the code offsets aren't what the cpu expects unexpected things can happen (e.g. all embedded data references such as text strings won't be found and won't be displayed correctly. So its a good idea to force CS:IP to be what you want it to be as soon as possible in the bootloader, using your own Far jmp. Because a Far jmp is 5 bytes, the first instruction could be: jmp 0000:7C05h ;which jmps straight to the next address at 00007C05h and enforces CS=0 If CS=7C0h and IP=0 on entry from the BIOS this will fix it. In FAMOS I often use org 0100h because there are many DOS utilities I can use to pre-test my code as a flat binary COM file before migrating it to FAMOS. So my first bootloader instruction would be: jmp 07B0h:0105h ;which still gets to linear address 00007C05h Actually I have a boot header as well so the first instructions are the standard 2-byte Near jmp + nop. The Near jmp jumps over the 59-byte header (at offset +003Eh) so my code is: org 0100h jmp start nop header: spt dw 0200h etc. (59 bytes) start: jmp 07B0h:0143h ;offset 13Eh here next: ... ;offset 143h here Hope this might help somebody _________________ FAMOS - the first memory operating system |
|||
20 Jul 2008, 00:19 |
|
neville 16 Nov 2008, 04:06
I now have a machine with an Athlon64 X2 CPU so I have been playing...
I can get to Long Mode using variations of sinsi's code at the start of this thread, but only by writing it to the bootsector of a floppy disk and then booting it. The SAME code written to a bootable physical CD using floppy emulation does NOT work - it causes the machine to endlessly reboot itself. The same code executed from 7B0H:0100H in FAMOS also reboots the machine. In FAMOS the page tables are all built successfully, PAE is enabled OK, Long Mode is enabled, but the reboot occurs when the instruction MOV CRO,EAX is executed when attempting to enable paging... Code: MOV EAX,CR4 OR EAX,20H MOV CR4,EAX ;enable PAE MOV EAX,PGTABLE MOV CR3,EAX MOV ECX,0C0000080H ;EFER.MSR RDMSR OR EAX,100H WRMSR ;enable long mode MOV EAX,CR0 OR EAX,80000001H MOV CR0,EAX ;enable paging CRASHES here WTF??? Can anybody help? _________________ FAMOS - the first memory operating system |
|||
16 Nov 2008, 04:06 |
|
sinsi 16 Nov 2008, 04:34
How do you know it crashes on that instruction? via bochs debugger?
That instruction triple faults if a butterfly farts I swear... |
|||
16 Nov 2008, 04:34 |
|
neville 16 Nov 2008, 05:54
sinsi wrote: How do you know it crashes on that instruction? via bochs debugger? No, via my own native FAMOS debugger. I've never used an emulator - I figure its best to use the real thing... Its definitely that instruction that crashes. _________________ FAMOS - the first memory operating system |
|||
16 Nov 2008, 05:54 |
|
sinsi 16 Nov 2008, 06:25
I've noticed that with nero you can specify a load segment for a bootable cd and it seems to default to 0x1000 (apparently with el-torito you can load your code at any segment)...
Can you post some code? |
|||
16 Nov 2008, 06:25 |
|
neville 16 Nov 2008, 20:59
I thought I would start my FAMOS 64-bit experiments with a program which:
(a) sets up Long Mode and displays my name on a text screen (b) waits for an interrupt from the keyboard (c) returns to FAMOS (if possible!) sinsi, because FAMOS runs in real mode (albeit Flat Real), the code you posted in this thread seemed like an ideal starting point... It will be great if I can do this, because then I can do 64-bit stuff on an "as required" basis before implementing a geniune 64-bit OS... My program "GO64" in FAMOS should just enter Long Mode, and display "Neville" on the screen in pretty colours. I realise returning to flat real FAMOS again could be difficult without rebooting, but its frustrating that I can't even get to Long Mode in the first place... The 512-byte bootsector version of the original code displays "Neville" just fine when booted from a floppy, but not from a CD. Here's the "GO64" code. It relocates itself to 0:7C00H before execution because I thought that might help it to work, but now I don't think that is the problem: Code: ;trial 64bit UNP for FAMOS (NB: no FPCA yet!) ORG 0100h MOV SI,300H MOV EDI,7C00H MOV CX,1FEH ;254 bytes of code max! FILL: MOV AL,[CS:SI] MOV [EDI],AL INC SI INC EDI LOOP FILL TIMES 200 DB 90H JMP 07B0H:0100H TIMES 284 DB 0 ;padding to offset 300H ;this MUST be offset 300H... NOP cli ; sub ax,ax ; mov ss,ax ; mov sp,7c00h ;FAMOS UNP stack at 9000H:FFFEH MOV AX,3 INT 10H ;set text video mode mov ax,7000h ;70000h ok for pagetables mov es,ax sub di,di mov cx,4096 sub eax,eax rep stosd mov dword [es:0000h],71000h + 111b ; first PDP table mov dword [es:1000h],72000h + 111b ; first page directory mov dword [es:2000h],73000h + 111b ; first page table mov di,3000h ; address of first page table mov eax,0 + 111b mov cx,256 ; number of pages to map (1 MB) .next: stosd add di,4 add eax,1000h loop .next ; create page table @ 73000 - mov eax,cr4 or eax,1 shl 5 mov cr4,eax ; enable physical-address extensions mov eax,70000h mov cr3,eax ; load page-map level-4 base mov ecx,0C0000080h ; EFER MSR nop rdmsr nop or eax,1 shl 8 ; enable long mode wrmsr mov eax,cr0 TIMES 4 DB 90H ; MOV [CR0COPY],EAX ;can we access linear mem here?? NOP or eax,(1 shl 31) + 1 mov cr0,eax ; enable paging + pmode ; reboots here.... NOP ; lgdt [cs:GDTR] - 200H ;HAND-CODE THIS... ; lgdt [cs:GDTR] ;HAND-CODE THIS... GDTR=398 -> 198h ; db 2eh, 0fh, 1, 16h, 98h, 1 lgdt [cs:198H] ;assembles correctly with ABSOLUTE ptr NOP jmp 8:long_start - 200H align 8 GDTR: ; Global Descriptors Table Register dw 2*8-1 ; limit of GDT (size minus one) dq GDT - 200H ; linear address of GDT align 8 GDT rw 4 ; null desciptor dw 0FFFFh,0,9A00h,0AFh ; 64-bit code desciptor USE64 long_start: NOP mov al,10001b ; begin PIC 1 initialization out 20h,al mov al,10001b ; begin PIC 2 initialization out 0A0h,al mov al,80h ; IRQ 0-7: interrupts 80h-87h out 21h,al mov al,88h ; IRQ 8-15: interrupts 88h-8Fh out 0A1h,al mov al,100b ; slave connected to IRQ2 out 21h,al mov al,2 out 0A1h,al mov al,1 ; Intel environment, manual EOI out 21h,al out 0A1h,al in al,21h mov al,11111100b ; enable only clock and keyboard IRQ out 21h,al in al,0A1h mov al,11111111b out 0A1h,al xor edi,edi ; create IDT (at linear address 0) mov ecx,21 make_exception_gates: ; make gates for exception handlers mov esi,exception_gate - 200H movsq movsq loop make_exception_gates mov ecx,256-21 make_interrupt_gates: ; make gates for the other interrupts mov esi,interrupt_gate - 200H movsq movsq loop make_interrupt_gates NOP mov word [80h*16],clock - 200H ; set IRQ 0 handler mov word [81h*16],keyboard - 200H ; set IRQ 1 handler NOP ; lidt [IDTR] - 200H ; load IDT register ; lidt [IDTR] ;HAND-CODE THIS... ; lidt [23FH] ;HAND-CODE THIS... 43F -> 23FH NO! lidt [43FH] ;assembles using RELATIVE ptr so dont - 200 !! NOP sti ; now we may enable the interrupts main_loop: mov rax,03760265014E0720h ;'_Nev' mov [0B8000h],rax mov rax,0765066C056C0469h ;'ille' mov [0B8008h],rax NOP jmp $ IDTR: ; Interrupt Descriptor Table Register dw 256*16-1 ; limit of IDT (size minus one) dq 0 ; linear address of IDT exception_gate: dw exception and 0FFFFh,8 dw 8E00h,exception shr 16 - 20H ;200/16 dd 0,0 interrupt_gate: dw interrupt and 0FFFFh,8 dw 8F00h,interrupt shr 16 - 20H ;200/16 dd 0,0 exception: ; exception handler in al,61h ; turn on the speaker or al,3 out 61h,al jmp exception ; repeat it until reboot interrupt: ; handler for all other interrupts iretq clock: inc byte [0B8000h+2*80] ; make the ticks appear push rax mov al,20h out 20h,al pop rax iretq keyboard: push rax in al,60h cmp al,1 ; check for Esc key je reboot mov [0B8000h+2*(80+1)],al ; show the scan key in al,61h ; give finishing information out 61h,al ; to keyboard... mov al,20h out 20h,al ; ...and interrupt controller pop rax iretq reboot: ;attempt to return to FAMOS... USE16 MOV EAX,CR0 NOP AND EAX,7FFFFFFFH ;reset PG MOV CR0,EAX ;disable paging MOV ECX,0C0000080H ;EFER.LME NOP RDMSR BTR EAX,8 NOP WRMSR ;disable long mode MOV EAX,CR0 AND EAX,0FFFFFFFEH ;reset PE NOP MOV CR0,EAX ;disable PM NOP DB 0EAH, 0, 1, 0D0H, 7 ;return to FAMOS? Don't assume ints are working! CR0COPY: DD 0 _________________ FAMOS - the first memory operating system |
|||
16 Nov 2008, 20:59 |
|
neville 19 Nov 2008, 22:38
I found a few bugs in the previous code, including an incorrect GDT pointer
after relocating the code to 00007C00H. I've now abandoned the idea of relocating the code because it shouldn't be necessary anyway... I fixed the bugs I found but the MOV CR0,EAX instruction still reboots. Grrr... Latest version of the code: Code: ;trial 64bit UNP for FAMOS ORG 0100h NOP cli ; sub ax,ax ; mov ss,ax ; mov sp,7c00h ;FAMOS stack at 9000:FFFEH MOV AX,3 INT 10H ;set text video mode cli ;save IVT here & restore before attempting return to FAMOS?? mov ax,7000h ;70000h ok mov es,ax sub di,di mov cx,4096 sub eax,eax rep stosd mov dword [es:0000h],71000h + 111b ; first PDP table mov dword [es:1000h],72000h + 111b ; first page directory mov dword [es:2000h],73000h + 111b ; first page table mov di,3000h ; address of first page table mov eax,0 + 111b mov cx,256 ; number of pages to map (1 MB) .next: stosd add di,4 add eax,1000h loop .next ; create page table @ 73000 - MOV EAX,GDT ADD EAX,1FF00H ;CS=1FF0H MOV [CS:LINADDR],EAX mov eax,cr4 or eax,1 shl 5 mov cr4,eax ; enable physical-address extensions mov eax,70000h mov cr3,eax ; load page-map level-4 base mov ecx,0C0000080h ; EFER MSR nop rdmsr nop or eax,1 shl 8 ; enable long mode wrmsr ; lgdt [cs:GDTR] ; LGDT first?? (still reboots...) TIMES 6 DB 90H NOP mov eax,cr0 NOP or eax,(1 shl 31) + 1 mov cr0,eax ; enable paging + pmode ; still reboots here.... NOP lgdt [CS:GDTR] NOP jmp 8:long_start align 8 GDTR: ; Global Descriptors Table Register dw 2*8-1 ; limit of GDT (size minus one) LINADDR: ; lin addr of GDT dq 0 align 8 GDT rw 4 ; null desciptor dw 0FFFFh,0,9A00h,0AFh ; 64-bit code desciptor USE64 long_start: NOP MOV AX,CS MOV DS,AX mov al,10001b ; begin PIC 1 initialization out 20h,al mov al,10001b ; begin PIC 2 initialization out 0A0h,al mov al,80h ; IRQ 0-7: interrupts 80h-87h out 21h,al mov al,88h ; IRQ 8-15: interrupts 88h-8Fh out 0A1h,al mov al,100b ; slave connected to IRQ2 out 21h,al mov al,2 out 0A1h,al mov al,1 ; Intel environment, manual EOI out 21h,al out 0A1h,al in al,21h mov al,11111100b ; enable only clock and keyboard IRQ out 21h,al in al,0A1h mov al,11111111b out 0A1h,al xor edi,edi ; create IDT (at linear address 0) mov ecx,21 make_exception_gates: ; make gates for exception handlers mov esi,exception_gate movsq movsq loop make_exception_gates mov ecx,256-21 make_interrupt_gates: ; make gates for the other interrupts mov esi,interrupt_gate movsq movsq loop make_interrupt_gates NOP mov word [80h*16],clock mov word [81h*16],keyboard NOP lidt [IDTR] NOP sti ; now we may enable the interrupts main_loop: mov rax,03760265014E0720h ;'_Nev' mov [0B8000h],rax mov rax,0765066C056C0469h ;'ille' mov [0B8008h],rax NOP jmp $ IDTR: ; Interrupt Descriptor Table Register dw 256*16-1 ; limit of IDT (size minus one) dq 0 ; linear address of IDT exception_gate: dw exception and 0FFFFh,8 dw 8E00h,exception shr 16 dd 0,0 interrupt_gate: dw interrupt and 0FFFFh,8 dw 8F00h,interrupt shr 16 dd 0,0 exception: ; exception handler in al,61h ; turn on the speaker or al,3 out 61h,al jmp exception ; repeat it until reboot interrupt: ; handler for all other interrupts iretq clock: inc byte [0B8000h+2*80] ; make the ticks appear push rax mov al,20h out 20h,al pop rax iretq keyboard: push rax in al,60h cmp al,1 ; check for Esc key je GO2FAMOS mov [0B8000h+2*(80+1)],al ; show the scan key in al,61h ; give finishing information out 61h,al ; to keyboard... mov al,20h out 20h,al ; ...and interrupt controller pop rax iretq GO2FAMOS: ;attempt to return to FAMOS... USE16 MOV EAX,CR0 NOP AND EAX,7FFFFFFFH ;reset PG MOV CR0,EAX ;disable paging MOV ECX,0C0000080H ;EFER.LME NOP RDMSR BTR EAX,8 NOP WRMSR ;disable long mode MOV EAX,CR0 AND EAX,0FFFFFFFEH ;reset PE NOP MOV CR0,EAX ;disable PM NOP DB 0EAH, 0, 1, 0D0H, 7 ;don't assume ints are working! _________________ FAMOS - the first memory operating system |
|||
19 Nov 2008, 22:38 |
|
neville 04 Dec 2008, 08:48
The problem I've been having with activating Long Mode (crashing on the MOV CR0,EAX instruction below) only occurs when the real mode code segment is non-zero at the time the instruction is executed. If CS=0, it works fine.
Can anybody explain why this should be? Code: MOV EAX,CR0 OR EAX,80000001H ;enable paging & pmode MOV CR0,EAX ;activate Long Mode (crashes if CS ne 0) JMP 0008:LONG_MODE ;works only if Real-Mode CS was 0 ... _________________ FAMOS - the first memory operating system |
|||
04 Dec 2008, 08:48 |
|
StarKnightD 11 Feb 2009, 16:27
Quote: The problem I've been having with activating Long Mode (crashing on the MOV CR0,EAX instruction below) only occurs when the real mode code segment is non-zero at the time the instruction is executed. If CS=0, it works fine. it's because CS doesn't represent an address when running in protected mode (both 32 and 64 bit forms) -- which is what it does in real mode -- rather it's symbolic of the current state of the code-segment. if memory serves me right, there are only 3 states the CS can be in, each of which are represented by the first 3 powers of 2. |
|||
11 Feb 2009, 16:27 |
|
Goto page Previous 1, 2 < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.