10

Out of all the operating systems for the 80286 processor I found, only two make use of the protected mode's ability to load more than one segment for text and one for data. These are MS-DOS (through various DOS extenders) and Windows. All other operating systems I checked would only give one text segment and one data segment to each process and call it a day. Were there any other operating systems that made full use of protected mode segmentation on the 80286?

IconDaemon
  • 103
  • 3
fuz
  • 1,574
  • 10
  • 35
  • I can find a lot of sources that strongly imply that MINIX is an answer, but none that is a smoking gun. Certainly there is a whole-system limit of 16mb but confirmation of per-process limits so far eludes me. Maybe somebody else can help? – Tommy Oct 30 '18 at 16:33
  • 2
    @Tommy Minix is not the answer as far as I'm concerned. On Minix, each process has one text and one data/stack segment. Segment sizes are fixed at link time and can be changed by the chmem utility to give programs more space. It's not possible to change segment sizes at runtime, there isn't even a brk syscall! – fuz Oct 30 '18 at 16:36
  • you have definitively stomped on that suggestion. I'll wager there's at least one CP/M-86 program that just runs away with the environment and thereby is as valid an answer as DOS, but that also feels like a cheat. It'd be interesting to know what VisiOn does given that programs are interpreted, not natively compiled. – Tommy Oct 30 '18 at 16:43
  • 5
    What about Xenix 286? – mannaggia Oct 30 '18 at 17:04
  • 5
    Your title is a bit misleading - The answer to that question is "all". – tofro Oct 30 '18 at 17:39
  • @tofro Minix for example does not. And back when I checked Xenix, my impression was that the answer for Xenix was “no,” too. – fuz Oct 30 '18 at 17:51
  • @fuz Maybe the earliest versions of Microsoft Xenix had that limitation, but I doubt it. SCO Xenix 286 didn't. –  Oct 30 '18 at 19:07
  • There was a Xenix for PC/XT that was limited. Pretty certain Xenix 286 allowed up to 16MB. It’s been a while but I used it a lot back in the day. – mannaggia Oct 30 '18 at 21:42
  • @mannaggia Up to 16 MB total RAM is what the 80286 can do. The question is if more than 64k text + 64k data are possible for a single process. – fuz Oct 30 '18 at 22:12
  • 3
    I find it a little misleading to say that MS-DOS made use of this ability. More accurate would be to say it didn't get in the way of user code doing it. User code pretty much had unfettered access to the underlying hardware. –  Oct 30 '18 at 23:02
  • Yep, I get that. I worked for a developer of accounting software written in COBOL, compiling to p-code, and I know just the runtime itself was larger than that. – mannaggia Oct 30 '18 at 23:03
  • The misleading part is "data" - You don't need a 286 or protected mode to address more than 128k of data. Even an 8088 can do that. – tofro Oct 31 '18 at 08:00
  • 1
    @tofro I read it as significant because on a 286 in protected mode, you can only access what your segment descriptors will allow you to; so you can end up being limited (as on Minix and Coherent). – Stephen Kitt Oct 31 '18 at 09:48
  • @mannaggia Xenix 286 definitely supports multiple segments, yes. – Stephen Kitt Oct 31 '18 at 09:49

1 Answers1

20

OS/2 supported “huge memory” on 286s. The New Executable format used for 16-bit OS/2 executables (and 16-bit Windows executables) supports multiple segments. At runtime, using the DosAllocHuge function, programs could allocate more than 64KiB of memory at a time, and would get a sequence of segment selectors which could be used to easily access all the allocated memory. The process is detailed in section 9.2.2 of Gordon Letwin’s Inside OS/2.

Xenix 286 also supported multiple text and data segments; processes with multiple segments were called “large model processes” (the same terminology as was used with C compilers under DOS). See Overview of the Xenix 286 Operating System.

FlexOS 286 (and perhaps Concurrent DOS 286) also allowed programs to allocate multiple segments. malloc could only allocate up to 64KiB at once, but programs could call it multiple times to allocate more than 64KiB in total in multiple segments.

I suspected Coherent 3 might have supported multiple segments, but it turns out that’s not the case, at least according to the Coherent 3.2 FAQ (question 7).

Stephen Kitt
  • 121,835
  • 17
  • 505
  • 462
  • Oh yeah, I totally forgot about OS/2. Any others you know of? – fuz Oct 30 '18 at 16:50
  • 1
    I'm pretty sure Concurrent DOS 286 could give something close to 1 Meg. (depending on how many holes for BIOS, video, etc.) per process. Even older CDOS on 8088/8086 could do that using LIM EMS - limiting processing to 128k in CDOS 286 would have made it totally useless. Of course once the 386 came along CDOS 386 did it all much better. – manassehkatz-Moving 2 Codidact Oct 30 '18 at 17:44
  • 2
    QNX is another likely candidate. Versions up to 4 ran on 286s. Some applications of the system (eg "QNX Windows", a variant with an openlook based GUI) required multiple megabytes of memory, so must have been running in protected mode. It would seem unusual for a system to require that much memory but only give out 128KiB per process. – Jules Oct 30 '18 at 18:23
  • 1
    iRMX286 is a possible candidate. It was Intel's real-time OS offering. It worked in protected mode and could address the full 16Mb range. I can't remember the details and I can't look them up either, having binned the manuals after not having looked at them for over 20 years. – cup Nov 01 '18 at 04:26
  • Yes, OS/2 v1.1 was marketed on just such a capability. – Mark Williams Nov 04 '18 at 20:22
  • How did, say, C compilers handle the multiple allocated segments? Did they generate special sequences to switch to a different segment? – mid Oct 19 '20 at 10:25
  • @mid on x86, they’d use instructions with far pointers. If necessary, they’d switch segments, but there’s not all that much special handling involved — the run-time cost comes from pointer canonicalisation in real mode, and keeping track of boundaries. – Stephen Kitt Oct 19 '20 at 11:24
  • I asked more about the actual sequence of instructions used to switch segments. Did it access the kernel for such situations? That would mean compilers produced OS-specific code – mid Oct 19 '20 at 13:44
  • @mid how familiar are you with segment-handling on x86? If you need to switch segments, you’d do something like push ax; pop ds (to change the data segment to the value stored in AX); that doesn’t involve the kernel, but it does check the segment permissions in protected mode. – Stephen Kitt Oct 19 '20 at 13:53
  • I thought we were talking about the 286 on protected mode. Sorry, I should've specified – mid Oct 19 '20 at 14:09
  • Oh, wow, I'm stupid. Sorry for troubling, @StephenKitt. I hadn't realized userspace can switch segments on 286 protected mode – mid Oct 19 '20 at 14:12
  • @mid ah, no worries, I wasn’t taking the context into account either (referring to real mode). Yes, user space can switch segments in protected mode, as long as it has access to the descriptors it’s using; but if it allocated memory using a kernel call, the kernel would have taken care of that (that’s part of the segment-handling algorithm documented for Windows in both real mode and protected mode, for example). – Stephen Kitt Oct 19 '20 at 14:13
  • @StephenKitt: I would think a program would more typically use les si,[someFarPointer] and then use an ES prefix on whatever instruction was going to use the fetched pointer. Just like in real mode except that the les instruction would take much longer because of the need to fetch a segment descriptor. – supercat Nov 04 '20 at 22:14