Recent

Author Topic: Lazarus for RISC OS  (Read 33893 times)

micken

  • Jr. Member
  • **
  • Posts: 82
Re: Lazarus for RISC OS
« Reply #15 on: July 21, 2023, 11:26:15 pm »
Hello Ron!

I understand that you have got lose ends from me over copy/paste :)

The things I have done.
Built fpc for arm linux with risc os binutils
Hacked a lot in linux rtl.
So it starts.. but doesn't get far. It would probably be easier to start with another rtl as base. AROS uses amiga shared libraries I guess.
RISC OS uses fixed SWI calls for everything.. like SWI 0 , for putc SWI 2 for puts etc. I am not sure if I can dedicate time for bringing up
fpc on risc os. But if you can help with a skeleton rtl , I could probably fill in the missing bits. RISC OS is not a posix system , even less than
Amiga. So ... lots of troubles.

Best regards,
Michael

TRon

  • Hero Member
  • *****
  • Posts: 3792
Re: Lazarus for RISC OS
« Reply #16 on: July 22, 2023, 01:32:47 am »
I understand that you have got lose ends from me over copy/paste :)
I'm still in the process of evaluating. Usually I figure things out as I go along. RiscOS is fairly new to me.

Quote
So it starts.. but doesn't get far. It would probably be easier to start with another rtl as base.
:)

The platform needs to be added to the compiler internals to make things a bit more comfy, then some (elf) startup code is required (usually a copy of what c does but a bot more Pascalified for the compiler so anything related to register usage or used ABI is welcome). After that the first RTL bits can be added.

Quote
AROS uses amiga shared libraries I guess.
Correct and for that it uses syscalls which is a concept only available for amiga like platforms (HASAMIGA)

Quote
RISC OS uses fixed SWI calls for everything.. like SWI 0 , for putc SWI 2 for puts etc. I am not sure if I can dedicate time for bringing up
fpc on risc os. But if you can help with a skeleton rtl , I could probably fill in the missing bits. RISC OS is not a posix system , even less than
Amiga. So ... lots of troubles.
The troubles are expected.

Can I compare swi's with something like (back in the days of) ms-dos and interrupt calls ? Is there any documentation on how swi's are implemented, what their cpu register/stack usage is etc ? I already found some list of available swi's calls (additional links to documentation would be appreciated) but that does not explain how things are in registers ad how registers are stored on the stack. I am aware that the whole source-code for riscos is available but just like for you the repository of Free Pascal might perhaps look a bit overwhelming so does the riscos repository look for me atm  :D

regards,
I do not have to remember anything anymore thanks to total-recall.

micken

  • Jr. Member
  • **
  • Posts: 82
Re: Lazarus for RISC OS
« Reply #17 on: July 22, 2023, 12:07:03 pm »
Startup code:
RISC OS doesn't require much of startup code. I am used to assembly and the most simple app is almost empty. I will dissasemble such a app when home again ( having vacation now ). The call convention is strictly ARM standards, RISC OS is modeled after the ARM cpu since it is designed by the inventors of ARM.

Current fpc status details:

I have hacked in support for write and memory allocation. RISC OS doesn't have native support for mmap, but there are other ways to allocate memory.
If I return -1 from the "mmap" call I get a nice error from fpc. I have noticed that fpc does call open and read and wonders what that expects. I am printing out the syscalls from the assembly routines. The problems that I am facing is bad pointers. It sooner or later fails with ldr str from memory. The fpgetenv fails in exit(). The PLD stuff doesn't work.. I Haven't found out where to config it to not using bx lr so I have binary patched that. I can follow the crashes and doing live patching. But ofc , it doesn't get very far. I can make it to read() call but after that I get get a abort on a address that isn't in ram. For getenv I just skipping it by " if defined(cpuarm)".

SWIs

You can find the docs here: https://www.riscosopen.org/wiki/documentation/show/HomePage
SWI stands for Software interrupt Instruction  ( i think you know this ). RISC OS is a singletasking system with cooperative multasking window system bolted on top. The system is driven by SWI calls,, each application gives cpu time to the system by guess what , a SWI! If I do a tight loop in assembly , the system freezes. Running a cli app in a taskwindow ( terminal ) does simulate some more multitasking , since the taskwindow gives cpu time. But it still freezes on "B ." .

I have a lot of projects going on, so not sure how much time I can spend with fpc.

I hope that this message helped a bit , I have spent one day with this. :-)

The picture shows the error if returning -1 :-)
« Last Edit: July 22, 2023, 12:52:17 pm by micken »

TRon

  • Hero Member
  • *****
  • Posts: 3792
Re: Lazarus for RISC OS
« Reply #18 on: July 22, 2023, 01:12:16 pm »
Thank you for your quick reply micken.

Quote
I have hacked in support for write and memory allocation. RISC OS doesn't have native support for mmap, but there are other ways to allocate memory.
Should be able to accommodate that as long as there is an alternative though in case wrong I would appreciate a heads up from one of the devs that know and happen to read this.

Quote
I have noticed that fpc does call open and read and wonders what that expects.
Depends, are you seeing those calls when using the linux or aros rtl as a base ?

Quote
I am printing out the syscalls from the assembly routines. The problems that I am facing is bad pointers. It sooner or later fails with ldr str from memory.
If the allocation fails to begin with then that would cause issues there.

Quote
The fpgetenv fails in exit().
Only works if/when riscos supports passing commandline arguments (argc, arv, argp) in a similar way as the rtl that is used for base (depending on the platform the registers/stack used to pass those values differ).

Quote
The PLD stuff doesn't work.. I Haven't found out where to config it to not using bx lr so I have binary patched that.
Platform specifics need to be configured correctly inside the compiler defined settings. As said in my previous post, I am working on those bits but as I already/also expressed to Stefan I have never done a full port and since having worked on the AROS rtl a lot of things seem to have been changed internally for the compiler. Unfortunately there is no full documentation available on how to do a full port (I am trying to document the process as well). I start at the basics and work my way through as I go along. First goal would be for the compiler to be able to recognize the riscos target so that a cross-compiler can be build, initially using some fake startup-code and basic rtl.

Right now I am adding things as needed and (re)building the compiler currently tells me I am (still) missing some things :D

Just like you I have multiple projects going on and have reserved the summer break to (also) try and catch up with a few things with regards to this project. There is currently no real need for you to worry about things that could be done by someone else.

Some assembly is probably required for the startup code, or at least to verify if the compiler creates it correctly and is usable by riscos (there I could use all the help I can get as my arm asm skills are next to none /and/ I am not familiar with riscos binaries).

Thank you very much for the help so far.

regards,

edit: typo's
« Last Edit: July 22, 2023, 01:17:32 pm by TRon »
I do not have to remember anything anymore thanks to total-recall.

StefanRISCOS

  • New Member
  • *
  • Posts: 29
Re: Lazarus for RISC OS
« Reply #19 on: July 22, 2023, 05:03:47 pm »
@Tron
About ARM assembler in RISC OS:
You can easily create ARM assembler programs inside the BBC BASIC:

https://simplemachines.it/doc/www.heyrick.co.uk/assembler/basic.html

http://www.riscos.com/support/developers/prm/asm.html

I could sponsor you this book if you think it might be useful
https://www.brucesmith.info/raspberry-pi-risc-os-beginners-assembly-language.html

micken

  • Jr. Member
  • **
  • Posts: 82
Re: Lazarus for RISC OS
« Reply #20 on: July 22, 2023, 06:27:27 pm »
@Ron

Sorry for not quoting  .. better at email than forums :)

I have sorted the stack and that gave me less errors.

Is there a document covering the flow of compiler start? Right now I get: stat64,open,close and after that instruction fetch abort at a address not in ram.
My guess is that it tries to check for a source file, but if open returns -1 it should just bail out , right? I also have the same for stat64 , returning negative.
Instruction fetch abort is probably a branch with bx reg , where reg is corrupted.

Haha found it. The big question is why! it branches to a fixed address?!

Another interesting find , is that fpc thinks that file  is open , even when open returned negative.
« Last Edit: July 22, 2023, 07:20:39 pm by micken »

TRon

  • Hero Member
  • *****
  • Posts: 3792
Re: Lazarus for RISC OS
« Reply #21 on: July 22, 2023, 07:56:03 pm »
Sorry for not quoting  .. better at email than forums :)
Don't worry. As long as it isn't a thread with over 5 individuals all shouting against each other at the same time then we'll be fine  :)

Quote
Is there a document covering the flow of compiler start?
No, not that I am aware of.

But based on the AROS parts and Free Pascal in general I can take a stab

sources reference:  https://gitlab.com/freepascal.org/fpc/source

Please do not take offense if i insult your intelligence with some obvious remarks/statements (I have to assume that like me you know nothing about this stuff).

The compiler executable (fpc) program file can be found at compiler/utils/fpc.pp

The "main start" of that program can be found at the bottom "begin" <lots of code> "end." pair

But, Pascal allows for units to be included in their "uses" section at the top. For fpc.pp file it explicitly includes unit Sysutils.

Each included unit /could/ include initialization code (executed before the main program start) and finalization code (executed after main program start end) and ordered in uses order (for init, for fina the order is in reverse).

Those initialization and finalization portions can explicitly be defined by using their respective keywords "initialization" and "finalization" that define a section that contains the code that is executed. If there isn't such a section explicitly defined but the unit does have a begin ... end. pair listed in its implementation section then that is equivalent to the initialization section. For details see https://www.freepascal.org/docs-html/current/ref/refse112.html

What is not explicitly mentioned in the code is that every program that get compiled also (automatically) includes the so called system unit (part of the rtl).

So, falling back to aros (as it is for me the simplest example) the system unit can be found at rtl/aros/system.pp

If you take a closer look at that unit then there is a initialization section (not explicitly defined) that gets executed. That is basically the first code (for initializing the rtl) that is executed.

If you take a closer look at the directory rtl/aros then you can also find some other files (which ones are present depend on the platform) and some directories that contain processor specific startup code. In our case
the arm directory would be the most interesting. In there is a file named "prt.as" and is something that should look a bit more familiar to you (even though the code is specific to/for aros). You can find a similar structure for Linux in the directory rtl/linux/ though there you are able to find many more cpu directories and their content is also a bit more overwhelming (too much for me to explain) but do have a look at the files inside the arm directory again as some of it might look familiar for/to you.

Going back to rtl/aros there you can also find a file named "si_prc.pp". I would advise to have a look there as that should look familiar to you (at least when running through a debugger that supports symbols and you have your Free Pascal code (fpc.pp for example) compiled with a (for your debugger) supported debug format.

The rest is as we say history, as we now have enough information to grep around to locate all the used symbols and subroutines that are used by the system routine. The only part that makes things more complicated is that common parts for some of the code is stored in a generic include directory and can be overridden by a 'local' include file (it is not always obvious when/if that happens so can get become lost at times in trying to trace the program flow).


Is that enough information to get you started with understanding things a bit better ?


What might perhaps be helpful to know as well is that you can for example compile a simple helloworld program with the compiler and have free pascal output the asm output for you (fpc -al hello_world.pas) so that you can match that asm output with what you see in the debugger. The fpc produced asm code can fairly easy be traced back to its Pascal equivalent by grepping the Free Pascal source-tree for functions and symbols names. For more details on compiler switches see: https://www.freepascal.org/docs-html/user/userap1.html

regards,
I do not have to remember anything anymore thanks to total-recall.

micken

  • Jr. Member
  • **
  • Posts: 82
Re: Lazarus for RISC OS
« Reply #22 on: July 22, 2023, 08:18:26 pm »
Thanks! Very welcome. There is no debugger for elf binaries in risc os. So the only way is to rely on faults addresses combined with objdump on compiler system and printouts.

TRon

  • Hero Member
  • *****
  • Posts: 3792
Re: Lazarus for RISC OS
« Reply #23 on: July 22, 2023, 08:41:16 pm »
There is no debugger for elf binaries in risc os. So the only way is to rely on faults addresses combined with objdump on compiler system and printouts.
Ah, that is unfortunate. In that case we would have to disassemble a c compiler generated example code and compare that against startup code generated by Free Pascal (a simple hello world example would suffice for such a task), that is unless the arm asm (c might perhaps suffice as well) startup code for riscos is listed/documented somewhere. Do you happen to know if that is the case or perhaps you know that code by heart ?

PS: forgot to mention that fpc.pp is actually a frontend to the(actual) compiler which is named pp.pas. I also noticed the mention of swi's somewhere in the source-tree so that seem to be accounted for (needs verification)

PPS: also note that you are going way to faaast for me  :) As soon as I can get the compiler to recognize/support the basics for the riscos target then I/we can start thinking of experimenting with some startup-code.
« Last Edit: July 22, 2023, 09:02:04 pm by TRon »
I do not have to remember anything anymore thanks to total-recall.

micken

  • Jr. Member
  • **
  • Posts: 82
Re: Lazarus for RISC OS
« Reply #24 on: July 22, 2023, 09:01:26 pm »
There is no debugger for elf binaries in risc os. So the only way is to rely on faults addresses combined with objdump on compiler system and printouts.
Ah, that is unfortunate. In that case we would have to disassemble a c compiler generated example code and compare that against startup code generated by Free Pascal (a simple hello world example would suffice for such a task), that is unless the arm asm (c might perhaps suffice as well) startup code for riscos is listed/documented somewhere. Do you happen to know if that is the case or perhaps you know that code by heart ?

PS: forgot to mention that fpc.pp is actually a frontend to the(actual) compiler which is named pp.pas. I also noticed the mention of swi's somewhere in the source-tree so that seem to be accounted for (needs verification)


Here is a example of a riscos executable in AOF format ( not elf ). Not much going on. OS_GetEnv givs you the commandlne which in turn can be made a list with another swi. This is a assembly written app. If you mix in the clibrary it will be much more complex. But that isn't needed for fpc.

00008000 : E1A00000 : .. á : MOV     R0,R0
00008004 : E1A00000 : .. á : MOV     R0,R0
00008008 : E1A00000 : .. á : MOV     R0,R0
0000800C : EB00001B : ...ë : BL      &00008080
00008010 : EF000011 : ...ï : SWI     OS_Exit
00008014 : 00000090 : ... : MULEQ   R0,R0,R0           ; *** Rd=Rm or Rd=R15
00008018 : 00000000 : .... : ANDEQ   R0,R0,R0
0000801C : 00000000 : .... : ANDEQ   R0,R0,R0
00008020 : 00000000 : .... : ANDEQ   R0,R0,R0
00008024 : 00000000 : .... : ANDEQ   R0,R0,R0
00008028 : 00008000 : .€.. : ANDEQ   R8,R0,R0
0000802C : 00000000 : .... : ANDEQ   R0,R0,R0
00008030 : 00000020 :  ... : ANDEQ   R0,R0,R0,LSR #32
00008034 : 00000000 : .... : ANDEQ   R0,R0,R0
00008038 : 00000000 : .... : ANDEQ   R0,R0,R0
0000803C : 00000000 : .... : ANDEQ   R0,R0,R0
00008040 : E1A00000 : .. á : MOV     R0,R0
00008044 : E04EC00F : .ÀNà : SUB     R12,R14,PC
00008048 : E08FC00C : .Àà : ADD     R12,PC,R12
0000804C : E99C000F : ..œé : LDMIB   R12,{R0-R3}
00008050 : E24CC010 : .ÀLâ : SUB     R12,R12,#&10       ; =16
00008054 : E59C2030 : 0 œå : LDR     R2,[R12,#48]
00008058 : E3120C01 : ...ã : TST     R2,#&0100          ; =256
0000805C : 159CC034 : 4Àœ. : LDRNE   R12,[R12,#52]
00008060 : 008CC000 : .ÀŒ. : ADDEQ   R12,R12,R0
00008064 : E08CC001 : .ÀŒà : ADD     R12,R12,R1
00008068 : E3A00000 : .. ã : MOV     R0,#0
0000806C : E3530000 : ..Sã : CMP     R3,#0
00008070 : D1A0F00E : .ð Ñ : MOVLE   PC,R14
00008074 : E48C0004 : ..Œä : STR     R0,[R12],#4
00008078 : E2533004 : .0Sâ : SUBS    R3,R3,#4
0000807C : EAFFFFFB : ûÿÿê : B       &00008070
00008080 : EF000010 : ...ï : SWI     OS_GetEnv
00008084 : E1A0D001 : .Ð á : MOV     R13,R1
00008088 : EF000002 : ...ï : SWI     OS_Write0
0000808C : EF000011 : ...ï : SWI     OS_Exit
« Last Edit: July 22, 2023, 09:04:29 pm by micken »

TRon

  • Hero Member
  • *****
  • Posts: 3792
Re: Lazarus for RISC OS
« Reply #25 on: July 22, 2023, 09:06:27 pm »
Here is a example of a riscos executable in AOF format ( not elf ). Not much going on. OS_GetEnv givs you the commandlne which in turn can be made a list with another swi.
Oh, that is perfect to start with. The only thing that could make it better is some documentation on what is done for what reason (some used instructions are clear of what they do but not why as i am unfamiliar with the kernel/io of riscos). Perhaps I'm able to figure it out myself along the way.

I take it there is no difference for riscos wrt startup code when a program is started either from a shell or the GUI (e.g. same register usage for both situation) ? the Amiga/Aros target differentiate between the two situations.
« Last Edit: July 22, 2023, 09:08:48 pm by TRon »
I do not have to remember anything anymore thanks to total-recall.

micken

  • Jr. Member
  • **
  • Posts: 82
Re: Lazarus for RISC OS
« Reply #26 on: July 22, 2023, 09:17:42 pm »
Here is a example of a riscos executable in AOF format ( not elf ). Not much going on. OS_GetEnv givs you the commandlne which in turn can be made a list with another swi.
Oh, that is perfect to start with. The only thing that could make it better is some documentation on what is done for what reason (some used instructions are clear of what they do but not why as i am unfamiliar with the kernel/io of riscos). Perhaps I'm able to figure it out myself along the way.

I take it there is no difference for riscos wrt startup code when a program is started either from a shell or the GUI (e.g. same register usage for both situation) ? the Amiga/Aros target differentiate between the two situations.

No difference .. apart from that a WiMP app is assumed to poll events .. if not system freeze. It also needs to be a new "task". A cli app can also be a WiMP task if needed.
I can double click on my little executable and it starts in a window that you can't move .. and assuming you return somehow in your code .. you can press space in order to continue riscos.

TRon

  • Hero Member
  • *****
  • Posts: 3792
Re: Lazarus for RISC OS
« Reply #27 on: July 22, 2023, 09:24:12 pm »
Thank you very much micken. Unfortunately I need to call it quits for today (duty calls).
I do not have to remember anything anymore thanks to total-recall.

micken

  • Jr. Member
  • **
  • Posts: 82
Re: Lazarus for RISC OS
« Reply #28 on: July 22, 2023, 09:50:15 pm »
Thank you very much micken. Unfortunately I need to call it quits for today (duty calls).

Thanks to you! A difference from a elf file is that the address info is correct.. ie starts at &8008. This means it can be *loaded and debugged with simple break commands. In theory it can be done with a elf file,, but it needs to be linked with a start address.. as it is normally everything is from 0x0. The start/load address is a part of the elf loader.
« Last Edit: July 22, 2023, 10:17:56 pm by micken »

micken

  • Jr. Member
  • **
  • Posts: 82
Re: Lazarus for RISC OS
« Reply #29 on: July 22, 2023, 10:53:05 pm »
The elf file can (with a bit of change in header) be converted to acorn format with the tool elf2aif. The resulting binary can be used with debugger. Unfortunately it didn't work taht well with fpc.. dunno ..

anyway screenshot attached 

 

TinyPortal © 2005-2018