Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

flexible linux ELF

26 views
Skip to first unread message

Paul Edwards

unread,
Jan 29, 2024, 3:16:20 PMJan 29
to
I am looking to create a lightweight Linux
environment for Windows and/or PDOS/386.

First let me talk about the Amiga.

https://sourceforge.net/p/pdos/gitcode/ci/master/tree/pdpclib/amistart.asm

So on entry to an executable, Commodore set
d0 to the command length, and a0 to the
command buffer. As opposed to Unix style of
parameters already parsed and on the stack,
or Windows style where you may a system call.

However, Amiga executables, after the library
is linked in, effectively have another number
hardcoded - 4. This is the SysBase where the
equivalent of glibc is hanging off. And with
the number 4 hardcoded, that C library is
unchangeable.

Commodore had goals and constraints that I
don't have.

I would like to have a more flexible SysBase,
so that I can run a flavor of PDOS under the
Amiga, and then for (certain - not ones with
a hardcoded, unchangeable 4 embedded in them)
Amiga applications to be able to run under that
instead, with files being redirected to an
emulated FAT16 disk or whatever.

So what I did was "create a convention" to pass
the SysBase in d7, and then add 2 GiB to d0 as
a flag to alert to the presence of d7.

So for my (pdpclib) applications, I check if d0
is greater than or equal to 2 GiB, and if so,
subtract 2 GiB to get the original length, and
at the same time fetch d7, and use that as the
SysBase. Otherwise I hardcode the number 4 like
everyone else.

And I'm happy with that. My pdpclib-based applications
will run under standard AmigaOS, but also can
potentially run under an emulation layer on the
Atari, or under a flavor of PDOS under the Amiga.
I set up alternative structures, and the app will
use those.

Commodore may not have liked the idea of Amiga
applications running on the Atari, so may not
have been willing to have such a scheme, so
perhaps in hindsight it would have needed some
sort of "programmer consortium" to override
Commodore.

Anyway, I'm happy with my "consortium" of 1 person
who is very late to the party. So my own executables
do what I want. And that's all I really care about.

Now I'm looking to do something similar for any
ELF executables I produce.

So I want to have the OPTION of producing an ELF
executable so that it runs on standard Linux. But
for that ELF executable to also run on some other
environment such as Windows, PDOS/386 or PDOS-generic.

Wintows and PDOS/386 don't pass anything on program
entry that I am aware of (or use). PDOS-generic does -
it passes a pointer similar to SysBase (which is why
PDOS-generic was invented in an Amiga forum).

I'm happy to change what PDOS-generic passes on the
stack, so long as it is just some extra parameters
that can be done in C instead of assembler.

I'm also happy for my (pdpclib-based) ELF executables
to be written to a new standard.

So sticking with 32-bit for now, there are two types
of ELF executables:

1. Does INT 80H
2. Uses glibc

Type 1 I have (limited) support for in PDOS/386 already
(ie I have an INT 80H handler). I do not wish to support
that in PDOS-generic as it is not possible/designed to
do that.

Type 2 I wish to run under PDOS-generic the same way
as I have a lightweight (53k) "Wine" - ie switch the
glibc references over to the native C library. I assume
this is technically possible but I've never dealt with
ELF internals before. PDOS-generic (pseudo-bios) would
be run on Windows.

But in both cases, there won't be any argc/argv on the
stack (and I don't want to change that - I want to
change the ELF executables instead).

So my question is - can someone suggest some ELF startup
code design that would work on both standard Linux and
PDOS-generic (type 2) and possibly PDOS/386 (type 1 - but
this is less possible and less important).

So with type 2, there will be a return address on the
stack, and the ELF startup code could check if that is
an unreasonably large value for argc. Or it could do
that, and then go on to check the next value on the
stack. If that is the number 1, or -1, then that is an
unreasonable value for argv[0]. So this is assumed to
be a PDOS-generic environment, and the command line is
fetched from (and then parsed) the SysBase-equivalent
instead of obtained already-broken-up from the stack.

The second flavor would require a change to PDOS-generic
to call applications with a 1 or -1 as the first
parameter, and SysBase-equivalent would be the second
parameter. I could do some "forward-planning" here
(that's my question) and pass some more parameters if
that would be helpful (would it, and what would they
be?). Note that Commodore may have failed to do forward
planning too. They probably didn't have access to
alt.os.development either.

This presumably means that the command-line breakup
code will be statically-linked into every (new) ELF
executable because there is presumably no standard
glibc function to do that (Windows has getmainargs
though, so maybe there is?). That's unfortunate, but
I can live with that.

For Type 1, I could change PDOS/386 to pass the
same things on the stack as PDOS-generic. Or maybe
it would be more appropriate to set an environment
variable and the ELF executable looks for that as
an override to inspecting the stack. PDOS-generic
could potentially do that too, although not so
easily, as there is a C90 getenv() but not setenv(),
and I wish to write my pseudo-bios in C90 as much
as possible.

Any suggestions? And any larger philosophical
questions underpinning this that I don't know
how to ask? (something similar to me not knowing
about block mode devices vs character mode
devices).

Thanks. Paul.

Paul Edwards

unread,
Feb 16, 2024, 6:52:59 PMFeb 16
to
On 30/01/24 04:16, Paul Edwards wrote:

> So sticking with 32-bit for now, there are two types
> of ELF executables:
>
> 1. Does INT 80H

> So my question is - can someone suggest some ELF startup
> code design that would work on both standard Linux and
> PDOS-generic (type 2) and possibly PDOS/386 (type 1 - but
> this is less possible and less important).

So I have an answer to this now:

you can use the getpid() syscall to get the process ID, then open and
read /proc/<PID>/cmdline

Apparently this method exists in Unix too.

So that relieves the burden on the stack
format. It does mean that the OS needs to
recognize the special open of "/proc", but
that's fine - that will be easier to implement
in standard C code.

BFN. Paul.

Scott Lurndal

unread,
Feb 17, 2024, 11:49:04 AMFeb 17
to
Paul Edwards <muta...@gmail.com> writes:
>On 30/01/24 04:16, Paul Edwards wrote:
>
>> So sticking with 32-bit for now, there are two types
>> of ELF executables:
>>
>> 1. Does INT 80H
>
>> So my question is - can someone suggest some ELF startup
>> code design that would work on both standard Linux and
>> PDOS-generic (type 2) and possibly PDOS/386 (type 1 - but
>> this is less possible and less important).
>
>So I have an answer to this now:
>
>you can use the getpid() syscall to get the process ID, then open and
>read /proc/<PID>/cmdline
>
>Apparently this method exists in Unix too.

But no linux code uses it to substitute for the argc and argv
arguments to main.

Paul Edwards

unread,
Feb 17, 2024, 10:20:05 PMFeb 17
to
Any executable I compile (against PDPCLIB) will though.

And that's all I'm after. "standards" for me to follow
myself. I am reminded of this:

https://en.wikipedia.org/wiki/Protected_mode

This was not without its limitations. If an application utilized or
relied on any of the techniques below, it would not run:[30]

Segment arithmetic
Privileged instructions
Direct hardware access
Writing to a code segment
Executing data
Overlapping segments
Use of BIOS functions, due to the BIOS interrupts being reserved by
Intel[31]
In reality, almost all DOS application programs violated these rules


So I have spent decades trying to organize my
own DOS code to follow the rules required to
transition not just to the above, but also
to 32-bit DOS (which never existed).

So I wanted to make my own code obey "the rules".

After all that effort it is more likely that I
am going to abandon the "DOS rules" altogether
and switch to the "OS/2 1.x rules", and apply
them to the 8086.

And/or switch to the "PDOS-generic rules".

And most of the above is largely irrelevant
because it turns out that all my applications
are C90 or C90 + ANSI X3.64 compliant so I
don't need anything special at all.

I was challenged about this a couple of days
ago. Someone said that to put the keyboard into
raw mode I needed to resort to BIOS calls, or
at least manipulation of the BIOS data areas.
But nope - the official ioctl/read are all that
are required.

BTW, unrelated to the above, I am planning on
adding OS/2 2.0 compatibility to PDOS/386, the
same way (limited) Win32 capability was added,
and the same way that I was planning to add
(further) ELF support above.

Anyway, I have Ubuntu Kylin installed again on
this Chicom computer, this time running under
Virtualbox, and this time from an American site
(I think) instead of direct from the PLA
(People's Suppression Army), so I will try out
this /proc theory now.

BFN. Paul.

Paul Edwards

unread,
Feb 18, 2024, 4:49:08 AMFeb 18
to
On 18/02/24 11:19, Paul Edwards wrote:

>>> you can use the getpid() syscall to get the process ID, then open and
>>> read /proc/<PID>/cmdline
>>>
>>> Apparently this method exists in Unix too.
>>
> Anyway, I have Ubuntu Kylin installed again on
> this Chicom computer, this time running under
> Virtualbox, and this time from an American site
> (I think) instead of direct from the PLA
> (People's Suppression Army), so I will try out
> this /proc theory now.

And ... it works!

So that's a very solid basis for PDOS/386.

With no msvcrt.dll or doscalls.dll present on
the PDOS/386 disk I am expecting to support
32-bit MSDOS (my definition), PDOS-generic,
Win32, OS/2 2.0 and Linux ELF executables.

All with a footprint that fits on a 360k floppy.

Or very close, anyway. ie it shouldn't be much
more than this:

C:\vbox>7z l pdos.vhd | grep -i pdos.sys
2024-02-14 12:10:02 ....A 241664 241664 PDOS.SYS

C:\vbox>7z l pdos.vhd | grep -i command.exe
2024-02-14 12:10:02 ....A 45568 49152 COMMAND.EXE

C:\vbox>7z l pdos.vhd | grep -i io.sys
2024-02-14 12:10:02 ....A 34103 36864 IO.SYS

C:\vbox>zcalc 241664+45568+34103
Calculated Value is 321335.000000


... in theory.

It would be cool if I could have a "hello world"
executable for each of those (OS/2, Linux etc)
on the same floppy. And even cooler if I could
run in 640k instead of the current requirement
for 2.5 MiB or something.

There were 80386 machines shipped with 1 MiB
of memory.

BFN. Paul.

Andy Valencia

unread,
Feb 18, 2024, 9:26:27 AMFeb 18
to
sc...@slp53.sl.home (Scott Lurndal) writes:
> >you can use the getpid() syscall to get the process ID, then open and
> >read /proc/<PID>/cmdline
> But no linux code uses it to substitute for the argc and argv
> arguments to main.

Right off the bat, I'm curious how you handle embedded spaces
in arguments?

$ mycommand arg1 "arg2 with extras" arg3

This context appears lost if you look at cmdline?

Andy Valencia
Home page: https://www.vsta.org/andy/
To contact me: https://www.vsta.org/contact/andy.html

Paul Edwards

unread,
Feb 18, 2024, 9:44:42 PMFeb 18
to
On 18/02/24 22:25, Andy Valencia wrote:
> sc...@slp53.sl.home (Scott Lurndal) writes:
>>> you can use the getpid() syscall to get the process ID, then open and
>>> read /proc/<PID>/cmdline
>> But no linux code uses it to substitute for the argc and argv
>> arguments to main.
>
> Right off the bat, I'm curious how you handle embedded spaces
> in arguments?
>
> $ mycommand arg1 "arg2 with extras" arg3
>
> This context appears lost if you look at cmdline?

I just tried it ...

root@kerravon2-pc:/home/kerravon/w2kshare# ./lintest.exe abc "d e f" ghi
welcome to pdptest3
main function is at 08048294
allocating 10 bytes
m1 is 0804FFB0
allocating 20 bytes
m2 is 08050000
stack is around FFA5115C
printing arguments
argc = 4
arg 0 is <./lintest.exe>
arg 1 is <abc>
arg 2 is <d e f>
arg 3 is <ghi>
root@kerravon2-pc:/home/kerravon/w2kshare#

... works fine already.

If it didn't, I would have reused the code I already
use for MSDOS.

BFN. Paul.

0 new messages