Mixing 32bit and 16bit code (comming down into real mode)

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.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

AJ wrote:Why stop there? What about encoding on quarks and leptons? :twisted:
Heisenberg? :twisted:
Every good solution is obvious once you've found it.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Damn #-o
User avatar
Stevo14
Member
Member
Posts: 179
Joined: Fri Mar 07, 2008 3:40 am
Location: Arad, Romania

Post by Stevo14 »

Well, it works now, sort of... :? I followed everyones advice (including reading the relevant sections of the Intel manuals and setting up a stack) and I am proud to say that I can now successfully enter real mode (yay!). The problem now is that interrupts don't work, despite loading the real mode IVT using:

Code: Select all

lidt [0x0000]
sti
Again, I'm probably missing something very fundamental.
AJ wrote: Why stop there? What about encoding on quarks and leptons? :twisted:
Or maybe even on the quarks and leptons of super-cooled, ultra-dense, hydrogen atoms? Takes up less space than carbon and has more adjectives. :wink:
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

Try this:

idt_real:
dw 0x3ff
dd 0x0000



Then lidt [idt_real]. You still have to load the IDTR with valid values.
Last edited by Ready4Dis on Fri Apr 18, 2008 5:36 pm, edited 1 time in total.
octavio
Member
Member
Posts: 94
Joined: Wed Oct 25, 2006 5:12 am
Location: Barcelona España
Contact:

Post by octavio »

Stevo14 wrote:Well, it works now, sort of... :? I followed everyones advice (including reading the relevant sections of the Intel manuals and setting up a stack) and I am proud to say that I can now successfully enter real mode (yay!). The problem now is that interrupts don't work, despite loading the real mode IVT using:

Code: Select all

lidt [0x0000]
sti
Again, I'm probably missing something very fundamental.
AJ wrote: Why stop there? What about encoding on quarks and leptons? :twisted:
Or maybe even on the quarks and leptons of super-cooled, ultra-dense, hydrogen atoms? Takes up less space than carbon and has more adjectives. :wink:
Read again the intel manuals especially the part where it explains what is
the idt (Interrupt Descriptor Table) and how to use 'lidt' wich your assembler because there are 16 and 32 bits versions.
User avatar
zaleschiemilgabriel
Member
Member
Posts: 232
Joined: Mon Feb 04, 2008 3:58 am

Post by zaleschiemilgabriel »

What do leptons and quarks have to do with switching to real mode?Image
User avatar
Brynet-Inc
Member
Member
Posts: 2426
Joined: Tue Oct 17, 2006 9:29 pm
Libera.chat IRC: brynet
Location: Canada
Contact:

Post by Brynet-Inc »

zaleschiemilgabriel wrote:What do leptons and quarks have to do with switching to real mode?Image
Slightly off topic, but did Yahoo give you permission to hot link their emoticons? I believe they're copyrighted... :roll:

http://yhoo.client.shareholder.com/press/permission.cfm

You should be careful.. ;)
Image
Twitter: @canadianbryan. Award by smcerm, I stole it. Original was larger.
User avatar
zaleschiemilgabriel
Member
Member
Posts: 232
Joined: Mon Feb 04, 2008 3:58 am

Post by zaleschiemilgabriel »

Whoops. I never thought of that. I assume I'm using them personally, not commercially, since I'm not trying to sell anything here. I also assume that if they wanted to, they could've disallowed hot-linking by HTTP routing. And thirdly, I assume that if those emoticons are there for everyone to see, they are also there for everyone to use. :) But I will stop using them if I'm not allowed... :oops:
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

zaleschiemilgabriel wrote:And thirdly, I assume that if those emoticons are there for everyone to see, they are also there for everyone to use. :)
A common misconception when it comes to "stuff that's on the internet".
Every good solution is obvious once you've found it.
bobjohnson2121
Posts: 2
Joined: Wed Apr 27, 2016 9:48 am
Libera.chat IRC: bobjohnson2121

Re:

Post by bobjohnson2121 »

Sorry to resurrect this very old thread, but does anyone know why Ready4Dis mentions 0x100FEFF in his post? I can't understand how he came to that number, but would really like to understand if anyone wouldn't mind helping me out.

Thanks for any help!

Ready4Dis wrote:Well, firstly, you need to make sure that the EIP you are at is a valid 16-bit EIP. You also must first drop down to 16-bit pmode before making the switch, then you also have to make sure you are at a legitemate physical address (paging not available in real-mode). So, to recap:
Must be <1mb (well, below 0x100FEFF), in 16-bit pmode, and at a valid physical page (not virtual). If all these are met, you now have to make sure the function knows where it's located, and it must support 16 and 32-bit relocations (well, unless you drop into 16-bit pmode on entry, then it must only support 16-bit relocations). The easiest method would be like this:

Memory map bottom 1mb (or however much you need, probably 4k is plenty), setup a 16-bit code and data segment, then reserve a block of memory below 1mb for your program (binary is nice, because elf, coff, etc don't support 16-bit relocations, and it'll have to be written in ASM). So, now we write the entry code similar to this:

Code: Select all

[bits 16]
[org 0x1000] ;Whatever you want here, 16-bit reserved location
Entry16:
  cli ;Disable interrupts
  mov eax, DATASEL16 ;16 bit data selector
  mov ds, eax
  mov es, eax
  mov fs, eax
  mov gs, eax
;Disable paging, works because it's a 1:1 mapping!
  mov eax, cr0
  and eax, 0x7FFFFFFe ;Disable paging bit & enable 16-bit pmode
  mov cr0, eax
  jump 0x0000:GoRMode ;Perform Far jump to setup CS :)
GoRMode:
  mov ax, 0x0000  ;Reset data selectors to 0x0000
  mov ds, ax
  mov es, ax
  mov fs, ax
  mov gs, ax
  lidt 0x000    ;Real move IVT is @ 0x0000
  sti               ;Restore interrupts, be careful, unhandled int's will kill it
;And finally we are ready to play in real mode!
This code was written in this window, I may have missed a step or so, but should get you pointed in the right direction. Be careful enabling ints, you probably want to disable your PIC or APIC before entering real-mode so you don't have unhandled interrupts firing. You can go back into p-mode after this, just remember to reset the IDT, re-enable everything (paging, pmode bit), do a retf (far return, so it pops the Code segment back off as well, and when you call this you need to do a far call (callf CODESEL16:0x1000) to the function. So, basically it's not difficult, just have to remember that real-mode and p-mode are very different (16-bit, no virtual memory, IVT instead of IDT, cannot access > 1mb, etc, etc). If you run into more problems, let us know, that should get you started pretty nicely though. The other option (not sure how APM works exactly, so this may or may not be viable) is v86 mode.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Re:

Post by alexfru »

bobjohnson2121 wrote:does anyone know why Ready4Dis mentions 0x100FEFF in his post?
Multiple typosis?
(0xFFFF << 4) + 0xFFFF = 0x10FFEF
bobjohnson2121
Posts: 2
Joined: Wed Apr 27, 2016 9:48 am
Libera.chat IRC: bobjohnson2121

Re: Mixing 32bit and 16bit code (comming down into real mode

Post by bobjohnson2121 »

Ooooh man I hope not typos!

Here is why I am asking: I have an ambient pressure (altitude) sensor that is malfunctioning from time to time. I communicate with the sensor from a Freescale Microcontroller (MCF52223) using SPI, well Motorolla/Freescale/Google's version of SPI - QSPI. There are two 16 bit integers I read to create a 32 bit integer which I then run through an equation to calculate ambient pressure. Generally the data comes in fine, but once in a blue moon the two integers I read in are 0x100 and 0xFEFF which turns into 0x100FEFF, and is not the correct data.

So I punched 0x100FEFF into google hoping to find some sort of computer science clue, and this forum is all that came up.
User avatar
jojo
Member
Member
Posts: 138
Joined: Mon Apr 18, 2016 9:50 am
Libera.chat IRC: jojo
Location: New York New York

Re: Mixing 32bit and 16bit code (comming down into real mode

Post by jojo »

That's... kind of hilarious.

Probably should've realized after about five minutes of reading through this thread that this is, like... insanely unrelated.
User avatar
osdever
Member
Member
Posts: 492
Joined: Fri Apr 03, 2015 9:41 am
Contact:

Re:

Post by osdever »

Stevo14 wrote: Again, I'm probably missing something very fundamental.
Yes. IDTR contains not IDT address, but special pointer structure. Use Ready4Dis's code.
Developing U365.
Source:
only testing: http://gitlab.com/bps-projs/U365/tree/testing

OSDev newbies can copy any code from my repositories, just leave a notice that this code was written by U365 development team, not by you.
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: Mixing 32bit and 16bit code (comming down into real mode

Post by alexfru »

bobjohnson2121 wrote:Ooooh man I hope not typos!

Here is why I am asking: I have an ambient pressure (altitude) sensor that is malfunctioning from time to time. I communicate with the sensor from a Freescale Microcontroller (MCF52223) using SPI, well Motorolla/Freescale/Google's version of SPI - QSPI. There are two 16 bit integers I read to create a 32 bit integer which I then run through an equation to calculate ambient pressure. Generally the data comes in fine, but once in a blue moon the two integers I read in are 0x100 and 0xFEFF which turns into 0x100FEFF, and is not the correct data.

So I punched 0x100FEFF into google hoping to find some sort of computer science clue, and this forum is all that came up.
Then this is completely unrelated. :)
If you're curious, the value (0xFFFF << 4) + 0xFFFF = 0x10FFEF is the maximum physical memory address that the x86 CPU can access while in real addressing mode (a segment register 16-bit value is shifted left 4 positions and a 16-bit offset is added to it). Slightly over 1MB.

Now, what I'd do about the sensor is check two things. First, if that specific pair of values is a special value that indicates some kind of error (value out of range, sensor in wrong mode, etc). See the documentation. Particularly suspicious is that 0x100 + 0xFEFF = 0xFFFF. Second, I'd check that the communication with the sensor is solid and the whole thing is put together correctly (wiring, any resistors/capacitors present/absent, frequencies/timing, pulse shapes, supplied voltage/current, etc). I'd also check how the I/O ports are programmed and see if any data can be lost or garbled because of some software bug (e.g. hardware miscofiguration, race condition, too big/small delays between port accesses, issues around interrupt handling/acknowledging, DMA (if any), entering and exiting various power modes (e.g. standby), etc). I don't know your system and am not going to learn about it, just giving some hints/directions.
Post Reply