"Tim Robinson trick" in Bochs?

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
carbonBased
Member
Member
Posts: 382
Joined: Sat Nov 20, 2004 12:00 am
Location: Wellesley, Ontario, Canada
Contact:

"Tim Robinson trick" in Bochs?

Post by carbonBased »

I've always called in "The Tim Robinson trick," as that's who I learned it from, but I'm sure others have independently used this trick of segment overflow to achieve, what-looks-to-be, a relocated kernel.

In other words, setting your code selector base to 0x4010000, for example, so that accessing code as 3GB (0xc0000000) will actually access code at 1MB (0x00100000).

This trick is fairly straightforward, but I've noticed it doesn't work in bochs. It works just fine in qemu, however.

This bothers me, as I've always thought that this was a solid mechanism, and that it should work on all systems. Is this not the case? Is anybody else using this mechanism?

Lastly, what of these new 64-bit machines? I assume I should still be able to safely assume a 32-bit overflow will occur when these chips are not configured for long mode?

Any information on this would be greatly appreciated.

Thanks,
Jeff
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: "Tim Robinson trick" in Bochs?

Post by Candy »

carbonBased wrote:I've always called in "The Tim Robinson trick," as that's who I learned it from, but I'm sure others have independently used this trick of segment overflow to achieve, what-looks-to-be, a relocated kernel.

In other words, setting your code selector base to 0x4010000, for example, so that accessing code as 3GB (0xc0000000) will actually access code at 1MB (0x00100000).

This trick is fairly straightforward, but I've noticed it doesn't work in bochs. It works just fine in qemu, however.

This bothers me, as I've always thought that this was a solid mechanism, and that it should work on all systems. Is this not the case? Is anybody else using this mechanism?

Lastly, what of these new 64-bit machines? I assume I should still be able to safely assume a 32-bit overflow will occur when these chips are not configured for long mode?

You're off by a 0.

Should work on new machines too, I expect, but on the other hand, I dislike the conceptual abuse.
User avatar
ces_mohab
Member
Member
Posts: 77
Joined: Wed Oct 18, 2006 3:08 am

Re: "Tim Robinson trick" in Bochs?

Post by ces_mohab »

carbonBased wrote: In other words, setting your code selector base to 0x4010000, for example, so that accessing code as 3GB (0xc0000000) will actually access code at 1MB (0x00100000).
Personally i use a small stub at the very beginning of the kernel that enables paging and maps some temporary pages then the first thing the kernel does is to make proper mapping and memory manager initialization.

the stub must be carefully written. setup temp stack...
To write an OS you need 2 minds one for coding and other for debugging.
User avatar
carbonBased
Member
Member
Posts: 382
Joined: Sat Nov 20, 2004 12:00 am
Location: Wellesley, Ontario, Canada
Contact:

Re: "Tim Robinson trick" in Bochs?

Post by carbonBased »

ces_mohab wrote: Personally i use a small stub at the very beginning of the kernel that enables paging and maps some temporary pages then the first thing the kernel does is to make proper mapping and memory manager initialization.
I may end up going this route, myself. I'm currently using the overflow trick until the kernel pager is initialized and everything is sorted out in a more ideal manor.

Unfortunately, I'm running into issues at this point, and sense bochs doesn't seem to support the overflow trick, I can't use it for debugging! For purposes of my sanity, I think I may write a minimal pager into my startup assemble.
candy wrote: but on the other hand, I dislike the conceptual abuse.
Yes, I'm beginning to myself, as well. I'm attempting to make the location of my kernel configurable at build time, and the overflow trick fit in nicely with this, but I don't think I want to eliminate bochs support, as its a useful debugger.

--Jeff
User avatar
salil_bhagurkar
Member
Member
Posts: 261
Joined: Mon Feb 19, 2007 10:40 am
Location: India

Post by salil_bhagurkar »

What is this overflow trick and whats the purpose?
User avatar
carbonBased
Member
Member
Posts: 382
Joined: Sat Nov 20, 2004 12:00 am
Location: Wellesley, Ontario, Canada
Contact:

Post by carbonBased »

It relies on a 32-bit overflow of a GDT selector base and an offset to produce code/data that "thinks" it's at one location, when it's really at another, without using the pager.

See the Tim Robinson link in this wiki page:
http://www.osdev.org/wiki/Higher_Half_Kernel

--Jeff
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Hmm strange. A test setup (written from scratch) works properly :?
What version of bochs are you using? (i have 2.2.6 and 2.3, both work correctly)

As for 64 bit cpu's, I doubt they want to break the existing architecture (i should test this again with my amd64).

Anyway, my setup for reference:

Code: Select all

; we are loaded at 0x7c00
; relocate to higherhalf and
; use GDT to map 0xC0000000 -> 0x0
ORG 0xC0007C00

BITS 16

; some position independent code to avoid multiple ORGs
; (as that doesnt work in NASM, not tested with YASM)
start:          CLI             ; disable ints to not break protected mode code

                XOR AX, AX
                MOV DS, AX
                MOV ES, AX      ; load segments to 0x0
                LGDT [0x7C00 + 0x40 - 6]   ; load gdtr
                MOV EAX, CR0
                OR AL, 1
                MOV CR0, EAX    ; enter protected mode

                JMP dword 0x10:pm_entry

times 0x40-6 - ($-$$) DB 0
gdtr:           DW 4 * 8 - 1
                DD 0x7c00 + 0x40

gdt:
gdtNULLSel  EQU $-gdt
            DD 0
            DD 0
gdtKData:
gdtKDataSel EQU $-gdt
            DW 0xFFFF               ; limit is 0xFFFFF, lower 16 bits
            DW 0
            DB 0
            DB 0x92
            DB 0xCF                 ; limit is 0xFFFFF, top 4 bits
            DB 0x40                 ; base is 0x40000000; 0x400..+0xC00.. = 0x100000000 (where the 1 ends up ignored)
gdtKCode:
gdtKCodeSel EQU $-gdt
            DW 0xFFFF               ; limit is 0xFFFFF, lower 16 bits
            DW 0
            DB 0
            DB 0x9a
            DB 0xCF                 ; limit is 0xFFFFF, top 4 bits
            DB 0x40                 ; base is 0x40000000

gdtKFlat:   EQU $-gdt
            DW 0xFFFF               ; limit is 0xFFFFF, lower 16 bits
            DW 0
            DB 0
            DB 0x92
            DB 0xCF                 ; limit is 0xFFFFF, top 4 bits
            DB 0x00                 ; base is 0, for writing to video memory

BITS 32

pm_entry:   MOV AX, 0x8
            MOV DS, AX
            MOV ES, AX

            MOV AX, 0x18
            MOV FS, AX
            MOV GS, AX

            MOV EDI, 0xB8000        ; target is video memory
            MOV ESI, string         ; source is a string somewhere in 0xC0007Cxx

looppoint:
            MOV AX, [ESI]           ; load from DS using overflow
            OR AX, AX               ; test for null terminator
            JZ done
            MOV [FS:EDI], AX        ; write to FS which is flat selector
            ADD ESI, 2
            ADD EDI, 2
            JMP looppoint           ; increment pointers and loop

            ; lock up
done:       HLT

            ; On bochs you should get 'All ok' in the top-left
string:     DB 'A', 7, 'l', 7, 'l', 7, ' ', 7, 'o', 7, 'k', 7, 0, 0

; boot signature
times 510-($-$$) DB 0
DB 0x55, 0xAA
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
stlw
Member
Member
Posts: 357
Joined: Fri Apr 04, 2008 6:43 am
Contact:

Re: "Tim Robinson trick" in Bochs?

Post by stlw »

carbonBased wrote:I've always called in "The Tim Robinson trick," as that's who I learned it from, but I'm sure others have independently used this trick of segment overflow to achieve, what-looks-to-be, a relocated kernel.

In other words, setting your code selector base to 0x4010000, for example, so that accessing code as 3GB (0xc0000000) will actually access code at 1MB (0x00100000).

This trick is fairly straightforward, but I've noticed it doesn't work in bochs. It works just fine in qemu, however.

This bothers me, as I've always thought that this was a solid mechanism, and that it should work on all systems. Is this not the case? Is anybody else using this mechanism?

Lastly, what of these new 64-bit machines? I assume I should still be able to safely assume a 32-bit overflow will occur when these chips are not configured for long mode?

Any information on this would be greatly appreciated.

Thanks,
Jeff

Bochs compiled with 64-bit emulaton support was not working correctly and not implemeted linear address truncation to 32-bit in legacy (non long64) mode.

In Bochs compiled without 64-bit the linear address stored in 32-bit variable so the truncation happens naturally.

I fixed it (hopefully) in todays Bochs's CVS and will be appreciated if you could run your test and see if it works as expected. Hopefully you are still have the code to do that.

Thanks,
Stanislav
Post Reply