Would be someone so kind to answer some questions? These questions are about 16-bit instructions execution on intel processors in L4 usermode programs. First, excuse me for my bad English (it is not native for me).
And first I'll try to explain the motivation. -- I am now trying to contribute to the project aiming to create an Opensource OS/2 clone. (osFree aka OS/3 project, http://www.osfree.org/) The goal now is to create OS/2 API implementation with binary compatibility with existing OS/2 (intel) applications. Also, it would be desirable to reuse existing OS/2 device driver base (if it is possible). We are planning to use L4 as a base for API implementation.
The problem with existing OS/2 applications is that they are not pure 32-bit; there are many common 16-bit API's now (they are to be replaced with 32-bit analogues in new implementation); almost each LX format executable contains 16-bit fragments (thunks for calling 16-bit API's), though the most of each executable is 32-bit and uses 32-bit flat memory model. Also, most old OS/2 device drivers are 16-bit, they are still very common now (but newer drivers are 32-bit). Another problem is that many drivers and applications are available in binary-only form (so, they cannot be recompiled, as with Linux) 32-bit applications and drivers support can be made, for example, by implementing a converter of LX-executables to pure 32-bits. Also, 16-bit fragments can be executed in a virtual machine. Or, as another variant, it may be possible to execute these 16-bit parts on a real processor. The problem is only how to maintain correct segment registers values and how to add a 16-bit segment descriptor to GDT or LDT.
The problem with L4 is that it doesn't expose segmentation to outside the kernel, it abstracts segmentation from usermode programs and only allows to use paging, but not segmentation. The reason is known: segmentation is not portable, it has no analogues on other architectures than intel one.
So, the questions are:
1) There is L4Linux. It is mostly 32-bit. But as I know, the Linux kernel also contains some 16-bit parts, such as setup code (it works with BIOS routines and probes hardware), and also (as I heard) acpi suspend/wakeup code. So, it contains 16-bit segments. But doesn't it interfere with L4? How did the people porting Linux to the L4 microkernel solve the problem of 16-bit code? And doesn't it interfere with ELF format capabilities (it is pure 32/64-bit, as I understand)?
2) Must all the segment registers be CS == DS == ES == FS == GS == SS == FLAT in L4 usermode programs (in Intel architecture implementation)? Or, there exist a possibility to use segments other than FLAT?
3) Is it possible to cause the L4 kernel to create 16-bit segment descriptor on Intel architecture?
Hi Valery,
Valery V. Sedletski wrote:
So, the questions are:
- There is L4Linux. It is mostly 32-bit. But as I know, the Linux kernel also contains some 16-bit parts, such as setup code (it
works with BIOS routines and probes hardware), and also (as I heard) acpi suspend/wakeup code. So, it contains 16-bit segments. But doesn't it interfere with L4? How did the people porting Linux to the L4 microkernel solve the problem of 16-bit code? And doesn't it interfere with ELF format capabilities (it is pure 32/64-bit, as I understand)?
The parts of 16-bit code in the Linux kernel are primarily to bootstrap the system and to bring it up again from deep sleep modes. In L4Linux, the microkernel does most of this job. So there is no need to run these parts in L4Linux anymore and they have thus been removed during the porting.
- Must all the segment registers be CS == DS == ES == FS == GS == SS == FLAT in L4 usermode programs (in Intel
architecture implementation)? Or, there exist a possibility to use segments other than FLAT?
Fiasco preserves some of these segments (e.g., GS to support thread local storage). However, unless OS/2 makes use of these segments in 32-bit mode there is no need to change these from a flat setting.
- Is it possible to cause the L4 kernel to create 16-bit segment descriptor on Intel architecture?
What you are looking for is microkernel support for the virtual x86 mode. Unfortunately, only the old L4 assembler kernels supported this processor mode and these are no longer supported. If you really want to run the 16-bit code on bare metal (and not in something like qemu) you probably need to add support for VM86 into the kernel (e.g., by adding an architecture specific systemcall which executes some code in VM86 mode and which returns with any abnormalities to a 32-bit exception handler).
Best regards
Marcus
On Wed, 20 Jun 2007 13:42:57 +0200, Marcus Voelp wrote:
Hi Valery,
- Must all the segment registers be CS == DS == ES == FS == GS == SS == FLAT in L4 usermode
programs (in Intel
architecture implementation)? Or, there exist a possibility to use segments other than FLAT?
Fiasco preserves some of these segments (e.g., GS to support thread local storage). However, unless OS/2 makes use of these segments in 32-bit mode there is no need to change these from a flat setting.
It seems, that OS/2 does not use GS (GS seems to be always == 0), at least, in application programs.
But, if the program contains 16-bit segments, there can be the need to execute 16-bit code in these segments. In OS/2, 16-bit protected mode segments can coexist with 32-bit flat segments. When 32-bit part of a program calls the 16-bit part, it comes through the thunk (assembler code, which converts 32-bits flat pointers into 16:16 pointers and passes control from 32-bit part to 16-bit one). So, during the passing through thunk, segment registers are loaded with 16-bit segment selector. So, there is a need in segments, other than flat (mostly, 16-bit ones).
- Is it possible to cause the L4 kernel to create 16-bit segment descriptor on Intel architecture?
What you are looking for is microkernel support for the virtual x86 mode.
But, V86 mode can help emulate Real mode. It is mostly useful for creating DOS emulator, but how can it help with creating 16-bit protected mode support? So, 16-bits != real mode (or I don't understand)
Unfortunately, only the old L4 assembler kernels supported this processor mode and these are no longer supported. If you really want to run the 16-bit code on bare metal (and not in something like qemu) you probably need to add support for VM86 into the kernel (e.g., by adding an architecture specific systemcall which executes some code in VM86 mode and which returns with any abnormalities to a 32-bit exception handler).
So, the V86 support can be implemented through architecture specific system call. And, probably, we need not only V86 support, but also a means to cause the L4 kernel to allocate GDT selector for 16-bit protected mode code support? So, the only way to execute 16-bit code (i.e., code in segmens with "16-bit" descriptor attribute) in L4 is to fork microkernel source code, adding custom changes?
Best regards
Marcus
-- Marcus V÷lp
Thanks for answering my questions, WBR, Valery
l4-hackers@os.inf.tu-dresden.de