gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Building an OS(Was:Dynamically loading & executing code)

#110497 - OOPMan - Tue Nov 28, 2006 10:33 pm

I'm interested in learning about whether or not it would be possible to dynamically load and execute
code from an external binary in a running homebrew program. Now, given that we have DSLinux and Moonshell
seems to have a plugin system I'm pretty sure it's possible, but I'm not too sure how it's done (And I
know that what applies to DSLinux in this regard does not necessarily apply to bare-metal homebrew anyway)

So, could anyone point me in the direction of some useful resources on the subject. I know tepples
mentioned the use of overlays in another thread a while back. Does anyone have information on
using these?

On the coding side, I'd imagine some assembler is necessary in order to cause a running program to
start executing binary code that has been loaded into an area of memory from an external file. Can anyone
give me any information on the kind of assembler need to do so?

Mainly I'm just looking for information. The idea of a "plugin" framework for code was mentioned in another
thread and I'm interested to find out just how feasible such a thing is...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...


Last edited by OOPMan on Thu Dec 21, 2006 3:56 pm; edited 3 times in total

#110499 - tepples - Tue Nov 28, 2006 10:37 pm

First read up on the ELF file format.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#110500 - Lick - Tue Nov 28, 2006 10:40 pm

Load up the binary to <address> and jump to that address. If you provide a specific return address, then the binary can jump back when it's done. I think that's the hard part.
_________________
http://licklick.wordpress.com

#110506 - tepples - Tue Nov 28, 2006 10:59 pm

But then we'll need a separate <address> for each piece of code that can be loaded at once. An ELF reader would allow loading a given piece of code at any <address>.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#110508 - Sausage Boy - Tue Nov 28, 2006 11:04 pm

ELF has relocation tables and stuff. The basic process is to find the code, relocate the code and run it. Sounds reasonably simple to me, but I guess it gets more complicated than that.
_________________
"no offense, but this is the gayest game ever"

#110517 - tepples - Wed Nov 29, 2006 12:13 am

That is, unless you compile your code with gcc option -fPIC . This will result in "position independent code" that runs slower but runs from any address. Mac OS 1 through 7 used this.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#110526 - sasq - Wed Nov 29, 2006 12:52 am

Unless the code you load uses no libraries itself (including libc) you have big problems. You can either link each binary statically which will waste huge amounts of memory (every plugin in a music player statically linked) or you need to create a very sophisticated dynamic library loader that handles dependencies between dynamic libraries with versions etc etc.

I think this is best left to operating systems.

#110529 - tepples - Wed Nov 29, 2006 1:00 am

Then the DS needs an operating system.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#110565 - OOPMan - Wed Nov 29, 2006 7:56 am

Thanks for all the useful info guys...

Hmmmm, so, we have a bit of a toss-up, though...

Either statically link all the plugins (Yech) or write a funky
dynamic linking loader (Ouch)...

Hmmmm...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#110580 - Sausage Boy - Wed Nov 29, 2006 3:32 pm

The last time I tried -fPIC with devkitPro, it didn't like me at all.

I think the wasted space from using statically link files is not nearly big enough to make up for the work of writing a dynamic library loader. If every program shares about 100kb of code, and you have 3 programs open, it means 300kb. Not too bad.
_________________
"no offense, but this is the gayest game ever"

#110586 - OOPMan - Wed Nov 29, 2006 4:46 pm

Hmmmm, maybe so, but it could add up, although it does depend on how many modules you have loaded at once. Also, it would be very very wasteful for ultra-small blocks of code :-(

The dynamic loader might be a better idea in the long run. I don't think one need go the whole hog and write and OS though, since the aim is to implement a modular code loading system, rather than provide all the functions of an OS...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#110594 - tepples - Wed Nov 29, 2006 7:14 pm

OOPMan wrote:
The dynamic loader might be a better idea in the long run. I don't think one need go the whole hog and write and OS though, since the aim is to implement a modular code loading system, rather than provide all the functions of an OS...

But once you've implemented a modular code loading system, a memory manager, a file system module, a way for modules to share interrupts, a way for modules to share input, and a way for modules to share the screen, you have implemented an operating system kernel.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#110596 - sajiimori - Wed Nov 29, 2006 7:27 pm

There are two basic problems to solve for dynamically loaded modules: calling out of the module, and calling into the module. It's not hard to solve them -- the real work is making it convenient and as automated as possible.

Calling out is pretty easy: enumerate all the functions that you want to be available, make a table of function pointers matching that enumeration, and have every module link in stub functions (that match the signatures of the shared functions) that index into the table to jump to the real code.

The stubs may not know where the table is, but it's easy to solve that by writing a software interrupt handler. Just put the function index to be called in r12 or something, then call the interrupt to execute it.

Calling into a module is similar: enumerate all the exported functions, put a table of offsets to those functions at the beginning of the module's binary, then write statically-linked stubs (matching the signature of the module's functions) that index into the table to jump into the module.

You'll surely want to automate the generation of the enumerations, tables, and stubs.

#111134 - Inopia - Mon Dec 04, 2006 9:53 am

@tepples: I agree the DS needs an OS. How about something like http://prex.sourceforge.net/ ? It already has a GBA port. If you look at http://prex.sourceforge.net/devel.html under 'Work completed', you can see it has Elf relocation.

It has multitasking and multithreading, small kernel memory footprint (<25k), no-mmu mode, and remote debugging services. I've looked at the source a bit, and it seems easy enough to write new device drivers.

I don't know enough about the DS hardware to do the port myself, but I think that if the scene wants to produce a viable multitasking platform for homebrew it's an option worth considering. Personally, I think a real operating system is the next step :P (and yes, dslinux is an OS, but not really tailored for the DS or at all usable right now)

#111140 - OOPMan - Mon Dec 04, 2006 10:35 am

Yes, given the discussion that this thread has spawned you are quite probably correct Inopia. It's interesting to see that PREX has a DS version...

Of course, there are other Real-Time OS'es out there, so it might be worth looking around, as it's quite possible there's another more mature project with ARM support...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#111150 - lyptt - Mon Dec 04, 2006 1:15 pm

I'd like to see an OS act as a replacement for the default firmware, the only problem is that an OS may be a lot larger than the space available for the firmware, although the GBA version of PREX is only around 65kb, which might work out pretty well if a similar filesize could be achieved for a DS version.

#111151 - Inopia - Mon Dec 04, 2006 1:17 pm

OOPMan: prex doesn't have a DS port yet, but it should be easy enough to adapt the GBA port.

#111152 - OOPMan - Mon Dec 04, 2006 1:45 pm

I think replacing the basic firmware with an OS might be more trouble than it's worth, considering that DSLinux runs just fine from a media adapter anyway...

Also, it would make getting your DS repaired a big problem, in the event of hardware failure...

Inopia, I meant to say GBA version :-) Bleh, my word failure...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#111156 - kusma - Mon Dec 04, 2006 2:05 pm

Inopia: hey man, good to see you are still alive! Still doing gba/ds-dev?

Onto the topic: Dynamic code relocation is really useful on it's own, especially for the GBA where you constantly battle the limits of IWRAM. IMO it would be really interesting to see an automated relocator. I have done a really basic one myself (using a script parsing objdump-output to know the size of symbols), but it requires manual setup all over and isn't really safe.

I haven't done any DS development myself yet, so I don't know about the real need for a ds-relocator.

#111435 - Inopia - Wed Dec 06, 2006 4:12 pm

Hey kusma <3! Not really active atm, but I'm keeping my eye on how things are going.

I think the main idea of having something like prex is that it supports multithreading/multitasking, not to mention that you'd not have to reboot your DS everytime you would want to switch programs :) Writing a device driver for the framebuffer would be straightforward enough, and would open up possibilities for a simple window manager :)

#111451 - OOPMan - Wed Dec 06, 2006 6:31 pm

The thing I would worry about with an OS is how much of the hardware it conceals. A big problem with DSLinux at the moment is that various elements of the DS's hardware are not really accessible under it in the same fashion they are under normal DS development...

No doubt this could be solved with proper device drivers, but still, it's something to look out for...

After all, at the moment DSLinux programs only have access to one screen, which is a bit of a downer...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#111519 - Darkflame - Thu Dec 07, 2006 5:54 am

prex looks quite interesting.
Seems crazy imo, to try to replace the ds's own firmware with anything too much, however :p
_________________
Darkflames Reviews --
Make your own at;
Rateoholic:Reviews for anything, by anyone.

#111547 - Inopia - Thu Dec 07, 2006 4:11 pm

I don't think prex or dslinux should be replacements for the firmware, but they would be a nice platform for homebrew.

As for hardware exposure, different drivers for the different pieces of flash hardware would be really nice for brewers. They wouldn't have to keep releasing new versions of their programs every time a new piece of kit hits the market.

#111558 - tyraen - Thu Dec 07, 2006 6:15 pm

Not that I know a whole lot about the subject, but from the Prex FAQ:
Quote:

Q. Does it support multi-processor systems?
No. Currently, Prex is designed only for uni-processor systems because of its performance and simplicity. OK, we know recent processor trend is moving to multi-core. This is one of our discussion item.

#111577 - OOPMan - Thu Dec 07, 2006 11:03 pm

Thanks for quoting that tyraen. That was something that I had some reservations about as well...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#111591 - Inopia - Fri Dec 08, 2006 2:00 am

Yeah, not being able to use the ARM7 is a downside :/

#111607 - OOPMan - Fri Dec 08, 2006 8:53 am

I don't think DSLinux allows actual usage of the ARM7 either. I know it makes use of it itself for input, etc, but I don't know if any DSL programs can access it...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#111654 - sajiimori - Fri Dec 08, 2006 7:01 pm

When an OS claims support for multiple CPUs, that has certain connotations that don't apply to the DS. In particular, it implies that the OS is going to automatically divide up tasks to be done on each CPU.

For the purposes of OS development, the DS isn't a multi-processor system, so it really doesn't matter if the OS supports that.

#111656 - Mighty Max - Fri Dec 08, 2006 7:52 pm

sajiimori wrote:

For the purposes of OS development, the DS isn't a multi-processor system, so it really doesn't matter if the OS supports that.

I disagree

OK, SMP is the popular way for multiprocessing (and relatively easy to handle for an OS), but unix derivates have been supporting asymetric processing power and hardware access for some time now.

Even from windows family there is an OS for runing on complete asymetric (and no remote memory access) systems: WinCCS 2003
_________________
GBAMP Multiboot

#111672 - OOPMan - Fri Dec 08, 2006 10:43 pm

You known, I was actually thinking about the libMPI work you're doing right now Max in connection with this thread.

While the ARM7 may not recieve the Lion's share of system resources of the bat, you've illustrated quite well with your libMPI stuff that parallelisation can work nicely on the DS.

On the other hand, let's just look at what happens if this hypothetical OS decides to ignore the ARM7. It will still be running an ARM7 binary in order to support input and sound. Which means that code written for said OS would have two choices (Simplistically speaking anyway): Treat the DS as a uni-processor system, or overwrite the OS's ARM7 binary with its own when it's loaded.

The first scenario would, in my opinion, remove a certain element of flexibility that DS coding provides, while the second would probably just plain be a bad bad idea :-)

I'd prefer it if an OS for the DS did support some kind of custom ARM7 binary, since the ARM7 is an integral part of the DS and obfuscating it's functionality via the OS would be a bit sad, in my opinion...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#111674 - HyperHacker - Fri Dec 08, 2006 10:56 pm

Well there'll have to be a kernel running on the ARM9, and obviously we'd need to run other applications' code on it at the same time. Why is this not feasible with ARM7?

Since ARM7 represents 33% of the system's processing power it's not really a good idea to just have it doing simple I/O. I'd think primarily it would be used by the OS alone, but would have routines to do CPU-heavy things like audio decoding, advanced math, etc, and the apps' ARM9 routines could call upon it to do these without needing any routines of their own running on ARM7. If it's necessary, apps could load some code (think kernel modules) into it as well. Maybe just write "add-on" apps that are ARM7 only that are always loaded, adding more APIs like this; for example write an MP3 decoder app that the OS would load at bootup, and then any app can have ARM7 decode an MP3.

In other words, ARM9 would have the kernel (loading apps into memory, file I/O, etc) and applications, ARM7 would have the API (functions apps can actually use while simultaneously doing whatever else, just as SNES games used the SuperFX, and expandable by these modules) and whatever parts of the kernel can't run on ARM9 (touch screen, wifi I/O, etc).
_________________
I'm a PSP hacker now, but I still <3 DS.

#111725 - Inopia - Sat Dec 09, 2006 1:58 pm

I agree with hyperhacker, nothing to add.

#111739 - OOPMan - Sat Dec 09, 2006 6:27 pm

Thing is, the ARM7 is still a CPU and I feel that locking it down and forcing it to do one set thing (Even if that set thing is actually a group of important things) would be a bit of a loss, in terms of flexibility...

It might be better if the ARM7 OS side contained only a very small micro-framework of some kind with everything else ARM7 destined being loaded and unloaded as needed. To be more explicit: The OS's ARM7 stuff could also be largely modular, thus allowing other programs as much access to the ARM7 as they desire. Or as little, if they choose to rely on the default OS ARM7 modules.

Thing is, I don't think it's good to, for example, always load an MP3 decoder or any other set module into the ARM7. One might be working on a homebrew app that does not make use of sound, or at least MP3s, in any major way. In which case loadng an MP3 decoder, or any other unused modules onto the ARM7 would be wasteful...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#111755 - OOPMan - Sat Dec 09, 2006 9:39 pm

Hmmmm, here's something of interest...

It's an RTOS called RTEMS...

Pertinent features from our standpoint would be:

  • Support for ARM7 and above
  • Multi-processor support
  • TCP/IP stack
  • GDB support
  • FAT support
  • The usual OS bells and whistles (Multi-tasking, etc...)
  • Python for scripting :-)


Apparently it was originally designed with missiles in mind :-)

I'm going to do some more looking :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#111764 - lyptt - Sat Dec 09, 2006 11:07 pm

That's mainly what real time operating systems are used for ;)

#111779 - HyperHacker - Sun Dec 10, 2006 12:50 am

OOPMan wrote:
Thing is, the ARM7 is still a CPU and I feel that locking it down and forcing it to do one set thing (Even if that set thing is actually a group of important things) would be a bit of a loss, in terms of flexibility...

It might be better if the ARM7 OS side contained only a very small micro-framework of some kind with everything else ARM7 destined being loaded and unloaded as needed. To be more explicit: The OS's ARM7 stuff could also be largely modular, thus allowing other programs as much access to the ARM7 as they desire. Or as little, if they choose to rely on the default OS ARM7 modules.

Thing is, I don't think it's good to, for example, always load an MP3 decoder or any other set module into the ARM7. One might be working on a homebrew app that does not make use of sound, or at least MP3s, in any major way. In which case loadng an MP3 decoder, or any other unused modules onto the ARM7 would be wasteful...

You're right, there's no need to have ARM7 the modules loaded at all times. It'd be nice, though, if they were separate from the program itself, so another program can load one up and use it without having to run the first program. For example, you might make a JPEG-decoding module to go with an image viewer, and then a web browser could load and use this module without the image viewer running.
_________________
I'm a PSP hacker now, but I still <3 DS.

#111780 - Inopia - Sun Dec 10, 2006 12:55 am

I thought PS2's were used for missles?

Anyway, I wouldn't care too much about direct ARM7 support. We can sit around and dream up millions of features and sketch ideal situations, but in the end it's all about feasability.

Something like prex is easy to port because the GBA port is there, relatively little work is needed to get it to run on DS. We can work from there. I suppose a device driver for the ARM7, where you can upload code and call them from the ARM9 would be one simple enough solution, although crude.

Porting RTEMS looks like a whole lot more work to me. It looks like a good OS because it supports multiprocessors, but I don't know if it has a no-mmu mode. I wonder if the extra effort is worth it.

I vote for simplicity. In that respect, PREX is still my favorite. Any other suggestions?

#111793 - Darkflame - Sun Dec 10, 2006 6:23 am

Quote:
I thought PS2's were used for missles?


Yes,but they couldnt do real-time weapon change ;)
_________________
Darkflames Reviews --
Make your own at;
Rateoholic:Reviews for anything, by anyone.

#111799 - OOPMan - Sun Dec 10, 2006 8:58 am

Inopia wrote:
I thought PS2's were used for missles?

Anyway, I wouldn't care too much about direct ARM7 support. We can sit around and dream up millions of features and sketch ideal situations, but in the end it's all about feasability.

Something like prex is easy to port because the GBA port is there, relatively little work is needed to get it to run on DS. We can work from there. I suppose a device driver for the ARM7, where you can upload code and call them from the ARM9 would be one simple enough solution, although crude.

Porting RTEMS looks like a whole lot more work to me. It looks like a good OS because it supports multiprocessors, but I don't know if it has a no-mmu mode. I wonder if the extra effort is worth it.

I vote for simplicity. In that respect, PREX is still my favorite. Any other suggestions?


As I see it, since both OSes support the ARM architecture and both lack the necessary device drivers, etc for the various DS-specific elements we need access to, they're both in largely the same category when it comes to ease-of-portability.

I don't think jury-rigging GBA PREX to run on the DS would be a good thing. It's designed with ARM7 GBA in mind, not ARM9 + ARM 7 DS.

To be honest, none of these OS'es make me entirely happy, at a glance. They all provide a lot of features, et al, but quite possibly they provide too many features. Things we don't need, or want, will be there regardless, which is a pain.

Also, as I see it, the key problem with developing on OS for DS homebrew could be illustrated by the case of DSLinux. DSLinux is a great OS for the DS. It has a great featureset and it works well, thanks to the hard work put in by many of the DSL people. However, we haven't seen hordes of bare-metal homebrew developers jumping ship to go and write their software on DSLinux. As I see it, this is a result of the fact that coding for DSLinux is more like coding for Linux than like coding for the DS. Hence, most current homebrew programs can not simply be modified slightly and recompiled to run under DSLinux.

This is what worries me about trying to port and existing OS like PREX or RTEMs. It's quite possible that we'd end up in a similar situation, with an OS that works great, but no actual support from homebrew developers who aren't very keen on re-writing their applications extensively to function with the OSes framework.

In this context, a lightweight custom OS might, in fact, be a better idea, if it allowed for as little monkeying with existing code to get said code working within the OS as possible. Of course, the flip side of all that is that it might end up being a very hack-ish system to work within.

Any thoughts on this people?
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#111830 - Inopia - Sun Dec 10, 2006 8:12 pm

I refuse to leave my position about PREX :) I think it's absolutely cute and tiny. I don't see too many useless features, really. The thing I think is very important in choosing something to port is memory usage. I don't know how well DSLinux fares in that department, but I like that 25k statement.

But back on topic, I do think you have a very good point there, oop. Maybe we shouldn't focus our efforts into porting an os, but maybe we should look into making development for DSLinux easier. I am thinking about tutorials, drivers, graphics shiz etc. Maybe we should focus on getting a tiny X server working? When we have a tiny x, we can start looking for a tiny gui toolkit (gtk is probably a bit too bloated:)

Whatever we do, I agree with oop on the acceptance issue.

#111844 - OOPMan - Sun Dec 10, 2006 10:25 pm

Erm, it's not that DSLinux development is difficult. DSLinux development is pretty much like development for Linux anywhere, just in a resource constrained environment...

See, part of the problem with porting a pre-existing OS geared towards existing embedded systems is that the DS is not quite like the majority of embedded systems such OSes usually run on...

For example, unlike most embedded systems the DS has:

  • Two screens. One is more normal. Hell, a lot of embedded systems don't even have any screens...
  • Touch display. A bit more common I think, but still not ultra-common
  • 2D and 3D graphics hardware. Not common at all.
  • Sound hardware. Not ultra-common either.
  • Two processors in an asymetric configuration


Now, if I have made any glaringingly erroneous statements there, please let me know, since I can not claim to be an expert in embedded system.

At a glance, however, the above list is part of the reason why porting an existing OS, even a good one, might never give us the kind of development flexibility we require.

PREX does look nice in many ways, but the lack of multi-processor support is not something that could really just be hacked around. Hacks are usually ugly and can break things in the long run.

*sigh*

There are so many sides to all, this though. I mean, writing a 100% custom OS would involve re-inventing the wheel, even if only on a small scale. However, the results could be good and doing so would probably allow for maximum integration with existing homebrew...

Possibly it's a pipe dream, but I really do think that a situation in which any homebrew apps that want to run under the OS need to be drastically modified at the source level is a situation to avoid. In essence, the OS should be virtually invisible to the app running on top of it...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#111851 - Inopia - Sun Dec 10, 2006 11:59 pm

I don't question the fact that a custom OS would be better, I just don't think it would be worth it.

#111858 - Lynx - Mon Dec 11, 2006 2:19 am

Is the topic still about dynamically loading and executing code?

Wouldn't the ideal solution be part of DevKitPro and it do all the work for us? I mean, if your going to require an OS to be running, then just use DSLinux and your done.. But I think most people would like it to be part of their NDS Game/App, not require an OS to do the work.

Again, did I miss something or did this topic head way off into left field?
_________________
NDS Homebrew Roms & Reviews

#111866 - tepples - Mon Dec 11, 2006 3:57 am

Lynx wrote:
Is the topic still about dynamically loading and executing code?

Almost, because any robust solution for loading modules would quickly become an operating system.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#111869 - HyperHacker - Mon Dec 11, 2006 4:19 am

What's with DS coders being afraid to do any actual work? Ports this, hacks that. No port is going to work as well as a new OS built from the ground up with the DS in mind, and trying to work with one is going to be a pain. DSLinux isn't unpopular because people don't want to write programs for it; it's unpopular because it's difficult to use. Using a command line on a touch screen with a 4x6 font is a pain in the butt, and being a port means it's still far from completion because it's a port of something not at all suited to the DS.

Of course we can take ideas/code from existing programs or even base something off them; no sense re-inventing the wheel. But I think writing a new OS specifically for the DS is the way to go.

Also, while the idea of allowing existing programs to run with few changes is appealing, I think it'd signifigantly hurt useability. These programs all expect to be able to do whatever they want because nothing else will be running. How do you plan to manage several different programs running at once that all want the display hardware set up a specific way and want to use the entire screen? If we drop this idea (not like people can't still run these apps separate from the OS) we can easily manage the graphic resources by giving each program, for example, a 256x182 buffer to draw on and drawing the focussed one on the screen leaving 10 pixels for a taskbar or similar.
_________________
I'm a PSP hacker now, but I still <3 DS.

#111873 - OOPMan - Mon Dec 11, 2006 8:58 am

Your third paragraph sums up my the flip side of getting stuff to run with as few changes as possible quite nicely HyperHacker :-)

While I do think it would be nice if existing stuff could be ported with as little trouble as possible, I also realise that it's not likely to be a clean solution.

With regards to screen usage, I personally would rather see each app allowed full screen area, while allowing the usage of an "Arcane Key Combo (TM)" to bring up the OS's interface for task management, etc...

Hmmmmmmmm, as long as coding for this hypothetical OS were largely as straight forward as coding bare-metal under devkitPro, I think it would probably seem some support.

What would people really like to see in a DS OS?
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#111893 - Inopia - Mon Dec 11, 2006 1:42 pm

I agree with hyperhacker on the second issue, wich should be very doable. I do however disagree on the first subject. I think writing something from the ground up is way too ambitious. If you want to do it, you have my blessing, but personally I won't wait around for it.

#111894 - OOPMan - Mon Dec 11, 2006 3:15 pm

Maybe not as ambitious as you think, Inopia...

While writing an OS is no light task, the fact that it would be written for a fixed platform would ease certain difficulties (HW config worries). Similarly, the aim of keeping things relatively minimal and modular would reduce the workload somewhat and allow it to be approached in a more organised fashion...

At least, that's what I'm guessing :-)

I think the key element of this OS for the DS would be the framework for loading, managing and executing modular code. Numerous other OS elements would slot into that framework as ordinary modules or, possibly, as priviledged modules. Come to think of it, though, that sounds rather obvious...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#111941 - Ollie - Tue Dec 12, 2006 12:07 am

Well, i've not got a DS yet and won't have one for a few weeks yet.

Still, as far as i can tell everyones being one extreme or the other. Some are saying that a new OS is too ambitious and shouldn't be waited for, others say it is something we could try to do - with various multi-tasking and blah blah.

I'm not an expert whatsoever, so correct me if i'm wrong but as far as i understand.. Everything starts somewhere.

Theres no way that people will just sit there, plan an OS for the DS with full features... and code it. Well i tell a lie, there ARE ways to do so if your REALLY dedicated and commited. But it'd take a fair amount.

I was thinking, that SURELY it'd be better to start small and work up. Yes "starting small" would probably make the system inflexible for later upgrading with new features. So this means a re-write, well actually thats great! Yes it means effort, boo hoo, it'd still mean the "OS" was steadily growing.

I was thinking, wouldn't it be feasible to begin with, to just have some kind of basic file system or something with each "file" just being plain old DS commands, no OS API stuff. Now imagine loading up the "OS" and seeing a scrolling menu of icons. You scroll to your application, double tap it... it loads. It takes the file and loads a command and the next (XYZ) commands after it into some pre-determined execution section of memory. It keeps executing memory and loading commands from the file the program is stored it.

Sure it'd only run one program at a time, but it'd be capable of running a program. So far what i've described is identical to media devices like GBAMP or whatever (i think), which is not quite what i had in mind. So to clarrify, you'd have an escape code that exited the current program and returned to the OS without restarting the GBA.

Your probably all thinking "Well fat lot of good that is", well your probably right. But it's a start. If you think about what that actually involes, your probably looking at an FAT file system, a system for loading code into some memory for execution, executing it, periodically loading the next chunks of code from the filesystem into the execution memory - whilst continually checking for the escape sequence to return to an application.

I've rambled on about this for far too long, and it probably isn't very sensible, but i'm afraid i've never homebrewed - i only program C++ on the computer. I'm just speaking using what i can understand as a normal developer. I hope i haven't wasted your time with you reading this, but i thought it was a useful opinion worth contributing! ^_^

#111943 - HyperHacker - Tue Dec 12, 2006 12:17 am

OOPMan wrote:
What would people really like to see in a DS OS?

Multitasking and a nice consistent API for things like drawing and working the hardware. I think using OS functions instead of directly accessing the hardware registers would be better in this case, as it helps ensure programs don't mess eachother up and allows for a sort of wrapper that could help make things easier to code. (For example, the OS would already have routines to draw simple shapes and GUI elements, and grabbing input from the microphone could be as simple as OS_ReadMic(BitRate, Buffer, BufferLength) or something along those lines.)

Since the DS is a fixed system and we wouldn't be expecting a lot of features, I don't think it'd be as much work as people seem to think. I'd start working on it now, actually, but I've already got 4954379 projects on the go and don't know near enough about relocatable code/modules to actually implement the whole loading programs from disk part. If someone does that, though, I'd be glad to pitch in designing and implementing the API.

One interesting issue that comes to mind is security. The lack of an MMU makes it difficult to implement memory protection (any program could read/write any part of memory, muck with hardware registers, turn the system off etc), and on the DS this may not be a big problem anyway. Though I wonder if the MPU could be used for this? Or would that be too slow/difficult to be feasible?
_________________
I'm a PSP hacker now, but I still <3 DS.

#111957 - Lynx - Tue Dec 12, 2006 1:18 am

So, commercial DS games have an OS? Maybe I'm clueless, but don't commercial DS games do what we "want"? Or maybe what everyone else wants, isn't what I'd want..
_________________
NDS Homebrew Roms & Reviews

#111963 - DekuTree64 - Tue Dec 12, 2006 2:08 am

Lynx wrote:
So, commercial DS games have an OS? Maybe I'm clueless, but don't commercial DS games do what we "want"? Or maybe what everyone else wants, isn't what I'd want..

Commercial games have a bunch of library code that they have to use (which includes support for loading overlays), but no dynamic relocation of code.

I think what OOPMan originally wanted is a simple DLL loader. Nothing to do with memory management, nothing to do with multitasking, just a library to load in an ELF file to a given address and allow you to call functions in it.

Unfortunately I have no experience writing dynamic linkers so I don't know how difficult that would be to write. But if the ELF format can give you the info to relocate a block of position-independent code, it really doesn't seem that difficult.

That said, the only thing it would really accomplish is saving memory on code that's not currently in use. While this would actually be useful in most commercial games I've worked on, there aren't many homebrew projects out there that are large enough to have a significant amount of code not being used at a given time.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#111989 - OOPMan - Tue Dec 12, 2006 9:18 am

Hmmmm, some pretty cool new posts...

Ollie: I do understand the key point of what you're saying, which is start small and build things up. However, I don't think doing so in a fashion that would require the OS to be re-written from the ground up every time a significant new feature is added would be a good way to go. Also, I think talk of menus, etc are rather premature and don't actually have much to do with the OS itself at all. These are shell-related topics that would be dealt with when the OS's shell was developed.

Hyperhacker: Nice points. I also think multi-tasking would be an important feature. Multi-threading would also be an important feature to consider in an environment that supports multi-tasking.

The API idea is also good. After all, relying on 100% direct hardware access when an OS and possibly other apps are running in the background would probably lead to trouble (Conflicts over HW resources, etc...). Whatever the API might be, however, I don't think it should be high-level. A high-level API would likely slow things down a lot, which is not good. In other words, the API should try to remain as simple as possible. It should not be much more difficult to write programs under the OS than it is under DKP. Keeping this in mind, abstract functions to handle drawing are not really something I would put on the table. Providing clear access to the HW, even in an abstracted fashion, would be better. In other words, think SDL, rather than Allegro, design-wise...

Memory management is an issue I myself was wondering about. For example, I had the idea that when a program under the OS is ready for release it's compiled with a spec about the min/max memory space it needs to run in. That way, when the OS loads code it could pre-allocate software all the memory it needs to work in from the get-go. One a PC or other large machine this would be wasteful, but on the DS it might help to ensure that programs don't violate each other's memory, etc. However, whether such an idea is even do-able without an MMU is something I don't know. I do know that DSLinux faces similar issues and at the moment exists with no real memory protection system.

Thinking about it, the memory alloction idea above *might* work if all the memory allocation functions, etc, went via the OS. That way the OS could ensure that when a program requests memory it gets memory allocated from within it's designated "block" and is unable to request more memory than is in the block. Still, it wouldn't do anything about the simple fact thatb a program could use pointers to completely fry any and all of the memory...

Hmmmmmm...

Deku: While the topic was originally following the subject of writing something very similar to a DLL loader it has kind of spread out from there. Tepples pointed out that in order to ensure the loader functioned correctly and well a lot of additional memory mangement functions, etc would need to be implemented anyway and that doing so would, in essence, involve a lot of work analogous to the development of an actual OS. So, yah, we kind of moved on to discussing the development of a homebrew OS from there :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#112012 - HyperHacker - Tue Dec 12, 2006 1:23 pm

N64 games used a simple OS AFAIK, so I imagine DS games would too.

Your memory management idea might help to stop memory fragmentation if nothing else. The DS does have a memory protection unit that can trigger exceptions when certain memory ranges are accessed, so it's more a question of whether switching protected ranges every time you switch threads and enter/exit userspace.

An SDL-like graphics system is the idea I was going for, but there's not much reason not to throw in some simple routines for drawing/filling simple shapes and drawing common GUI elements. This could go well with the ARM7 kernel modules idea (though this might be better done on ARM9 since it's faster); if a program needs advanced drawing routines it can just load the appropriate module, and then it's not taking up memory when not in use.
_________________
I'm a PSP hacker now, but I still <3 DS.

#112025 - Ollie - Tue Dec 12, 2006 4:07 pm

Yeah OOPMan, the use of an interface was basically just a visualisation of the simplest interface that could be started with. As opposed to a command-line-interface. If it was command line, starting a program would be "guess the exact filename of the program you want to run, no that's wrong, keep trying..."

DSLinux probably suffers from this, although i haven't tried it yet. I hope to as soon as i get a DS and the homebrew stuff >:]

Also OOPMan, i suppose recoding it wouldn't be a "great" thing, but it would give the opportunity to iron out the code and keep it neat, because you'll have a known knowledge of how to achieve something because you've already achieved it once before. So you could use the old code to look at, giving you something to base off of and make it neat. Etc etc...

As i've been told, if you love your code, re-write it :P

#112028 - OOPMan - Tue Dec 12, 2006 5:04 pm

Ollie: Thing is, the shell is not really a core element of the OS, unless you're going to approach things from a Windows angle of "Integrate your shell/GUI into you kernel", which is a mixed bag.

Like I said, the whole shell thing is secondary. The OS comes first, the shell is basically just an app that runs within the OS to ease the user experience. While this may not be the case with Windows, I think it would be good if this were the case with a homebrew DS OS.

The point you make about re-coding does have some validity. Hopefully, however, by keeping the individual OS components as simple and light-weight as possible, extensive recoding would be less necessary.

HyperHacker: Was the N64 OS an actual OS? I never owned an N64 (Or any console prior to the DS in fact :-) so I don't know. Did it remain running in the background while the N64 game executed?

The memory organisation idea is based somewhat on some stuff wrt to virtual memory that we handled in CSC last year. Of course, keeping in mind that virtual memory is not possible on the DS, this is why the idea may have some flaws.

The MPU sounds like it could be useful though :-)

With regards to the graphics system, etc, things are a bit mixed. As I said above, I don't think any graphics routines stuff you be linked in at the core kernel level. The OS should provide clear access to as much of the HW as safely possible though, so it would be possible for a basic drawing module to be loaded for use by other applications, like you said.

From where I'm sitting it looks like the ideal homebrew DS OS would be built as either a micro-kernel or an exo-kernel/nano-kernel.

I personally think that an exo-kernel style system would be more interesting to work with and would have the added benefit of allowing more direct HW access than most other options. I'm probably going to take a look at L4 to get a better idea of how well this would work...

There is a downside to these approaches though, in that micro-kernels and the like can be a bit system intensive, which would not be good on the DS...

Thoughts, anyone?
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#112036 - Mighty Max - Tue Dec 12, 2006 6:38 pm

OOPMan wrote:

The memory organisation idea is based somewhat on some stuff wrt to virtual memory that we handled in CSC last year. Of course, keeping in mind that virtual memory is not possible on the DS, this is why the idea may have some flaws.

The MPU sounds like it could be useful though :-)


Why do ppl still think it is impossible?

Partition the 4MB into blocks. A user process only has access to its code, and some of the data blocks by the MPU regions. Whenever a data abort due to region miss happens, retrieve the address of the data accessed.

With that address check whether this data is still in the 4MB main ram, and change a region to allow access to that range of data. Or, if the memory was used otherwise (like beeing used for the mirror) inbetween swap the blocks content with your blockdevice (i.e. m3 ram or cfcard etc)

With the main ram mirroring every 4MB, you can reuse one pysical memory range at the different mirrors of this:

The block at 0x02000000 and the one at 0x02400000 i.e. can be used to address two completely different datasets, even if they point at the same physical memory we can seperate their access. We can just not access both at the very same time. For these accesses that alternate between such related regions some kind of caching would be required (instead of doing slow cf card accesses on every read/write) but thats very doable.

This way each process can address 16MB (4 mirrors of 4MB main ram) of virtual memory. And a different process might get an own set of these pages ...

And its not much slower to access these virtual pages when you only have to switch(which is indeed slow) pages every 64/128/256 or more kB
_________________
GBAMP Multiboot

#112045 - OOPMan - Tue Dec 12, 2006 8:32 pm

Hmmmm, that sounds pretty interesting Max...

Just to check and see if I've gotten the right end of the stick...

You're suggesting that we use the additional memory provided by certain cards to provide software with access to a seemingly contigious block of memory, much the same as DSLinux does, right?

If what you're talking about is the above, then yes, it's very much doable, as has been demonstrated by DSLinux's ability to provide 36mb of addressable memory at once.

However, actual virtual memory that makes use of paging to and from a much slower form of media (Such as an HDD or the media inserted into a media adapyer) to provide the illusion of near limitless memory (Barring overheads, of course) is, I believe, still not possible specifically due to the lack of an MMU. DSLinux has been unable to implement true virtual memory for this reason. In fact, the closest anyone has come is, if I recall the post on the DSL forums, developing a software emulation of an MMU that did provide the requisite functionality. As you can guess, however, this solution proved unusably slow by a few orders of magnitude.

Is a large contigious memory area possible, provided a device toting extra RAM is plugged into slot-2? Yes, we know this already.

Is true virtual memory possible? Not as far as I know. This is, unless I'm completely wrong, an actual hardware limitation that we can do nothing about.

Anyone else want to back me up on this?
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#112050 - Mighty Max - Tue Dec 12, 2006 9:23 pm

OOPMan wrote:

Is a large contigious memory area possible, provided a device toting extra RAM is plugged into slot-2? Yes, we know this already.

Is true virtual memory possible? Not as far as I know. This is, unless I'm completely wrong, an actual hardware limitation that we can do nothing about.


I think you misunderstood my explanation, so a bit more visual:
[Images not permitted - Click here to view it]

It really doesnt matter where the pages are stored when a page has to replaced for accessing the main ram through a mirror (and tho addressing a different page at the same physical address)

So you have a 16MB virtual address space pointing to a managed 4MB of physical memory.

When i got some time i can do a techdemo to show you this is possible on the gbamp which has no extra ram. The thing i mentioned the extra ram of m3 was just that copying ram<->ram is much faster the cf<->ram


:edit: Actually i allready made a techdemo on the gbamp to create a virtual ramspace in gba addressspace, but this was by manually relocating access instead of abusing the "natural" relocation by the ram mirrors. You can find the source here: http://mightymax.org/paging.zip
_________________
GBAMP Multiboot


Last edited by Mighty Max on Tue Dec 12, 2006 9:42 pm; edited 2 times in total

#112054 - OOPMan - Tue Dec 12, 2006 9:36 pm

I would very much like to see a tech demo of this Max, as it sounds really interesting and cool if it does indeed work...

I wondered myself whether or not I might be mis-understanding you somewhat and it looks like this was the case :-)

Anyway, hopefully you will be able to provide a tech demo, as I think it would be a very cool thing to see in action...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#112056 - simonjhall - Tue Dec 12, 2006 9:37 pm

@Max:
I did this very same thing on my gbamp to do memory-mapped files. It was slow as ants! And even without the actual file access bit.

With regular virtual memory, when you get a fault you copy a chunk of data into your real memory and then map that whole chunk into the memory space. That way when you access that address again it just works. If you use this trapping out-of-bounds exceptions method every time you access that address it'll cause a fault - unless you change all pointers to point at this new memory location (which isn't feasible).

There are other ways of doing it however where you can treat the local memory like a cache, but they're not tremendously fast either. They do avoid incurring an overhead every time that you access some fancy memory though - although there is a penalty when you first access that address.
_________________
Big thanks to everyone who donated for Quake2

#112057 - OOPMan - Tue Dec 12, 2006 9:51 pm

Hmmmm, thanks for that simon. Clears things up even more...

On the subject of memory, I do not think that the hypothetical DS OS should rely on the user being a SC/M3/G6 user and hence having access to an additional 32mb of memory.

While I can understand why this was necessary with DSLinux (Given it's Linux roots, etc, a lot of the apps and the OS itself carry a rather large memory footprint by our standards) I think it would be better, performance wise and efficiency wise to code said hypothetical DS OS on the basis that the system only has 4mb of physical RAM to work with.

The reasons for this are varied. For a start, most existing homebrew apps are fairly small, in terms of actual memory space used (The exception being those unpleasant apps that use GBFS and similar injected filesystems). Hence, having access to 36mb of RAM is not quite as vital.

Coding the OS with only 4mb of memory in mind would also allow to to be used on a wider range of devices, including the various slot-1 devices out there (This could actually greatly increase the compatibility of slot-1 devices with homebrew if the OS, in some way or other, abstracted the existence of the slot-1/slot-2 device).

Efficiency-wise, I think it would be a good thing as well. For a start, the additional RAM provided by the SC/M3/G6 is slower to access and allowing the OS to access the memory in a fashion contigious with the 4mb of main RAM would require the 8-bit write problem to be addressed in much the same fashion as DSLinux did (Toolchain modifications, general but unavoidable performance hit to all memory as a result of mod). Also, having less memory space to work in would encourage the OS developers and people developing apps for the OS to code their software as modular and efficiently as possible in terms of memory-usage, etc. There is such a thing as too much of a good thing :-)

If needs be a plugin module to provide some form of access to the additional RAM could be written as well, allowing something of the best of both worlds, one hopes. (Although this might prove a pipe dream...)

Anyway, just some tangent thoughts, since we were chatting about memory :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#112062 - Mighty Max - Tue Dec 12, 2006 10:17 pm

simonjhall wrote:
@Max:
I did this very same thing on my gbamp to do memory-mapped files. It was slow as ants! And even without the actual file access bit.

With regular virtual memory, when you get a fault you copy a chunk of data into your real memory and then map that whole chunk into the memory space. That way when you access that address again it just works. If you use this trapping out-of-bounds exceptions method every time you access that address it'll cause a fault - unless you change all pointers to point at this new memory location (which isn't feasible).


Yes, thats why i approched it this time as pages which are in the mirrors, another access to that page will not again cause the swapping, until one of it other mirrors was accessed. This removes the handling to once in a page, instead of ones per access like i did before.

Lets make an example, i use 512kBpages. Over all 4 mirrors of wram. When i access a non present page the first time at 0x02600000, the wram at 0x02200000, is saved, and the data that should be at 0x02600000 gets loaded to the physical address 0x02200000, the region of the stored mem is changed for the new address. The next access to 0x02600004 will not cause an exception, therefor no slowdown will happen.

Due to the mirroreffect will map 0x02600004 to 0x02200004 where the data actually is, without the need of more software actions. Until one of the other 3 mirrors is accessed again.

If you have 1 region to allow all access for priviledged mode to every memory space, you got 7 regions left to access 7*512 = 3.5MB simultaneous without needing to doing any of the swapping, while you can use the longest since requested region when the next swapping needs to be done.
_________________
GBAMP Multiboot

#112067 - simonjhall - Tue Dec 12, 2006 10:34 pm

Oh my god that is so crafty! I see now - nice!
If you tell the MPU to protect a certain part of memory, is that memory protected in all mirrored versions, or just the one?
_________________
Big thanks to everyone who donated for Quake2

#112068 - Mighty Max - Tue Dec 12, 2006 10:36 pm

In just one, it handles the mirrors as it would be an own ram. Thats the way how you can seperate between allowed and disallowed accesses to the same physical ram
_________________
GBAMP Multiboot

#112075 - HyperHacker - Wed Dec 13, 2006 12:17 am

As far as GBA-slot memory, ideally the OS would make this transparent much like DSLinux. However I think the 8-bit write problem would make this either too slow or too difficult to be feasible. Perhaps the OS offers a special version of malloc() that uses GBA-slot memory if available and falls back to main RAM otherwise. Programs can then use this and assume the allocated buffer is in GBA ROM (or even check the pointer to see), and avoid using 8-bit writes. Time-critical code and ports can continue using standard malloc() which will allocate from main RAM only.

OOPMan wrote:
Like I said, the whole shell thing is secondary. The OS comes first, the shell is basically just an app that runs within the OS to ease the user experience. While this may not be the case with Windows, I think it would be good if this were the case with a homebrew DS OS.

Kernel/shell separation is good but on a DS OS, chances are the shell is going to be running at all times, so integrating it with the kernel can give a speed boost which is important on such a low-power system.

Quote:
Was the N64 OS an actual OS? I never owned an N64 (Or any console prior to the DS in fact :-) so I don't know. Did it remain running in the background while the N64 game executed?

The N64 console only had a simple bootROM that loads 1MB from the cartridge, does a checksum on it, and executes it, and provides some exception handling routines. Turning it on without a cartridge only gave a blank screen. The "OS" if it can even be called that is built into each game and basically just provides multithreading, simple exception handling, and probably routines for things like playing sounds and displaying graphics. Some games used relocatable code extensively but I'm not sure the OS handled this.
_________________
I'm a PSP hacker now, but I still <3 DS.

#112106 - OOPMan - Wed Dec 13, 2006 8:41 am

HyperHacker wrote:
As far as GBA-slot memory, ideally the OS would make this transparent much like DSLinux. However I think the 8-bit write problem would make this either too slow or too difficult to be feasible. Perhaps the OS offers a special version of malloc() that uses GBA-slot memory if available and falls back to main RAM otherwise. Programs can then use this and assume the allocated buffer is in GBA ROM (or even check the pointer to see), and avoid using 8-bit writes. Time-critical code and ports can continue using standard malloc() which will allocate from main RAM only.


Interesting point. Do we have any idea what kind of a performance hit the 8-bit write solution used in DSLinux has? I know there is some loss, but I've not encountered any concrete info yet.

The custom malloc() is an interesting idea, though...

Anyone else have any thoughts on whether this would be a viable solution...

HyperHacker wrote:
Kernel/shell separation is good but on a DS OS, chances are the shell is going to be running at all times, so integrating it with the kernel can give a speed boost which is important on such a low-power system.


A good point, yes. Still, if a micro-kernel type OS was used, then it would probably be a bad thing nevertheless. Mach kinda illustrated that integrating too many things into a micro-kernel caused a big hit in performance.

Also, I'm just not sure it would be necessary to integrate if the OS was written properly and ran well. After all, if the shell is simply a program running on top of the OS, then ensuring that any program running on the OS is able to execute as effectively and efficiently as possible will, as a result, ensure the shell executes nicely as well...

If the shell was integrated into the kernel, it would probably pay dividends to make sure as much of it was unloadable as possible, especially if it was an intensive graphical shell.

Shell-wise, I'd be quite happy with something like the SC menu, although maybe with a few extras (Clock, brightness settings and so forth...).

HyperHacker wrote:
The N64 console only had a simple bootROM that loads 1MB from the cartridge, does a checksum on it, and executes it, and provides some exception handling routines. Turning it on without a cartridge only gave a blank screen. The "OS" if it can even be called that is built into each game and basically just provides multithreading, simple exception handling, and probably routines for things like playing sounds and displaying graphics. Some games used relocatable code extensively but I'm not sure the OS handled this.


Interesting. I did see mention on the Wikipedia that certain embedded OSes are actually statically linked into the programs they help run. It sounds like the N64 used this method :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#112116 - masscat - Wed Dec 13, 2006 11:43 am

OOPMan wrote:
HyperHacker wrote:
The N64 console only had a simple bootROM that loads 1MB from the cartridge, does a checksum on it, and executes it, and provides some exception handling routines. Turning it on without a cartridge only gave a blank screen. The "OS" if it can even be called that is built into each game and basically just provides multithreading, simple exception handling, and probably routines for things like playing sounds and displaying graphics. Some games used relocatable code extensively but I'm not sure the OS handled this.


Interesting. I did see mention on the Wikipedia that certain embedded OSes are actually statically linked into the programs they help run. It sounds like the N64 used this method :-)

Having the OS and application in a single binary (or single logical unit) means that it can be tested as a single unit. And, assuming there are no hardware changes, the application will always run as expected (neglecting bugs).
This approach is the best approach for products that have a fixed functionality and are not trying to provide general purpose computing platform.

If the OS and application are separated then testing becomes harder as making changes to one may break the other. This can become rather nasty with the OS (or dynamically linked library) supporting old interfaces for older applications and applications supporting different features depending on what OS version is running. Any desktop OS gives an example of this problem with applications breaking and the OS growing as it supports new and legacy features. Also different versions of the OS may have different resource requirements, therefore an app that ran under version 1.0 of the OS may not run under version 2.0 as the OS has used more memory (a real problem on the DS).
If you want to load a number of random applications at the same time then you have little choice but to keep the apps and OS separate.

#112175 - sasq - Thu Dec 14, 2006 12:32 am

Seems like it would work - allthough it's not ideal since every access that goes to a different page has to trigger an exception and execution of code to figure out which page was accessed and to see if it is valid (Since the limited number of protection areas means you need to move around one (or maybe a few) small RW area(s) on top of a large area with no access).

But for linear accesses it shouldn't be too slow.

#112221 - Mighty Max - Thu Dec 14, 2006 3:05 pm

Less talking, more acting ;)


I've started to implement some of the things we needed, here is the overall setup im using, maybe someone has some corrections or addons to the setup.

1. I've done a very simple cooperative multitasking, to seperate priviledged routines from user mode routines.

2. All system (system mode) calls use one of the undefined instructions (we cant use swi) with r0 set as the function value, r1-r3 as parameters. Currently i got the following system calls implemented:
- SYSCALL_IDLE - no param, will switch to the next thread
- SYSCALL_CREATETHREAD(entryPoint,stacksize,passed param) - will create a USR mode thread
- SYSCALL_EXITTHREAD(retval) - will release thread from shedule and switch to next thread
- SYSCALL_MALLOC,SYSCALL_FREE - threadsafe mallocs/frees of pageable memory pool

3. Memory-Regions:
- Priviledged (only the system thread) can access every memory. It does not trap an exception when accessing a blended out page, therefor has to make sure that the data is available before accessing it
- Usermode can only access 6x512kB regions in the mainram, when accessing something else, the memory-blender is triggered. Access to HW registers and VRAM is (atm) allowed for R/W
= 8 Regions (full Regionsset)

4. ThreadManagement Memory: after the systemn init, a huge amount of the TCM is free (not used as stack anymore). This memory is used as a non-paged memory pool for threadcontext and threadlist storages. It can only accessed by the system thread, and will never be swapped out.


Got to do the paged memory pool checks now (IsPagePresent,StorePage,RestorePage, UpdateRegionsForPage).

Problems i encountered yet: Due to the special purpose memory locations, the wram is allready fragmented (as this memory is preserved in all mirrors). Some space is to be reserved to be non paged in mainram too (currently first 512kB) because the system mode code has to be present at any time.
_________________
GBAMP Multiboot

#112223 - OOPMan - Thu Dec 14, 2006 3:39 pm

Hmmmmm, looks pretty good Max...

Are you planning to move the co-op multi-tasking to pre-emptive at any point?

Any thoughts on what you're going to do about IPC and the DS's two processors?

What about the code? Mostly assembler or mostly C, so far?

So far it's looking pretty micro-kernel-ish, just lacking the IPC stuff yet :-)

Anyway, nice to see that someone is actually putting some code in place :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#112224 - OOPMan - Thu Dec 14, 2006 3:50 pm

On a bit of a tangent, but still OS related. I grabbed L4::Pistachio Embedded and took a brief look at it. They do, indeed, seem to have support for the ARM architecture, but all of the existing ports seem to be for ARMs with a MMU. I've emailed the project's porting officer to get his opinion on how viable L4 would be on the NDS, given that we lack an MMU.

Anyway, if I get a reply, I'll post it, assuming there's anything interesting in it :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#112225 - Mighty Max - Thu Dec 14, 2006 3:52 pm

OOPMan wrote:
Hmmmmm, looks pretty good Max...

Are you planning to move the co-op multi-tasking to pre-emptive at any point?


Yes i am, but thats something at the end of the ptriority list. The plan is to have syscall check if it was called from within a IRQ and set the return point and register values from the irq stack data. However the current irq dispatcher of ndslib isn't compatible to that.

Quote:

Any thoughts on what you're going to do about IPC and the DS's two processors?


The base of the code im currently using was intended as the solution for the MPIlib problem i posted about. the arm7 will however not be able to do the virtual memory trick.

Quote:

What about the code? Mostly assembler or mostly C, so far?

Mostly C, beside cp15 interaction and exception dispatcher.
_________________
GBAMP Multiboot

#112228 - masscat - Thu Dec 14, 2006 4:12 pm

Mighty Max wrote:
2. All system (system mode) calls use one of the undefined instructions (we cant use swi) with r0 set as the function value, r1-r3 as parameters. Currently i got the following system calls implemented:
- SYSCALL_IDLE - no param, will switch to the next thread
- SYSCALL_CREATETHREAD(entryPoint,stacksize,passed param) - will create a USR mode thread
- SYSCALL_EXITTHREAD(retval) - will release thread from shedule and switch to next thread
- SYSCALL_MALLOC,SYSCALL_FREE - threadsafe mallocs/frees of pageable memory pool

Can you not use SWI if you set up your own exception vectors at memory 0x0000000 (i.e. in the ITCM) and set the ARM to use the low vectors. You would have to pass any Nintendo used values to the Nintendo code though.

#112229 - Mighty Max - Thu Dec 14, 2006 4:48 pm

I was thinking on using itcm for a different purpose.

(To lay it over the non-moveable memory space when accessing the mirrors of them. i.e. over the accessed mirror where i.e. the bios stack for exceptions is, so i got a continous memory at least over the mirrors)

But i got to think about this solution some more.
_________________
GBAMP Multiboot

#112252 - masscat - Thu Dec 14, 2006 10:21 pm

The ITCM address is fixed at 0x00000000. The result of writing values other than 0x00000 as the region base are unpredictable according to the ARM946E-S tech ref manual.
The DTCM region base can be set to whatever you like.

#112254 - Ant6n - Thu Dec 14, 2006 10:31 pm

I wonder what programs would one run in a DS. My wild guess is that there are pda-like things on one hand and games on the other. For the first kind possible slowdowns due to virtual memory tricks shouldnt be that much of an issue, for the 2nd kind everything should go as fast and big as possible. But how many other programs should actively run in the background when you are running a game? I think, none.
As far as I can see, when you have an OS on the DS, it would make sense to have a card with memory to be actually able to run multiple programs from.
So what I am suggesting is to create two modes that software can run in; one that shares resources and memory with other programs and is not necessarily as fast, but multiple programs can do something at the same time and might even share the screen in some fashion; and another that forces all the other programs to be stored on drive/external ram, pauses all thier processes, gives access to all (almost) memory and all the resources. When the 'game' terminates, all the little programs are loaded back and come back to live.

#112265 - Mighty Max - Thu Dec 14, 2006 10:58 pm

masscat wrote:
The ITCM address is fixed at 0x00000000. The result of writing values other than 0x00000 as the region base are unpredictable according to the ARM946E-S tech ref manual.
The DTCM region base can be set to whatever you like.


Oh, havent seen that paragraph.

Got to check some things, afaik devkitPro sets ITCM to 0x01000000 in crt0 and ndslib stores irq dispatcher as well as irq table there. It seems to work. oO
Code:

Linker script and memory map
                0x01000000                __itcm_start = 0x1000000

...

 .itcm          0x01000000       0xc8 c:/devkitPro/libnds/lib\libnds9.a(interrupts.o)
                0x01000000                irqTable
 .itcm          0x010000c8       0xd8 c:/devkitPro/libnds/lib\libnds9.a(interruptDispatcher.o)
                0x010000c8                IntrMain

_________________
GBAMP Multiboot

#112272 - OOPMan - Thu Dec 14, 2006 11:15 pm

Ant6n wrote:
I wonder what programs would one run in a DS. My wild guess is that there are pda-like things on one hand and games on the other. For the first kind possible slowdowns due to virtual memory tricks shouldnt be that much of an issue, for the 2nd kind everything should go as fast and big as possible. But how many other programs should actively run in the background when you are running a game? I think, none.
As far as I can see, when you have an OS on the DS, it would make sense to have a card with memory to be actually able to run multiple programs from.
So what I am suggesting is to create two modes that software can run in; one that shares resources and memory with other programs and is not necessarily as fast, but multiple programs can do something at the same time and might even share the screen in some fashion; and another that forces all the other programs to be stored on drive/external ram, pauses all thier processes, gives access to all (almost) memory and all the resources. When the 'game' terminates, all the little programs are loaded back and come back to live.


It's user choice whether to run multiple apps at once or to run a single app at once. The OS should not place restrictions on how many apps can run, etc, as this is more a matter of common sense. The only restrictions that the OS should impose in this respect should be hardware restrictions (Eg, Refusing to load a new app if no memory is available, etc...)

I do not see screen sharing among multiple apps running at once (In other words, a window system with multiple running apps each getting their own window) as being a priority due to the small display size. A better bet would to allow task flipping between the "graphics" thread of each app.

Whatever the case may be, talk of things such as windowing systems, etc seems rather premature to me, and quite possibly not all that important really. If the OS itself ends up being poorly written (I'm not taking a dig at you Max, just in case it could be construed that I am :-) then a windowing system will not save it.

While I think it is far to early to really discuss much about things like GUI systems, etc, I do feel, in general, that a windowing system in the style of X.org or the MS-Windows manner, is not really very appropriate for the DS, taking into account the various HW limitations around. I feel that each app would obtain better peformance on the graphics side by recieving locked access to the GUI hardware. Applications that wish to run in the background (Music players, etc...) should be multi-thread so that the graphics run in a separate thread to whatever background processes occur.

But, like I said, it's a bit early for such grand talk...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#112284 - Ant6n - Fri Dec 15, 2006 12:13 am

i wasnt talking so much about windowing system as about how to share resources, because it seems that sharing memory etc and page flipping might slow things down a lot. That's why i say make it possible to have programs that pause everything and grant access to all resources and then you don't need to slow them down with stuff like virtual memory.
If one has an OS for the DS but can't run games because they run too slow in an emulated mmu, thatn this would defeat the purpose of an dsos

#112290 - GPFerror - Fri Dec 15, 2006 12:45 am

why not improve dslinux with some of the features that you have listed?

#112293 - tepples - Fri Dec 15, 2006 12:50 am

Ant6n wrote:
I wonder what programs would one run in a DS. My wild guess is that there are pda-like things on one hand and games on the other. For the first kind possible slowdowns due to virtual memory tricks shouldnt be that much of an issue, for the 2nd kind everything should go as fast and big as possible. But how many other programs should actively run in the background when you are running a game? I think, none.

What about a Vorbis player? Factoring that out into a separate process allows the menu .nds and the game .nds to use the same music code.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#112297 - masscat - Fri Dec 15, 2006 1:10 am

With regard to the ITCM location in the memory map:

From what I can remember of the start up code the size of the ITCM gets set to 32MBytes so that it gets mirrored to 0x01000000 (and many other places). The base is still at zero though. Not sure why it was done this way, maybe Nintendo did it and it just got copied.
Using the default MPU settings the region 0x00000000 to 0x00FFFFFF is not declared and therefore causes an exception if read or written. But if you do set up the MPU to cover it you get to see the ITCM happily sitting at 0x00000000.

#112303 - HyperHacker - Fri Dec 15, 2006 1:53 am

In terms of applications running simultaneously, I could see myself using the following all at once:
-Music player
-Notepad*
-Web browser, IRC, or text editor

*If the music player supports AAC+ streaming, then I'd be listening to my favourite station and copying the names of songs that I like into a text file so I can later seek them out and buy them. On Windows, I copy them from the station's web site which has a dynamic Now Playing box, as it's easier than copying from Winamp.
This brings up another point to consider much farther down the road - we'll need a clipboard.


As for the interface, I've shared my thoughts on this before, but since you probably don't all remember and I've made some minor improvements, here they are again.

Each screen would be put into 2D mode 5, with the layers divided up like so:
1 (lowest): Desktop background/icons and/or debug info like Moonshell.
2: Application graphics area.
3: Child windows.
4: Menus and keyboard.

Windowing/display:
Layer 2 is the primary application graphics area. No windows are used here. Each program can request zero to two displays which are up to 256x182 bitmaps stored in RAM. Each screen shows one display as well as a 256x10 status bar at the top which is used to choose which display is shown.
The status bar on the top screen shows the title of the top display and the current time and temperature. The status bar on the bottom screen shows the title of the bottom display and three buttons. The first button displays the system menu from which you can switch displays, open or close programs, shut down the system, etc. The second swaps screens - the top display is moved to the bottom and vice-versa so it can be touch. The status bars do not switch places (or else you'd have no way to switch back). The third toggles the keyboard.
Programs can create windows of any size that fits on the screen, which are displayed on layer 3. Due to limited resources this is best used for small or short-lived things like popup dialogs, floating tool boxes, etc. This works like Moonshell's windowing system, though ideally the title bars would be a bit smaller. Each window is bound to a specific display and appears only above that display.
Menus and the keyboard are drawn on layer 4. Programs' menu bars are displayed below the status bar.

I might draw a quick mockup later, but for now I've got to get going.
_________________
I'm a PSP hacker now, but I still <3 DS.

#112306 - Firon - Fri Dec 15, 2006 2:48 am

HyperHacker wrote:


*If the music player supports AAC+ streaming, then I'd be listening to my favourite station and copying the names of songs that I like into a text file so I can later seek them out and buy them.


Speaking of HE-AAC, I'm sure that can be done on the DS by compiling faad2 with low power SBR enabled (no parametric stereo in this mode, so you can't use DI.FM's 24k streams).
I don't know if the DS has enough power (at least without some optimization) to use SBR in normal mode, which would also allow PS.

#112353 - Mighty Max - Fri Dec 15, 2006 3:06 pm

Ok, changing it to ITCM is some work.

First implementation of the "new bios":

Code:
.arm

.global ITCM_Code
.global ITCM_End

// registers in FIQ we use to store pointer to currect threadcontext(tc) and the threadlistentry (tl)
tc .req r12
tl .req r11

// defines
.equ    MODE_SYS, 0x1F
.equ   MODE_USR, 0x10
.equ   MODE_FIQ, 0x11
.equ   MODE_IRQ, 0x12
.equ   MODE_SVC, 0x13
.equ   MODE_ABT, 0x17
.equ   MODE_UND, 0x1B

ITCM_Code:
   reset:
      B reset_code
   undefined:
      B undefined_code
   softwarei:
      B softwarei_code
   codeabort:
      B abort_code
   dataabort:
      B abort_code
      .word 0
   irq:
      B irq_code
   fiq:
      B fiq_code
      
   // address = 0x00000020
   swi_c_handler:
      .word      0
   // address = 0x00000024
   data_c_handler:
      .word      0
   
   reset_code:                  // no reset yet, halt system
      B reset_code
   
   undefined_code:
      B undefined_code         // no undefined instruction handler
            
   softwarei_code:               // swi:
      STMDB r13!,{r0-r12,r14}      //   store registers
      BL store_context         //   store thread context
      LDR r12,=0x00000020      
      LDR r12,[r12]            //   load irq_c_handler
      CMP r12,#0         
      MOVNE r14,r15            //   call it if it isnt 0
      BXNE r12
      BL restore_context         //   restore thread context
      LDMIA r13!,{r0-r12,r14}      //   restor registers
      MOVS r15,lr               //   return
      
   abort_code:                  
      B abort_code            // no data abort handler yet
      
   irq_code:
      SWI 0xFFFFFF            // we do irq handling in svc (so we can do taskswitches by irq)
      SUBS r15,r14,#4            //   return
      
   fiq_code:
      B fiq_code
      
//   The expected layout of threadcontext, it could be better. It was defined in respect to UND switches
//
//   typedef struct THREADCONTEXT {
//      unsigned long      bios_stack,
//                     bios_return,
//                     r11,r10,r9,r8,r7,r6,r5,r4,r3,r2,r1,r0,
//                     r13,r14,r15,
//                     r12,
//                     cpsr,
//                     cp15_status ;
//   } THREADCONTEXT, *LPTHREADCONTEXT ;      
      
   store_context:
      STMDB r13!,{r14}
      BL receive_threadcontext
      
      CMP r0,#0
      LDMEQIA r13!,{r14}
      BXEQ lr
      
      
      // bios stack & bios return is not to save anymore, as we dont use the old bios anymore
      ADD r0,r0,#8
      
      // store r11 - r0 in reverse order, the values are on stack
      LDR r1,[r13,#0x30]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x2C]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x28]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x24]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x20]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x1C]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x18]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x14]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x10]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x0C]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x08]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x04]
      STMIA r0!,{r1}
      
      // load previous mode r13,r14 and store them to [r0] and following
      MRS r3,spsr
      AND r2,r3,#0x1F
      CMP r2,#MODE_USR
      LDREQ r2,=MODE_SYS
      MRS r3,cpsr
      BIC r3,r3,#0x1F
      ORR r2,r2,r3
      MRS r3,cpsr
      MSR cpsr,r2
   
      STMIA r0!,{r13}
      STMIA r0!,{r14}
      
      MSR cpsr,r3
      
      // store return address as previous mode r15
      LDR r1,[r13,#0x38]
      STMIA r0!,{r1}
      // store r12
      LDR r1,[r13,#0x34]
      STMIA r0!,{r1}
      
      // store saved psr (CPSR of thread)
      MRS r1,spsr
      STMIA r0!,{r1}
      
      // cp15_status is ignored as we dont change it
      ADD r0,r0,#4
      
      LDMIA r13!,{r14}
      BX lr
   restore_context:
      STMDB r13!,{r14}
      BL receive_threadcontext
      
      CMP r0,#0
      LDMEQIA r13!,{r14}
      BXEQ lr
      
      // bios stack & bios return is not to save anymore, as we dont use the old bios anymore
      ADD r0,r0,#8

      // restore r11 - r0 from reverse order, the values are on stack
      LDMIA r0!,{r1}
      STR r1,[r13,#0x30]
      LDMIA r0!,{r1}
      STR r1,[r13,#0x2C]
      LDMIA r0!,{r1}
      STR r1,[r13,#0x28]
      LDMIA r0!,{r1}
      STR r1,[r13,#0x24]
      LDMIA r0!,{r1}
      STR r1,[r13,#0x20]
      LDMIA r0!,{r1}
      STR r1,[r13,#0x1C]
      LDMIA r0!,{r1}
      STR r1,[r13,#0x18]
      LDMIA r0!,{r1}
      STR r1,[r13,#0x14]
      LDMIA r0!,{r1}
      STR r1,[r13,#0x10]
      LDMIA r0!,{r1}
      STR r1,[r13,#0x0C]
      LDMIA r0!,{r1}
      STR r1,[r13,#0x08]
      LDMIA r0!,{r1}
      STR r1,[r13,#0x04]
      
      // set previous mode r13,r14 from [r0] and following
      
      // caution: we need to have a valid spsr before doing this!
      // spsr was stored 0x10 bytes later
      LDR r3,[r0,#0x10]
      AND r2,r3,#0x1F
      CMP r2,#MODE_USR
      LDREQ r2,=MODE_SYS
      MRS r3,cpsr
      BIC r3,r3,#0x1F
      ORR r2,r2,r3
      MRS r3,cpsr
      MSR cpsr,r2
   
      LDMIA r0!,{r13}
      LDMIA r0!,{r14}
      
      MSR cpsr,r3
      
      // restore return address as previous mode r15
      LDMIA r0!,{r1}
      STR r1,[r13,#0x38]
      // restore r12
      LDMIA r0!,{r1}
      STR r1,[r13,#0x34]
      
      // restore saved psr (CPSR of thread)
      LDMIA r0!,{r1}
      MSR spsr,r1
      
      // cp15_status is ignored as we dont change it
      ADD r0,r0,#4
      
      
      LDMIA r13!,{r14}
      BX lr ;
      
      
   // thread context/list ptrs are stored in a banked fiq register, which is persistent
   receive_threadcontext:
      MRS r1,CPSR
      BIC r0,r1,#0x1F
      ORR r0,r0,#MODE_FIQ
      MSR CPSR,r0
      MOV r0,tc
      MSR CPSR,r1
      BX lr
ITCM_End:


:edit: biggest bugs removed ;)

:edit^2:
Old featureset works again. .NDS file (does not run in dualis or desmume)

This ITCM trick (Thanks masscat) solves the problem with allready fractioned on startup memoryspace already. Don't need to cover the UND vector now *g*

Time to seperate loader code from servicing code now and store that outside WRAM.
_________________
GBAMP Multiboot

#112452 - Mighty Max - Sat Dec 16, 2006 3:38 pm

After some fighting the irq->swi mapping, preemptive taskswitching works now too.

But i got a design question for you all:
Shall a user mode program be able to receive irq ownership? (Thus lifting priviledges, unable to access virtual mem directly)
Or shall an irq trigger the creation of a sub-thread to handle the irq (stack intense)
Or shall only system mode drivers be able to access irqs?
_________________
GBAMP Multiboot

#112453 - wintermute - Sat Dec 16, 2006 4:07 pm

masscat wrote:
With regard to the ITCM location in the memory map:

From what I can remember of the start up code the size of the ITCM gets set to 32MBytes so that it gets mirrored to 0x01000000 (and many other places). The base is still at zero though. Not sure why it was done this way, maybe Nintendo did it and it just got copied.


It's done this way so that null pointers cause exceptions. If I had placed the itcm code at 0 rather than using one of the mirrors then using null pointers would just overwrite itcm code and cause random errors. This way memory at 0 is protected and causes an immediate fault.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#112455 - OOPMan - Sat Dec 16, 2006 4:43 pm

Mighty Max wrote:
After some fighting the irq->swi mapping, preemptive taskswitching works now too.

But i got a design question for you all:
Shall a user mode program be able to receive irq ownership? (Thus lifting priviledges, unable to access virtual mem directly)
Or shall an irq trigger the creation of a sub-thread to handle the irq (stack intense)
Or shall only system mode drivers be able to access irqs?


I would go for the option offering the best perfomance/reliability payoff. Alas, since I don't know that much about the technical side of what you're talking about, I can't pick it out of the list.

But, yeah, I'd say go for the option that gives running programs the best peformance.
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#112483 - Mighty Max - Sat Dec 16, 2006 8:54 pm

Ok, the code is a bit ugly on some things. (i.e. mem alloc)

But at least everyone is able to play around a bit on the code: Source

The user mode threads now have no access to the hw registers or VRAM. The only way to output right now is a swi to print a char at x,y.

The ndslib console and iprintf were removed for the space it frees. The 27kB it takes now fit into the SIWRAM. Into the few left kB the usermode library loader has to fit.
_________________
GBAMP Multiboot

#112620 - Mighty Max - Mon Dec 18, 2006 7:15 pm

Now everything is in siwram or itcm. Beside the IPC (set by the ARM7 i havent touched yet) the complete wram area is free and cleaned to zero.

[Images not permitted - Click here to view it]

Im a bit lazy right now, i should have started on the linker allready to build usermode executables for the system. But promised, will do that.
_________________
GBAMP Multiboot

#112622 - OOPMan - Mon Dec 18, 2006 7:20 pm

Nice :-) There's even a system clock already :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#112624 - Mighty Max - Mon Dec 18, 2006 7:39 pm

OOPMan wrote:
Nice :-) There's even a system clock already :-)


Just temporary, i was playing around. System clock should be a user mode program, meaning removal from the core.

The bar beside is more interesting, it shows used/free DTCM and virtRAM.
_________________
GBAMP Multiboot

#112849 - Mighty Max - Wed Dec 20, 2006 8:41 pm

I have isolated the problem with running the code on desmume (and sent the patch to the sf.net desmume maintainer)

There is still a problem somewhere, causing a false jump after some time. But the first seconds work just fine. The RTC transfer code has a problem too.

GBFS Version with custom built Desmume

[Images not permitted - Click here to view it]
_________________
GBAMP Multiboot

#112909 - Ollie - Thu Dec 21, 2006 2:06 pm

Are you guys actually writing a DS OS or am i just seeing things? XD

#112910 - OOPMan - Thu Dec 21, 2006 2:10 pm

Mighty Max is indeed working on something of that sort :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#112911 - Mighty Max - Thu Dec 21, 2006 2:35 pm

It's at least a proof of concept, and i will release its source and documentation when done, so someone can create a real OS from it.
_________________
GBAMP Multiboot

#112938 - Mighty Max - Thu Dec 21, 2006 8:22 pm

After finding that bug that caused troubles with corrupting ITCM when accessing a swapped out page, the 16MB virtual addressspace is working like a charm :D

A usermode program can now use the mirrors as they were independend ram places:

Code:

void usrMain(void) {
   unsigned long addr = malloc(0x900000) ;   /* assign 9 MB */
   /* both write access the same physical memory */
   *(volatile unsigned long *)(addr + 0x00500000) = 0xE12FFF1E ;    /* write something into the physical ram at (addr + 0x00500000) & 0x23FFFFF */
   *(volatile unsigned long *)(addr + 0x00100000) = 0 ;          /* write something into the physical ram at (addr + 0x00100000) & 0x23FFFFF */
   /* but the paging will backup the mirrors content while another mirror is accessed */
   if (*(volatile unsigned long *)(addr + 0x00500000) != 0xE12FFF1E) {
      printString(0,100,"Failed to write value!") ;
   } else {
      printString(0,100,"Write value success") ;
   } ;
   
   while (1) syscall(SYSCALL_IDLE) ;
} ;


Results in a nice "Write value success" :D (Only problem: this again breaks compatibility with emulators, as they dont handle region access rights)


Means i have nothing left but to implement a loader for usermode programs :)
_________________
GBAMP Multiboot

#112939 - Lick - Thu Dec 21, 2006 8:32 pm

Couldn't this have been done with a C/C++ system? Why an OS?
_________________
http://licklick.wordpress.com

#112941 - Sausage Boy - Thu Dec 21, 2006 8:37 pm

If I understand this correctly, the OS is the whole point, not the memory mapping system.
_________________
"no offense, but this is the gayest game ever"

#112942 - Mighty Max - Thu Dec 21, 2006 8:38 pm

I dont get what you want to say lick.
It are just a bunch of C files, donated with two small .s files.

:edit:
Ahh, no it wouldnt. In the normal state, many memory spaces are hardcoded for a special purpose in the ds bios. Therefor a code that takes care of all these things will need to reimplement nearly every function (irqs, swi, etc) again, which is euqally to setup & manage the DS's resources. Before executing the payload. Meaning it would have to be defined as an os.
_________________
GBAMP Multiboot

#112943 - Lick - Thu Dec 21, 2006 8:45 pm

Sausage Boy wrote:
If I understand this correctly, the OS is the whole point, not the memory mapping system.

Would be nice if that memory mapping system would be available seperately..

Mighty Max: never mind, hehe. Good job! Keep at it!
_________________
http://licklick.wordpress.com

#112949 - OOPMan - Thu Dec 21, 2006 11:06 pm

Lick, I think what Max is basically saying is that the effort of implementing the OS-provided features on a per-program basis would be rather a lot of effort...

With any luck Max's work will, at the very least, provide a solid foundation for any further OS-like efforts on the DS (Excluding DSLinux, of course, since that's already pretty feature complete...)

I think the general aim is to produce a light-weight OS that restricts individual programs as little as possible while also providing various useful features to the application programmer (Memory mapping for example) that would be troublesome to implement in a per program basis.

In other words the combination of HW + OS + SW should allow for extra flexibility in application programming than the plain HW + SW style currently in use.

Well, anyway, that's my hope :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#112954 - HyperHacker - Thu Dec 21, 2006 11:38 pm

I'm not sure I understand what you're doing with memory mapping here. You've given each program 16MB of virtual memory, and upon accessing it, the paging system automatically switches some things so that that memory region points to some arbitrary spot in main RAM? So two programs can use the same addresses, which actually point to some unmapped space, and they'll really be accessing two separate regions of main RAM? OK, but what happens when you run out of memory? For that matter why 16MB when there's only 4MB to map it to, or did you implement GBA slot expansion already?
_________________
I'm a PSP hacker now, but I still <3 DS.

#112966 - Mrshlee - Fri Dec 22, 2006 1:01 am

Pipe dream - Any chance of fake multitasking?

Using a SC, hit a trigger and it dumps the RAM and DTCM onto the Cart ram and loads the OS code back into the main memory.. select an additional program and that boots..

Trigger between the two programs with delay for I/O or something - depends if this would work for the OS-Aware applications or standard homebrew if we can trigger the IRQs without patching the unmodified homebrew releases..


I remember thinking about the possibility of a hardware based OS for DS.
placed ARM7 cpu and some ram onto a cart. DSMEM style. keep an active running OS on the cart at all time to handle memory and everything else.

Have the DS boot into the GBA cart OS and switch between programs on the DS and on the Cart.
_________________
MrShlee.com
Projects
Dev-Scene
MyTechpedia

#112977 - Mighty Max - Fri Dec 22, 2006 2:33 am

Mrshlee wrote:
Pipe dream - Any chance of fake multitasking?


Is running preemptive as well as cooperative.

Quote:

Using a SC, hit a trigger and it dumps the RAM and DTCM onto the Cart ram and loads the OS code back into the main memory.. select an additional program and that boots..


No need to. User mode programs have no direct control over anything other then wram and its mirrors. They can't overwrite anything vital. (ok right now they can, as siwram is still flagged for usermode access, but thats gonna change)

Quote:

Trigger between the two programs with delay for I/O or something - depends if this would work for the OS-Aware applications or standard homebrew if we can trigger the IRQs without patching the unmodified homebrew releases..


Different programs is something it is not aware yet. It shares one memoryset for all usermode threads.

It is not supposed to run .nds files. These would need control over the hardware they are not allowed to. Allready the very first action the default crt0 does would get it killed, as hw register access (REG_IME) is not allowed.

HyperHacker wrote:

For that matter why 16MB when there's only 4MB to map it to, or did you implement GBA slot expansion already?


There are 4 mirrors of 4MB wram (16MB addressrange for 4MB physical mem)

Let us play with the example code.
There are 256 Bytes reserved for the user thread stack in wram:
0x02000000 - 0x020000FF
Also the 9MB allocated:
0x02000100 - 0x029000FF

At startup there are 6 user mode regions set:
0x02000000 - 512kB
0x02080000 - 512kB
0x02100000 - 512kB
0x02180000 - 512kB
0x02200000 - 512kB
0x02280000 - 512kB

The first write:
address 0x02000100 + 0x00500000 is accessed. There is no region mapped at this address, so there is a abort happening. In the abort, the memory from (mirror0-page2) 0x02100000 from the pysical address 0x02100000 is saved to disc. The memory (mirror1-page2) 0x02500000 is loaded to the physical address 0x02100000. And region2 base address is set to 0x02500000.

The write now happens to 0x02500100. It does no longer cause an abort. Due to the hardware mirroring, the physical address 0x02100100 will be changed.

Now the second write.
To 0x02100100 will cause an abort, as this region no longer exists. The page 0x02500000 will be saved (from physical 0x02100000) and the old mirror0 page2 will be loaded again. The region is set to 0x02100000. The value 0 is written to the physical address 0x02100100. While the stored value on disc keeps intact.

On the read now the same things as in the first write will happen.
You can read now the value you stored to 0x02500100 at 0x02500100. Even tho the physical address was used to store something else inbetween.


Thats the worstcase btw, alternating access shifted 4,8 or 12MB will allways produce a backup/restore cycle. Everything involving different physical memory regions does happen a lot faster. (homebrew that will never access more then 4 mb will never experience the slowdown)
_________________
GBAMP Multiboot

#112996 - HyperHacker - Fri Dec 22, 2006 6:56 am

Saved to disk? As in a swap file? Not a good thing with flash memory. :-/
_________________
I'm a PSP hacker now, but I still <3 DS.

#113016 - Lick - Fri Dec 22, 2006 11:54 am

If the programmer uses the memory mapping system wisely, he will try to access the same region as much as possible, and swap as little as possible.

It would be cool if the OS would stop an application from starting if the RAM is fewer than what the application will us. Though the application will somehow need to specify the amount it needs.
_________________
http://licklick.wordpress.com

#113018 - OOPMan - Fri Dec 22, 2006 12:17 pm

Well, assuming programs come pre-packaged (Not as .NDS files but in a similar format adjusted for the OS) then packages that are overly large will be rejected.

Those apps relying on dynamically allocated memory, on the other hand, will fail when Malloc() tosses an error....Hmmmmm, that introduces the problem of cleaning up behind those apps...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113019 - Mighty Max - Fri Dec 22, 2006 12:29 pm

HyperHacker wrote:
Saved to disk? As in a swap file? Not a good thing with flash memory. :-/


We should remove the complete fatlibs. Rewriting the very same fat sectors is not good for flash *shruggs*

The pagesize is choosen to keep the swapcount as low as possible, and the file is not resized dynamically, which reduces the write load on filemanagement sectors of fat. And a caching system will reduce the load further.

Plus you dont have to use the feature, you can still run with the 4MB.

Also keep in mind that we got non-flash CF soltuions around. microdrives should handle swapping just like any other hdd.
_________________
GBAMP Multiboot


Last edited by Mighty Max on Fri Dec 22, 2006 12:41 pm; edited 1 time in total

#113020 - Mighty Max - Fri Dec 22, 2006 12:34 pm

OOPMan wrote:
Well, assuming programs come pre-packaged (Not as .NDS files but in a similar format adjusted for the OS) then packages that are overly large will be rejected.


Current plan is to have an .elf loader. (meaning a lot of work tho)

Quote:

Those apps relying on dynamically allocated memory, on the other hand, will fail when Malloc() tosses an error....Hmmmmm, that introduces the problem of cleaning up behind those apps...


Malloc will be done by the individual program (later via a user mode lib) out of the allocated heap for the program. After a program dies/exits, simply all heapspace tagged with the programs context will be free'd.
_________________
GBAMP Multiboot

#113023 - OOPMan - Fri Dec 22, 2006 12:55 pm

Mighty Max wrote:

Plus you dont have to use the feature, you can still run with the 4MB.


That's good, at least...

Quote:
Also keep in mind that we got non-flash CF soltuions around. microdrives should handle swapping just like any other hdd.


Hmmmm, isn't there only one micro-drive solution? Doesn't it suck?

I think it would be better to target swapping for the various devices out there offering memory (SC,M3,G6,etc) rather than the lone(?) micro-drive solution...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113025 - Mighty Max - Fri Dec 22, 2006 1:10 pm

I had mentioned the use of sdram solutions(Opera-card, m3, sc) allready earlier. I just got none of them, so i am developing the cf version first.
_________________
GBAMP Multiboot

#113026 - OOPMan - Fri Dec 22, 2006 1:24 pm

You're on a GBAMP then, right?
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113027 - Mighty Max - Fri Dec 22, 2006 1:27 pm

Correct.
_________________
GBAMP Multiboot

#113033 - chishm - Fri Dec 22, 2006 1:50 pm

Modern Flash memory cards use write balancing algorithms to prevent wearing of any particular sector. I think people worry too much about the wear on their cards.
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com

#113048 - OOPMan - Fri Dec 22, 2006 3:12 pm

Also, 1gb sticks are not very expensive anymore either :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113051 - Mighty Max - Fri Dec 22, 2006 3:19 pm

I still work on a 64MB card from 1998 (was bundeled witha vga resolution digicam that is long gone)
_________________
GBAMP Multiboot

#113125 - Inopia - Sat Dec 23, 2006 12:27 pm

Hey chism, haven't seen you around for a while :)

#113147 - Mighty Max - Sat Dec 23, 2006 6:35 pm

Dynamically loading a usermode routine now works for the first time.

The example usermode program (Source) is loaded from disc and executed.

Play around with it a bit with it (changing strings, location etc). It is not documented yet in any way (not even comments in source). The Version with loader and the example (which loads main.dle from root dir) can be found at: http://mightymax.org/Virtual16.zip

It will not use any swapping (except you build a >4MB .dle file :D)
_________________
GBAMP Multiboot

#113149 - OOPMan - Sat Dec 23, 2006 7:22 pm

Very nice. I'll test this on my SC a little later and see what happens...

At the moment no$gba doesn't like it at all while dualis starts okay but doesn't load the file (Because I haven't set it up properly yet...)

I still need to grab your fixed version of Desmume...

Anyway, nice work man :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113150 - Mighty Max - Sat Dec 23, 2006 7:28 pm

Desmume wont run it because of using the old fatlib. (It will load but fail to find main.dle)
Dualis wont run it because it does not support alternative swi vectors

no$cash ... no clue. I dont use it.

So far it should only be working on these hardwares solutions:
Code:

#define SUPPORT_NMMC      // comment out this line to remove Neoflash MK2 MMC Card support
#define SUPPORT_MPCF      // comment out this line to remove GBA Movie Player support
#define SUPPORT_M3CF      // comment out this line to remove M3 Perfect CF support
#define SUPPORT_SCCF      // comment out this line to remove Supercard CF support
#define SUPPORT_SCSD      // comment out this line to remove Supercard SD support
#define SUPPORT_FCSR      // comment out this line to remove GBA Flash Cart support




I need something to load system mode drivers at runtime later. And a kernel that checks gbfs space for such a driver or the main.dle
_________________
GBAMP Multiboot

#113152 - OOPMan - Sat Dec 23, 2006 7:34 pm

Hmmmm, well, I guess we'll see what it thinks of my SC:miniSD then :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113201 - Ollie - Sun Dec 24, 2006 10:55 am

Post back how well it does, OOPMan, i'm getting a supercard MiniSD and i want to see if it works. I'm really interested in this thread, i don't understand it all, but i'm interested! XD

#113203 - OOPMan - Sun Dec 24, 2006 11:20 am

Ouch. Bad news. It works less well on my SC:miniSD than it does on Dualis!!!!

The gbfs version loads up but starts flickering like crazy and doesn't get display the loading progress bar thing or the info bar at the bottom of the screen.

The non-gbfs version doesn't flicker, but doesn't display the loading bar or the bottom screen bar. It ssems to get to the point that it should and does display the "memory setup" line, but does nothing...

Hmmmmm...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113205 - Mighty Max - Sun Dec 24, 2006 11:54 am

Where exactly do these problems occure?

On the gbfs version:
What exactly is flickering? When you say the info bar is not displayed. Is the screen prepared for the info display before (like the bar is there but without content)? Or is still the default console showing?

On the normal version: what is the last line given out?


---

Do you know if the old SC:sd driver works with SC:minisd?
_________________
GBAMP Multiboot

#113207 - OOPMan - Sun Dec 24, 2006 12:33 pm

With the GBFS version:

Flickering starts as soon as the rom loads. Text displayed:

Quote:
Loading kernel ...
protection base
siwram set
siwram test
loaded
executing


And that's it. No loading bar, no status bar :-(

This happens when I load the ROM via the SC firmware, Moonshell or DSO Blue 2.3

With the non-GBFS version:

No flicker, text displayed:

Quote:
Loading kernel ...
filesystem init
proection base
siwram set
siwram test
loaded 28528 bytes
executing


And that's it again. No loading bar, no status bar. As with above, this happens no matter how I load the binary...

On Dualis I see a slight bit of graphics corruption for a second and then the following text:

Quote:
itcm setup
memory setup
system thread


The loading bar displays and the status bar displays...

Which version of devkitPro are you working on and what FAT library are you using?
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113209 - Mighty Max - Sun Dec 24, 2006 12:46 pm

OK, yes i know now what's causing this.

I will make a pure gbfs version. That should make it run on desmume again, and solve your troubles for now.

The current _gbfs version only uses gbfs for the kernel loader, but not within the kernel itself. So the fat driver lockup takes down the kernel on trying to initialize.
_________________
GBAMP Multiboot

#113211 - OOPMan - Sun Dec 24, 2006 12:56 pm

I look forward to testing it :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113217 - Mighty Max - Sun Dec 24, 2006 3:19 pm

Pure GBFS vresion (and some bugs fixed)
http://mightymax.org/virtual16_gbfs.rar

Works again in desmume (on the fixed/ current CVS version) :D

Unfortunally with binary data included its a bit difficult to play around. Dynamically loaded fix data ;)


/me is out for chrismas
Everyone out there, have some nice days!
_________________
GBAMP Multiboot

#113218 - Ollie - Sun Dec 24, 2006 4:25 pm

Hey, i thought this little thing i found on Ken Perlin's webpage could be an interesting concept for a DS operating system. I just remembered i can't link directly on here can i?

Well try and find it, it's an interesting java applet demonstrating a very nifty little idea which might work nicely for a DS operating system _somehow_.

If you google Ken Perlin's webpage (it'll probably be found easily), and scroll down to the row of images that is titled "ideas". On that row, the third image in, click it and it will take you to a java applet about "Whiteboard". This java applett is a simple application that gives you a drawing board, you can draw onto it simply using left click, typing puts text where you've last clicked on the screen.

But the main nifty part is that, you can embed programs onto the white board. You type in the program name, hit the escape key and it loads it onto the whiteboard. Whilst still giving you the ability to infinately pan the screen around and zoom.

This might make a nifty idea for interacting with multiple programs on a DS, possibly. I just thought that via your OS or not, it'd make a nifty idea for the DS :)

#113219 - ghaxaq - Sun Dec 24, 2006 4:49 pm

Hi mighty max..I tried out your OS(the last version you released) and it works on my SC-CF..It shows a small user bar and some text, and it also detects the stylus position..it is showing to be some kickass although it cannot do nothing till now..maybe sooner it will make something useful.

#113224 - OOPMan - Sun Dec 24, 2006 5:53 pm

The new GBFS version works on my SC:miniSD

When I first loaded it up it locked as soon as I touched the touchscreen, but when I tried a second time it worked fine. Not sure what caused that...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113269 - Mighty Max - Mon Dec 25, 2006 7:00 pm

http://mightymax.org/virtual16_gbfs.rar now does disable sound/screen on lid-close.

(Just a minor feature while trying to help in the thread http://forum.gbadev.org/viewtopic.php?t=12011)
_________________
GBAMP Multiboot

#113271 - OOPMan - Mon Dec 25, 2006 7:13 pm

Hmmm, by the way, I managed to get that lock-up again. I *think* it happens if you hit the touchscreen too soon after V16 has booted...

I'm not sure though...

It's a little infrequent and hard to guess why it's happening...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113272 - Mighty Max - Mon Dec 25, 2006 7:19 pm

Should be also solved. I didnt have that problem myself, but i was not resetting the fifo data on startup, so remaining words (probably due to the SC loader) in the fifo hardware could cause a hangup (infinite waiting for replies)
_________________
GBAMP Multiboot

#113273 - OOPMan - Mon Dec 25, 2006 7:26 pm

Okay, I'll give it a spin and see if I can lock it up :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113427 - Inopia - Wed Dec 27, 2006 8:01 pm

http://ecos.sourceware.org/about.html

how about this?

#113429 - OOPMan - Wed Dec 27, 2006 8:04 pm

Check back through the thread. The general agreement was that porting an existing RTOS (Such as eCos, Prex or FreeRTOS) would probably be less than optimal...

However, feel free to give it a shot...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...


Last edited by OOPMan on Wed Dec 27, 2006 8:43 pm; edited 1 time in total

#113434 - Mighty Max - Wed Dec 27, 2006 8:23 pm

Inopia wrote:
http://ecos.sourceware.org/about.html

how about this?


eCos expects an MMU. The DS only has an MPU.


:edit:
btw, some nice weird bugs fixed. Did you know, that the instruction & data caches are very resistant against powering the DS off? *g* That caused me some troubles when the gbfs version jumped to addresses from the non gbfs version and vice versa when shutting down and starting the other. Repeated starts of the same version then made it working again.
_________________
GBAMP Multiboot

#113484 - HyperHacker - Thu Dec 28, 2006 5:07 am

Interesting. This could be used to exchange data between games, like Banjo-Tooie was supposed to do.
_________________
I'm a PSP hacker now, but I still <3 DS.

#113506 - Inopia - Thu Dec 28, 2006 10:55 am

You guys seem to be making progress!

For the gui, I suggest using a hardware abstraction layer. If the new OS has some form of interprocess communication like unix sockets, we could employ the same model as X on unix. When you think about it, it's actually very natural for our purposes.

The first layer could be a hardware abstraction layer that manages the sound, graphics and so forth. Usermode programs can request exclusive access to each, but if a lock is obtained the lock may be released by the abstraction layer at any time (to facilitate task switching between two programs that both use the 3D hardware for instance). This would ofcourse require mutual exclusion mechanisms.

Running in the background we can have usermode programs that provide easy access to these resources. For the sound we could have a soundmixer, and for graphics and input sometiming like an X server.

X servers are really quite simple, all they really do is manage windows on the screen on the behalf of usermode programs that connect to it. The X server captures input (buttons and stylus in our case) and generates events on the client programs. Client programs receive a piece of memory they can paint into. For simplicity, we could build the window manager into the X server. The window manager is the piece that draws the borders around windows and makes them draggable. We have two screens, so it would seem natural to me to use them as if they were two desktops, switching between them with some key combo.

Finally, on top of our X-like server, we could put a gui toolkit. There already are a lot of lightweight solutions available we could perhaps adapt. But this is really the responsibility of the client programs, not the OS.

Now if a game wants to use both screens, it can simply request a lock on the graphics hardware, wich it is granted as soon as it becomes the 'active' process (this has nothing to do with task scheduling, it's just a bit indicating wich process is currently in the user's face, like task switching with alt+tab on windows) . When the user switches back to the OS, the x-server regains the lock on the graphics hardware and the screen is restored.

Oh, and we need a screencapture feature so people can post screenshots of their desktops, just like in the good old days :P

#113507 - nornagon - Thu Dec 28, 2006 11:31 am

I hate to be all doom and gloom, but... I think this is a fairly useless pursuit.

My reason: speed. If I'm writing a game, a toy, a tool, or whatever, I'm going to, sooner or later, run up against a point at which the OS simply can't perform at the speed I need it to. As an example, I've spent the last few days trying to optimise my World of Sand app, and I've managed about four more fps. Which brings it up to a total of 6 fps when the screen's completely full of fairly processing-intensive materials.

If there's an OS in the way, what hope do I have of getting decent speed out of the DS? What does having an OS provide in terms of benefits to the (seasoned) programmer? Why is it so hard to turn off the DS in order to start a different app/game? What real benefits does having an OS net the user?

I appreciate the coolness of the thing, but I'm skeptical of its practicality and usefulness.

#113508 - Mighty Max - Thu Dec 28, 2006 11:43 am

If an program aquires exclusive access to the vram and threadshedule (setting all others into waiting) there should be no slowdown at all, while retaining the advantage of having dynamically loaded modules. Where code can be loaded and released into the program when needed.

A lot of programs around here tho are far away from beeing that cpu intense and use swiWaitForVBlank. Which can be simply replaced with idle() and alowing another few instances of it to run without loosing speed.
_________________
GBAMP Multiboot

#113509 - OOPMan - Thu Dec 28, 2006 11:58 am

Nornagon, haven't you encountered the concept of a Real-Time OS before?

An RTOS is designed with exactly the kind of issues you raised in mind. In other words, a good RTOS will do its very best to hinder performance as little as possible.

RTOSes are used in a huge variety of time-critical systems on a variety of embedded systems and the best of them have been very good at what they do...

It's easy to think "Windows" when you think of an OS. As a model OS, though, Windows is a pretty poor point-of-reference. It does a very good job of choking system resources and reducing system performance.

Asking what benefits an OS can provide, on the other hand, is a little silly. By providing an abstraction layer between hardware and software the OS allows software to benefit from various features that, if implemented on a per-program basis can be trouble-some to implement well. By providing a standard way to perform certain tasks, such as accessing system resources and so forth the OS makes the job of the application programmer that much easier, reducing the workload involved in performing a variety of simple yet important tasks.

I appreciate your skepticism, though. This is precisely why the aim is to produce something DS-specific, light-weight and fast.

I do not think an OS is a useless pursuit. Computing history has illustrated, as far as I can see, that on any sufficiently complex computer system a well-written OS can provide more in the way of benefits than problems. Is the DS a sufficiently complex systems? Yes. It may seem puny compared to the PC sitting on your desktop, but it's still a great deal more powerful than the system that flew the Apollo space modules and pretty much any computer produced prior to 1980.

In some ways this all links into the PALib vs. libnds argument in another thread. Both high-level and low-level have their pros and cons. The trick is to achieve an optimal balance between the two factors...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113510 - Inopia - Thu Dec 28, 2006 12:09 pm

The key lies in designing a layered system, this allows lazy programmers that care less about speed to quickly develop their products, and lets hackers obtain locks for low level access to do some cycle fucking.

#113525 - ghaxaq - Thu Dec 28, 2006 3:59 pm

An OS will be useful to display applications on your media as icons and make them clickable for easier access, and could also support plugins, and maybe in built apps..thus collects all your needs in one app by linking to external applications that are frequently used without the need to turn on and off your DS.

#113588 - nornagon - Fri Dec 29, 2006 2:00 am

I see a lot of people in this thread trying to suggest GUI ideas for this OS... they want it to have a window manager, a gui toolkit, app multiplexing, blah blah.

Yes, it's a lot like the libnds vs. PAlib debate. If I can't get at the hardware and do what I want with it without risk of fucking other things up, that's limiting me. And, fyi, I'm working on something right now that gets to the point where swiWaitForVBlank()ing slows it down signifigantly. It also uses the arm7 for some parallel processing stuff, time-critical.

I think it's a very closed-minded viewpoint to say, "Well a lot of apps spend time idling in swiWaitForVBlank(), so it's fine to replace that with important OS stuff." You run up against a wall when you come across apps that, gasp, actually push the hardware.

More power to you if you can manage to write something that comes within 95% of the speed of the DS without the OS and manages to provide some signifigant benefit. But I don't think that's easy, and I think using an OS--same as using PAlib--makes life easy when you start off, but you end up hitting a performance wall and there's nothing you can do about it without either severely hacking PAlib (or the OS) or just dropping PAlib (or the OS) and just hammering the registers yourself.

One thing I think a DS-specific OS might actually work for is the purpose that DSLinux currently provides -- that is, IRC, web browsing, music playing, SSH, etc. Miscellaneous tasks that are often performed in parallel to one another. But I think for more critical applications, it just Doesn't Work?.

It'll be interesting to see where this goes, though :)

#113598 - tepples - Fri Dec 29, 2006 2:20 am

nornagon wrote:
One thing I think a DS-specific OS might actually work for is the purpose that DSLinux currently provides -- that is, IRC, web browsing, music playing, SSH, etc. Miscellaneous tasks that are often performed in parallel to one another. But I think for more critical applications, it just Doesn't Work?.

A lot of DSOrganize users looking for a successor would take issue with your suggestion that IRC, music playing, text editing, and the like aren't "critical" to their enjoyment of the DS.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#113599 - sajiimori - Fri Dec 29, 2006 2:29 am

Bottom line: Is the OS going to have anything that it must do every game loop (or periodically for that matter)?

If you can answer "no" to that, then nornagon can have 100% of the CPU cycles per game loop, end of story.

#113601 - simonjhall - Fri Dec 29, 2006 2:57 am

sajiimori wrote:
Bottom line: Is the OS going to have anything that it must do every game loop (or periodically for that matter)?

If you can answer "no" to that, then nornagon can have 100% of the CPU cycles per game loop, end of story.
Quoted for truth :-D

Time to read up on real-time OSes - they've been developed for many years for a world where couting clock cycles matters.
I think some people in this thread are looking for a PDA app for the DS, not an OS.
_________________
Big thanks to everyone who donated for Quake2

#113606 - nornagon - Fri Dec 29, 2006 4:52 am

tepples wrote:
nornagon wrote:
One thing I think a DS-specific OS might actually work for is the purpose that DSLinux currently provides -- that is, IRC, web browsing, music playing, SSH, etc. Miscellaneous tasks that are often performed in parallel to one another. But I think for more critical applications, it just Doesn't Work?.

A lot of DSOrganize users looking for a successor would take issue with your suggestion that IRC, music playing, text editing, and the like aren't "critical" to their enjoyment of the DS.


Read again. I said for more critical applications -- i.e, ones that require more raw power than the others enumerated.

So, (and this might've been mentioned earlier in the thread; I haven't read thoroughly) what does the OS actually do?

#113609 - GPFerror - Fri Dec 29, 2006 5:05 am

GPFerror wrote:
why not improve dslinux with some of the features that you have listed?


as dslinux has been brought up again, and my question from page 6 was missed/ignored , I will ask it again :)

thanks,
Troy(GPF)

#113611 - nornagon - Fri Dec 29, 2006 5:14 am

@GPFerror: I'm not an expert, but from what I can tell it would be a lot trickier to pare down the dslinux kernel into something that can both run at the speed it needs to and retain compatability with existing dslinux stuff. It's easier to get something workable if we start from the beginning.

#113631 - Mighty Max - Fri Dec 29, 2006 10:20 am

nornagon wrote:

I think it's a very closed-minded viewpoint to say, "Well a lot of apps spend time idling in swiWaitForVBlank(), so it's fine to replace that with important OS stuff." You run up against a wall when you come across apps that, gasp, actually push the hardware.


You really misunderstood me there. idle() does not give the OS time to do things. Actually it doesnt do anything there, but give other threads time to run. If you are the exclusive running thread. idle() does nothing and can be simply ignored.

Quote:
what does the OS actually do?

Provide means to share the system resources.
(for now)
- memory
- cputime
- gfx
(to be done)
- libraries
- files
And ability to start/stop applications

Meaning, that app, that can set up (start) by itself and does not want to share anything because it pushes the hardware to its limit, doesnt need the service. So why should it be run with the service?
_________________
GBAMP Multiboot

#113638 - nornagon - Fri Dec 29, 2006 12:04 pm

So when I call idle(), does the OS guarantee that control will be returned to my app within a certain amount of time?

Also -- why do you need to run multiple apps at once on the DS? Unless, like I said before, it's for IRC/SSH/etc., which dslinux does pretty decently.

It'd be nice, though, if the OS would catch the 'lid closing' interrupt and go to sleep :)

#113640 - lyptt - Fri Dec 29, 2006 12:16 pm

I think it'd be quite handy, the possibility of closing apps on the DS without powering off is a good feature by itself, I think being forced to power off each time you want to run a new program is really user-unfriendly.

#113644 - simonjhall - Fri Dec 29, 2006 12:36 pm

lyptt wrote:
I think being forced to power off each time you want to run a new program is really user-unfriendly.
Yeah, that's very true. Plus it'd decrease the chances of me blowing a third fuse on my DS :-D
_________________
Big thanks to everyone who donated for Quake2

#113646 - Mighty Max - Fri Dec 29, 2006 12:37 pm

nornagon wrote:
So when I call idle(), does the OS guarantee that control will be returned to my app within a certain amount of time?


Depends on the setting right now. Whether or not preemptive mode is enabled. In pure cooperative, the time needed to return depends only on the time other threads need to get along the next idle.

In preemptive the timeslots can be sized relatively to the amount of threads running, meaning that the preemptive taskswitch into the thread occures before a constant maximum time passed.

Quote:

Also -- why do you need to run multiple apps at once on the DS? Unless, like I said before, it's for IRC/SSH/etc., which dslinux does pretty decently.


I dont know. Why do you need to run multiple apps on other platforms? Its the decission of the user i'd think.
Actually i am not very optimistic to that. I just like to do things like that.
(DS)Linux has the disadvantage (and its also its advantage) of having all that stuff around it. Even for uClinux my personal opinion is: bloated.
But im not familiar enough with the structure to work directly there and Mess with the things we dont need and only eat resources.

Quote:

It'd be nice, though, if the OS would catch the 'lid closing' interrupt and go to sleep :)


It works quite smooth now, alltho i'm not quite sure if the decission to go into sleep should be done by the kernel or be result of usermode threads to reply for an event and call for the sleep, so it can "pause" correctly (as i.e. the RTC and thus time will still continue)
_________________
GBAMP Multiboot

#113650 - OOPMan - Fri Dec 29, 2006 1:37 pm

Damn, a lot of interesting posts since I last checked the thread :-)

My opinions on some of the points raised:

Nornagon wrote:
I see a lot of people in this thread trying to suggest GUI ideas for this OS... they want it to have a window manager, a gui toolkit, app multiplexing, blah blah.


Okay, this is one point I personally keep stressing again and again. GUI != OS. There are people posting ideas for GUI-based OSes but my personal hope is that Max will pretty much ignore most of that stuff. I personally don't think a complex GUI system is very suitable for the DS overall. At the moment I think it's more important to write an actual OS, rather than try and integrate all kinds of extraneous features into the kernel that will cause the kind of problems you worry about, namely reduced performance.

Nornagon wrote:
Yes, it's a lot like the libnds vs. PAlib debate. If I can't get at the hardware and do what I want with it without risk of fucking other things up, that's limiting me. And, fyi, I'm working on something right now that gets to the point where swiWaitForVBlank()ing slows it down signifigantly. It also uses the arm7 for some parallel processing stuff, time-critical.


I think you've missed part of the point behind Max's V16 experiment. I do believe his aim is specifically not produce an OS, or the base of an OS, that conceals hardware functionality. In other words, V16 is not trying to abstract the underlying hardware of the DS, something which ports of more platform generic OSes (Linux, Prex, etc...) would do in the aims of platform portability. Precisely because the OS is being programmed with ONLY the DS in mind is significent, as it means the OS will be able to expose the underlying hardware with much greater ease, allowing people programming under the OS to keep using the large majority of their funky tricks with few or no changes...

Nornagon wrote:
More power to you if you can manage to write something that comes within 95% of the speed of the DS without the OS and manages to provide some signifigant benefit. But I don't think that's easy, and I think using an OS--same as using PAlib--makes life easy when you start off, but you end up hitting a performance wall and there's nothing you can do about it without either severely hacking PAlib (or the OS) or just dropping PAlib (or the OS) and just hammering the registers yourself.


Using an OS does not necessarily make things any easer. Arguably, programming software that functions well in a multi-threaded, multi-processing environment is actually more difficult than just programming software that runs in an exclusive mode.

The performance wall on computer systems is not so much a case of CPU processing limits as I/O throughput limits. One thing taught in the the CSC lectures I attended on the subject of system and CPU design was that CPU cycles are "cheap". In other words, performance is usually limited more by I/O and I/O-related processing than anything else. While the DS is a rather clever little system, I personally doubt it is quite so funky that the effect I/O has on performance can be ignored. But why am I talking about this anyway? Simple. Blaming the OS for poor performance is an easy thing, but it's not always the right thing. In the case in poorly written OSes, such as Windows, it may be true. However, a custom-designed, light-weight OS for the DS designed with maximum application performance in mind is less likely to be a source of poor performance than I/O operations performed by the applications themselves.

Let's just take two scenarios. You're running apps for your DS under this hypothetical OS.

In case one, you're running numerous applications at once, including at least one "performance hog". Will the peformance oriented app peformance more poorly? Quite possibly. In a case such as this, however, the user should know better than try and running, say, QuakeDS, Moonshell playing MP3s and NDSMail all at once. The combined I/O requirements are sure to cause poor performance in all the applications, regardless of how the OS schedules resources.

In case two, you're running QuakeDS and nothing else. Will QuakeDS perform poorly simply because it's being run in an environment with an OS? No, not necessarily. In such a case there will probably only be 2 "programs" running at once: The application and the OS. If the OS has been written in such a fashion that it does it's very best to impact application performance as little as possible then it's rather unlikely that QuakeDS will crash an burn simply because it is being run under an OS. If this were true then technologies such as virtualisation would be simply unfeasible, no matter what tricks were played. However, it is not true and blaming poor performance on the OS is, in this case, a cop-out.

Nornagon wrote:
One thing I think a DS-specific OS might actually work for is the purpose that DSLinux currently provides -- that is, IRC, web browsing, music playing, SSH, etc. Miscellaneous tasks that are often performed in parallel to one another. But I think for more critical applications, it just Doesn't Work™.


As I explained above, running a single "critical" application by itself under the OS will not fail simply because said application is being run under an OS.

Nornagon wrote:
@GPFerror: I'm not an expert, but from what I can tell it would be a lot trickier to pare down the dslinux kernel into something that can both run at the speed it needs to and retain compatability with existing dslinux stuff. It's easier to get something workable if we start from the beginning.


This is exactly the point I made myself with regards to DSLinux. DSLinux is nice. It's cool that we can actually run Linux on the DS. However, DSLinux is more Linux than DS and hence software running under DSLinux just sees the DS as pretty much any generic embedded system running uClinux.

Nornagon wrote:
So when I call idle(), does the OS guarantee that control will be returned to my app within a certain amount of time?


As long as the OS supports pre-emption, yes.

Nornagon wrote:
Also -- why do you need to run multiple apps at once on the DS? Unless, like I said before, it's for IRC/SSH/etc., which dslinux does pretty decently.


Here we come to the crux of the problem. Why not just do it under DSLinux? There are a couple of reasons, but the first and foremost, as I stated above, is that DSLinux is more Linux than DS. Meaning that it's a nice thing to work with if you want to port existing Linux applications with minimal fuss or create new appications within an environment that is specifically Linux. On the other hand, if you want to create software that is designed with the DS in mind then DSLinux is not a good choice. it abstracts the hardware in such a fashion that the DS appears to be just another genetic computer with keyboard, mouse, display and wifi. Linux's portability is both a pro and a con. On the one hand it makes porting existing code easy and ensures that various system components can be relied on to work in a certain way, reagrdless of the underlying hardware (Keyboard, mouse, display, wifi, file systems, etc, etc). On the other hand, though, it's portability does a good job of completely concealing the underlying features of the DS itself. The only "program" in DSLinux that can actually see the DS for what it is the OS itself. This is, make no mistake, more of a loss than a gain, given that the DS is a fixed platform and thus does not benefit greatly from Linux's inherent portability, which makes more sense if one's aim is to produce an OS and software for that OS that runs on a variety of platforms.

Make no mistake, an OS for the DS is a good thing. Some people thinking of the benefits are concerned with various aspects such as GUIs and Window Systems that could be described, at best, as being "shallow" concerns. These are not the true benefits of the OS. The benefits of the OS come in at a rather lower level and are by no means ingsignificent.

Support for shared code (Ie. dynamically linked libraries) could make a very very big difference in application programming. Shared code allows programs to be reduced in size overall and pared down to a more modular form. It also allows for easier recitification of problems in software and shared code alike. A problem with the application does not require a rebuild of the shared code anda a problem with shared code can be fixed without having to rebuild every single application that relies on the shared code.

File system and device management is another important area that stands to benefit. At the moment DS development is hindered by the conflict between gba_nds_fat and libfat. Some developers work with gba_nds_fat, or one of it's numerous peculiar variants (Another problem in itself), and older version of devkitPro while other developers make use of libfat and use the more recent version of devkirPro. This is not a good thing. It segments the developer community and makes it rather more difficult for source code to be shared and adapted, where said soure code relies on one or the other library. Allowing the OS to handle the underlying access to media devices could reap numerous benefits. Developers need not worry about which library to use and which version of devkitPro they need. Both users and developers could also expect better support for SLOT-1 devices without it coming at the cost of reduced support for SLOT-2 devices. The overall effect of this could be significant. Assuming popular applaications such as Moonshell, DSOrganize and more could be adapted to the OS without too much trouble, said apps and many others could be guaranteed to work correctly, regardless of the underlying media adapter.

To me these two points are highly significant and the first was the seed of this entire topic :-)

Anyway, so, my thoughts :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113657 - nornagon - Fri Dec 29, 2006 2:35 pm

Unification of code is a good thing, agreed. It'd be nice to be able to link against, say, a shared MP3/OGG/MOD/S3M/etc. playing library, or a jpg/png library.

The reason I'm confused is: Why has multithreading become a part of this? It's not an attempt to replace DSLinux, with its SSH and IRC and multitasking capabilities, right? The aim is to provide a very thin compatability layer for programs -- essentially, flashcart access unification. The rest of the DS hardware stays the same; no need to provide a compatibility layer.

Where are the I/O bottlenecks on the DS? The cache on the arm9 is pretty good at fixing up ram access bottlenecks, and the only other I/O points are touchscreen/buttons and the displays -- to which access is very fast anyway. More time is spent processing than displaying or reading input. Oh, and flashcart access -- but that should be only during load/save operations, and shouldn't be a performance problem.

By "Doesn't Work" I don't mean the thing doesn't work at all -- I mean it's too slow to be usable.


So, the reason to have an OS is essentially for shared and dynamically linked code. Which is a Good Thing, because it lets the shared code be updated independently of individual applications. Stuff like touchscreen accuracy, flashcart access, compression/decompression, and mixing. Nice. But why do we need to multithread? Would it not be enough to provide the application with an OS call to unload itself, letting the OS take control again so the user can load another app? There's no need for multitasking, as far as I can see.

#113662 - OOPMan - Fri Dec 29, 2006 3:22 pm

nornagon wrote:
Unification of code is a good thing, agreed. It'd be nice to be able to link against, say, a shared MP3/OGG/MOD/S3M/etc. playing library, or a jpg/png library.

The reason I'm confused is: Why has multithreading become a part of this? It's not an attempt to replace DSLinux, with its SSH and IRC and multitasking capabilities, right? The aim is to provide a very thin compatability layer for programs -- essentially, flashcart access unification. The rest of the DS hardware stays the same; no need to provide a compatibility layer.


Er, no, the aim is actually to write an OS :-) A thin compatibility layer is an option, yes, but a thin compatibility layer would probably become Yet Another NDS Library. Some people might use it, some people might not. Of course, the same could be said of an OS I guess :-0 However, it is possible that the benefits of an OS would encourage great adoption than that of Yet Another Library...

Quote:
Where are the I/O bottlenecks on the DS? The cache on the arm9 is pretty good at fixing up ram access bottlenecks, and the only other I/O points are touchscreen/buttons and the displays -- to which access is very fast anyway. More time is spent processing than displaying or reading input. Oh, and flashcart access -- but that should be only during load/save operations, and shouldn't be a performance problem.


Unfortunately there are pretty much always bottlenecks, even with the use of caches and other useful features to reduce their impact. Optical computing might change all that, but that's not quite at production level just yet :-)

The key I/O bottleneck I was referring to was media device access. Pretty much all homebrew uses media devices to some extent and in the more complex ones I/O bottlenecks are a problem (Example: Nitrotracker was virtually unusable on SC-devices due to an I/O problem in the fat library used that made directory listing horribly slow). While I appreciate that some homebrew (Such as World of Sand ;-) rely more on the CPUs than anything else, one has to think of the worst case scenario when taking into account problems of various kind (I/O or not...)

I think it's safe to say that media devices on the DS, while more sprightly than HDDs, are not quite at the level yet where they can be ignored as a source of I/O bottlenecks.

Possibly I didn't explain the "cpu cycles are cheap" concept as well as I could have. In the above quote you state "More time is spent processing than displaying or reading input". While this is perhaps technically true, it's also somewhat simplistic. CPU cycles are plentiful, even on a low-power processor such as the ARM7/9. Wasting a few here and there to support the underlying functions of an OS is not nearly as huge a performance hog as those cycles spent handling I/O from various devices. In other words, the processor time spent on I/O is more of a worry than processor time spent in purely internal CPU operations. I/O is pretty much always the bottleneck. Unless the OS is doing a lot of I/O of its own, which is definitely not the aim of the game, it's effect on performance should not be nearly as terrible as you imagine.

Quote:
So, the reason to have an OS is essentially for shared and dynamically linked code. Which is a Good Thing, because it lets the shared code be updated independently of individual applications. Stuff like touchscreen accuracy, flashcart access, compression/decompression, and mixing. Nice. But why do we need to multithread? Would it not be enough to provide the application with an OS call to unload itself, letting the OS take control again so the user can load another app? There's no need for multitasking, as far as I can see.


Why do we need to multi-thread in the OS? There are a couple of important reasons for this.

One is to ensure that applications using multi-threading do so in a predictable fashion. If every app used it's own multi-threading library then multi-threading would most likely not be reliable or predictable.

Another reason was significant in the early history of multi-tasking version of UNIX that did not support multi-threading (Linux went through this stage as well). By not supporting multi-threading at the OS level one forces developers to use application-level multi-threading libraries. While these can function well, they nevertheless function within the context of a single thread of execution within the OS. Essentially, their multi-threading is artificial and this significantly reduces the benefits of multi-threading.

In the context of the DS we have other reasons as well.

For one, unless someone decides to write a single monolithic media application that plays music, performs file I/O and integrates whatever other arbitrary features users desire then the idea of an OS that lacks multi-tasking and multi-threading falls down. If such an app is not written, users will inevitably become frustrated. They want to do tasks X, Y and Z and app A, rather the load app A to perform task A, app B to perform task Y and app to perform task Z in a linear or possibly alternating fashion.

Put another way. A multi-threading, multi-tasking DS OS would allow someone out there to devote their development time to writing a file I/O application while someone else writes a dedicated music player. The developers of each app are able to pursue their aims as completely as they desire, while the users are able to run either app or even both apps at the same time, secure in the knowledge that the OS will ensure that neither app interferes with the other.

In other words, it reduces the work individual developers have to do to support certain features users deem necessary (Eg, Performing file I/O while listening to music).

What happens when you don't have multi-threading and multi-tasking to support this? Take a look at DSO and Moonshell. Whenever you change directories music playback stutters. This is mostly likely due to the application being single-threaded and thus is unable to perform file I/O and music playback in an alternating (Ie. Multi-threaded) fashion.

Is it possible to rectifiy this problem? Yes. As explained above. File I/O is a costly operation, where as the music playback is likely to be more CPU intensive than anything else. By threading the file I/O and the music playback you are able to allow the user to seemingly play music and perform file I/O at the same time. This satisfies the user's desire to do both, even though the tasks themselves are executing linearly.

Implementing such multi-threading on a per-application basis is costly however. On the other hand, writing multi-threaded code in the knowledge that the large majority the work involved in getting such code to work well is handled by the OS makes it easier for individual developers to take the plunge and multi-thread their code.

There are probably many more reasons I could pull out of the sack, but I'll only lay down one more.

The DS is an asymmetric, dual-processor system. However, I'm guessing that a significant number of developers out there (This applies to the PALib crowd especially, I'm guessing) treat it as a uni-processor system, relying on a pre-supplied ARM7 binary to handle various tasks (Sound, Wifi, Input, etc...). While this may be an easy way to dip one's toe in the water with regards to coding for the DS, it's not without it's problems. For a start, it's wasteful. Both Mighty Max and Hermes have illustrated that it is possible to run generic code on both the ARM7 and the ARM9 at the same time. Why then does a large body of the homebrew developer scene largely ignore at least one of the processors? I'd imagine it's because the work involved in getting an individual program to use the ARM7 and the ARM9 in a useful, stable fashion is difficult.

Here is where the OS can prove useful. By supporting both the DS's peculiar hardware and multi-tasking and multi-threading it could allow for better general usage of both processors at the same time. In a nutshell, it could improve efficiency.

In my opinion, support for multi-threading and multi-tasking is essential. To ignore one or the other would lax.

With regards to implementing the OS as an application that loads and unloads completely as required, I have to ask what the point is. If the OS is optional, why use it? After the OS has been unloaded applications are free to use the hardware as if the OS had never been loaded in the first place. This makes the OS itself rather pointless, in my opinion. Whatever memory organisation it's pursued while likely disappear and the various other features it could provide (Multi-threading, multi-tasking, etc) would be pointless to implement. In essence, your suggestion in this regard would be a bad idea, as the benefits offered over bare-metal coding would be few and, quite likely, trivial. To put it another way: libcartreset already does this. Duplicating it's role would be a bad idea.
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113664 - tepples - Fri Dec 29, 2006 3:32 pm

nornagon wrote:
Also -- why do you need to run multiple apps at once on the DS? Unless, like I said before, it's for IRC/SSH/etc., which dslinux does pretty decently.

OOPMan made some excellent points. As I see it, DSLinux's lack of a GUI is another big reason. Some people think it would be easier to start from scratch than to shoehorn uCLinux + X + app into 4 MiB (for M2, SC Rumble, or SLOT-1 cards). In addition, an OS designed for running games would make it easy to add background music to your game by running a Vorbis player in the background.

OOPMan wrote:
At the moment DS development is hindered by the conflict between gba_nds_fat and libfat. Some developers work with gba_nds_fat, or one of it's numerous peculiar variants (Another problem in itself), and older version of devkitPro while other developers make use of libfat and use the more recent version of devkirPro. This is not a good thing.

The issue is that the most recent binary version of devkitPro isn't compatible with all the features of libfat due to lack of space in the devoptab, and wintermute has given no indication that he has made any progress toward devkitPro R20.

nornagon wrote:
Why has multithreading become a part of this? It's not an attempt to replace DSLinux, with its SSH and IRC and multitasking capabilities, right? The aim is to provide a very thin compatability layer for programs -- essentially, flashcart access unification.

Isn't that what DLDI is for?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#113678 - Inopia - Fri Dec 29, 2006 6:03 pm

@oopman: I agree with you that we shouldn't start cramming GUI stuff into the kernel, that's why I proposed these things should be in user mode.

#113690 - OOPMan - Fri Dec 29, 2006 7:47 pm

Inopia wrote:
@oopman: I agree with you that we shouldn't start cramming GUI stuff into the kernel, that's why I proposed these things should be in user mode.


Don't worry, I wasn't singling you out :-) There have been other GUI related posts but I would have to say your recent one was rather more grounded in reality than some ;-)

When it comes to GUIs my preferred system would be a CLI with natural language recognition and auto-completion. Maybe not realistic, especially not on a system like the DS, but fun for sure :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113694 - Mighty Max - Fri Dec 29, 2006 8:31 pm

I'm currently cleaning up and commenting the sources for the kernel. There are a several ToDo's in there. That should make it possible for everyone to take a look and extract the features wanted.

Virtual Memory and the threading basics are complete, dynamically loading is still in a testing state. So grab you knifes and prepare to cut the parts out ;)
_________________
GBAMP Multiboot

#113696 - OOPMan - Fri Dec 29, 2006 9:11 pm

Nice work Max. Hope to take a look at sources once they're released :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#113722 - Mighty Max - Fri Dec 29, 2006 11:46 pm

I have packed the whole project folder into http://mightymax.org/virtual16.zip

Some copies in the makefiles are hardcoded to /F/ (copies to my CompactFlash) you might want to remove thos copies. Other then this, please report back when you have problems compiling.

Folders/Parts:
- arm7: arm7 binary that starts with the loader and will be used from the kernel
- arm9/arm9_gbfs: simply loads the .knl into siwram and jumps to it.
- kernel: the arm9 kernel, doing all the nasty stuff
- userMode: contains the main.dle template, and the .o(elf) => .dle converter
- virt_16: data needed on the CF card by the FAT version
_________________
GBAMP Multiboot

#113724 - nornagon - Sat Dec 30, 2006 1:06 am

OOPMan wrote:
The key I/O bottleneck I was referring to was media device access.


... Which should really only be used in short spurts, such as loading/saving or directory browsing.

OOPMan wrote:
CPU cycles are plentiful, even on a low-power processor such as the ARM7/9. Wasting a few here and there to support the underlying functions of an OS is not nearly as huge a performance hog as those cycles spent handling I/O from various devices.


So what you're saying is that the OS will be fast due to the fact that it does no flashcart I/O in and of itself. Okay.

OOPMan wrote:
One is to ensure that applications using multi-threading do so in a predictable fashion. If every app used it's own multi-threading library then multi-threading would most likely not be reliable or predictable.


... But multithreading apps that don't use the OS would still work fine without the OS. If an app neads multithreading, it uses a multithreading library. The multithreading libraries available work.

OOPMan wrote:
By not supporting multi-threading at the OS level one forces developers to use application-level multi-threading libraries.

Which works just fine without an OS.

OOPMan wrote:
For one, unless someone decides to write a single monolithic media application that plays music, performs file I/O and integrates whatever other arbitrary features users desire


... like DSLinux...

OOPMan wrote:
then the idea of an OS that lacks multi-tasking and multi-threading falls down. If such an app is not written, users will inevitably become frustrated. They want to do tasks X, Y and Z and app A, rather the load app A to perform task A, app B to perform task Y and app to perform task Z in a linear or possibly alternating fashion.


Or they could use DSLinux. Which works fine. (Though still requires a little wizardry.)

OOPMan wrote:
Is it possible to rectifiy this problem? Yes. As explained above. File I/O is a costly operation, where as the music playback is likely to be more CPU intensive than anything else. By threading the file I/O and the music playback you are able to allow the user to seemingly play music and perform file I/O at the same time. This satisfies the user's desire to do both, even though the tasks themselves are executing linearly.


So is the user playing music and reading an ebook at the same time, or is he (she) using an ebook reader that plays music? The difference between multitasking and multithreading is one that should be made (I seem to have failed at that, I'll try harder next time :P)

OOPMan wrote:
Implementing such multi-threading on a per-application basis is costly however. On the other hand, writing multi-threaded code in the knowledge that the large majority the work involved in getting such code to work well is handled by the OS makes it easier for individual developers to take the plunge and multi-thread their code.


How many apps benefit from multithreading? So far as I can see, the uses would be pretty limited: it could be used for background encodes/decodes, and it could be used to perform file i/o while doing other things. There are other uses, but most of them much less useful than those two.

OOPMan wrote:
The DS is an asymmetric, dual-processor system. However, I'm guessing that a significant number of developers out there (This applies to the PALib crowd especially, I'm guessing) treat it as a uni-processor system, relying on a pre-supplied ARM7 binary to handle various tasks (Sound, Wifi, Input, etc...). While this may be an easy way to dip one's toe in the water with regards to coding for the DS, it's not without it's problems. For a start, it's wasteful. Both Mighty Max and Hermes have illustrated that it is possible to run generic code on both the ARM7 and the ARM9 at the same time. Why then does a large body of the homebrew developer scene largely ignore at least one of the processors? I'd imagine it's because the work involved in getting an individual program to use the ARM7 and the ARM9 in a useful, stable fashion is difficult.


Having recently done just that, I can vouch for its difficulty. The trick, though, is not just getting code to run on the arm7 (and shuttle data back and forth in just the right manner), it's also making sure your parallelism works right. I'll draw from my experience with World of Sand: I moved processing of some of the field to the arm7. Essentially, I split the field in two every frame and handed one chunk to the arm7, letting the arm9 do the rest. Then I'd run the algo over the bit in the middle, and display the result. The problem was that, due to the way the algorithm works, the top part of the field always has to be run *after* the bottom part; there's no way of having both processors working on the same frame at the same time. The solution (thanks sgstair) is to have the arm7 actually process the next frame, while the arm9 is processing the current one, so by the time the arm9 finishes processing this frame, there's always some data left for it from the arm7 which it can continue on from.

You'll admit that's not very easily genericizable.

OOPMan wrote:
In my opinion, support for multi-threading and multi-tasking is essential. To ignore one or the other would lax.

Multi-threading, I see now, is pretty essential. I'm still skeptical about the usefulness of multitasking.

Quote:
With regards to implementing the OS as an application that loads and unloads completely as required...


D'oh, you missed what I was saying -- I meant, provide the app with a callout to the OS that unloads the app and lets the user select another app. That means you don't have to poweroff, which people seem to hate doing for some reason.

#113727 - Sausage Boy - Sat Dec 30, 2006 1:56 am

Quote:
D'oh, you missed what I was saying -- I meant, provide the app with a callout to the OS that unloads the app and lets the user select another app. That means you don't have to poweroff, which people seem to hate doing for some reason.


But what happens when you want to listen to music and play a nice little game of tetris at the same time?
_________________
"no offense, but this is the gayest game ever"

#113737 - nornagon - Sat Dec 30, 2006 5:45 am

Chances are the tetris game has background music.

#113738 - Firon - Sat Dec 30, 2006 6:09 am

But what if you don't like the game's music? :P

#113743 - nornagon - Sat Dec 30, 2006 6:52 am

Better hope it comes with source.

#113746 - HyperHacker - Sat Dec 30, 2006 8:25 am

Why multitask?
So we can, uh, do multiple tasks at once. For example, play music while reading text files, or copy between multiple instances of some sort of editor. I don't know how many times people have whined that Moonshell and DSO are only able to do one thing at a time.

Why not use DSLinux?
It's not practical. DSLinux was only meant as a tech demo to say "hey, we can run Linux on the DS", much like the NetBSD Toaster. It's akward to use and doesn't do a lot of things well; for example, last time I tried to play an MP3 it only played one of every 8 seconds and would crash the OS if I mistyped the file name.

Why dynamic link?
One, it saves space. Two, it eliminates the problem that Program X doesn't work with Card Y because Card Y is brand new and Program X was abandoned months ago. Similarly, if Program X has some sort of touch-screen problem for example, updating a file fixes it and all other programs, even if the original author isn't around anymore.

nornagon wrote:
OOPMan wrote:
The key I/O bottleneck I was referring to was media device access.


... Which should really only be used in short spurts, such as loading/saving or directory browsing.

Should, but can't always. MP3 players, for example, generally stream the file from disk as buffering ~3.5MB of it into memory at a time would take ages, meaning slow start-up times and a long pause every time the buffer is emptied. Try DSOrganize's streaming audio feature for an example of how well this works.
_________________
I'm a PSP hacker now, but I still <3 DS.

#113756 - nornagon - Sat Dec 30, 2006 9:52 am

HyperHacker wrote:
Why multitask?
So we can, uh, do multiple tasks at once. For example, play music while reading text files, or copy between multiple instances of some sort of editor. I don't know how many times people have whined that Moonshell and DSO are only able to do one thing at a time.


But is that a feature that will draw homebrew developers into developing with this OS?

HyperHacker wrote:
Why not use DSLinux?
It's not practical. DSLinux was only meant as a tech demo to say "hey, we can run Linux on the DS", much like the NetBSD Toaster. It's akward to use and doesn't do a lot of things well; for example, last time I tried to play an MP3 it only played one of every 8 seconds and would crash the OS if I mistyped the file name.


DSLinux works very well for what I use it for (mostly); that is, SSH, IRC and web browsing with links. There's the occasional hiccup but less every week.

[quote="HyperHacker]Why dynamic link?
One, it saves space.[/quote]

Uh, what? Where does it save space, on your SD card? You're honestly worried about the few extra kB of space per program that linking statically consumes? On a 256MB+ card? Come again?

HyperHacker wrote:
Two, it eliminates the problem that Program X doesn't work with Card Y because Card Y is brand new and Program X was abandoned months ago. Similarly, if Program X has some sort of touch-screen problem for example, updating a file fixes it and all other programs, even if the original author isn't around anymore.


Agreed, a good thing.

HyperHacker wrote:
Should, but can't always. MP3 players, for example, generally stream the file from disk as buffering ~3.5MB of it into memory at a time would take ages, meaning slow start-up times and a long pause every time the buffer is emptied. Try DSOrganize's streaming audio feature for an example of how well this works.


Okay, fair. How can this easily be put in a multithreading context? Are you just going to read the data during VDraw or when the program's otherwise idle?

#113759 - Mighty Max - Sat Dec 30, 2006 10:35 am

Quote:

Uh, what? Where does it save space, on your SD card? You're honestly worried about the few extra kB of space per program that linking statically consumes? On a 256MB+ card? Come again?


When loaded every statical linked binary has to be in main ram for cards like the gbamp or slot-1 soltutions. There is no need to have a mpeg decoder when not playing mpegs, no need for a menucode where the menu is disabled, no need for having the games AI code when in menu etc ... that can easily sum up several 100kB.

And then there are those apps you talked about that really pushes the DS hardware. RAM is an expensive resource on the DS. Just think about why there is an Opera Card



And actually, i dont try to draw anyone to use this. I really don't care if anyone will use it later. Im doing this to proof it to myself that i'm able to do so. (See the my first post within this thread and the attraction of the impossible/difficult to do decently to me)
_________________
GBAMP Multiboot

#113760 - Firon - Sat Dec 30, 2006 10:39 am

HyperHacker wrote:

Two, it eliminates the problem that Program X doesn't work with Card Y because Card Y is brand new and Program X was abandoned months ago.


DLDI pretty much solves that problem.


Last edited by Firon on Sat Dec 30, 2006 1:07 pm; edited 1 time in total

#113766 - nornagon - Sat Dec 30, 2006 12:51 pm

Mighty Max wrote:
And actually, i dont try to draw anyone to use this. I really don't care if anyone will use it later. Im doing this to proof it to myself that i'm able to do so. (See the my first post within this thread and the attraction of the impossible/difficult to do decently to me)


Ahhhhh, well then, that makes it a completely different beast. Doing things Because You Can is cool; I was thinking you were doing this with the view of getting homebrew coders to use it near-universally.

I'm interested to see what happens :)

#113776 - tepples - Sat Dec 30, 2006 3:28 pm

nornagon wrote:
OOPMan wrote:
For one, unless someone decides to write a single monolithic media application that plays music, performs file I/O and integrates whatever other arbitrary features users desire

... like DSLinux...

Some operating systems are light. Other operating systems are heavy. Because this project is lighter than DSLinux, it is more feasible to put a GUI on top of the basics and have it all fit into 4 MB for people who have a GBA Movie Player or SuperCard Rumble series, or people who have a SLOT-1 card and live in those territories where the Opera browser is not released.

Quote:
Or they could use DSLinux. Which works fine. (Though still requires a little wizardry.)

How much more RAM would be needed to get X working on DSLinux? As I see it, the point of this project is not to create a GUI itself but to create an operating system that leaves enough room in RAM for a GUI.

Quote:
So is the user playing music and reading an ebook at the same time, or is he (she) using an ebook reader that plays music?

Applets in the Java platform implement an interface that extends java.lang.Thread. Mac OS 1 through 6 used a similar interface for the cooperatively-multitasked "desk accessory" apps that were available on its start menu. (Mac OS 7 and later put each desk accessory in its own process and generalized the start menu to cover shortcuts to any application.)

Quote:
The difference between multitasking and multithreading is one that should be made (I seem to have failed at that, I'll try harder next time :P)

Linux has no difference. At one point in Linux's development, threads were merely processes that shared memory.

Quote:
How many apps benefit from multithreading? So far as I can see, the uses would be pretty limited: it could be used for background encodes/decodes, and it could be used to perform file i/o while doing other things. There are other uses, but most of them much less useful than those two.

Games can use background tasks to decompress textures that they have loaded. They can use background tasks to compute . I believe The Ur-Quan Masters does the latter, as it's a port from the thread-heavy 3DO operating system.

Quote:
OOPMan wrote:
I'd imagine it's because the work involved in getting an individual program to use the ARM7 and the ARM9 in a useful, stable fashion is difficult.

Having recently done just that, I can vouch for its difficulty. The trick, though, is not just getting code to run on the arm7 (and shuttle data back and forth in just the right manner), it's also making sure your parallelism works right.

You're right that a lot of homebrew developers have little experience in programming where multiple threads cooperate closely. For one thing, most of them have only one CPU in their machines, as dual core x86 CPUs are comparatively recent. But it's good practice, as one needs to think parallel to hope of getting a job at a company with a console devkit.

Quote:
Multi-threading, I see now, is pretty essential. I'm still skeptical about the usefulness of multitasking.

Multitasking is useful in this OS for the same reason it is useful in DSLinux. We're just trying to get it done using less RAM.

nornagon wrote:
Firon wrote:
nornagon wrote:
Sausage Boy wrote:
But what happens when you want to listen to music and play a nice little game of tetris at the same time?

Chances are the tetris game has background music.

But what if you don't like the game's music? :P

Better hope it comes with source.

As far as I can tell, no Tetris? product has come with source code. And yes, a lot of people over on TC hate listening to the Tetris DS remix of Super Mario Bros. over and over.

HyperHacker wrote:
Similarly, if Program X has some sort of touch-screen problem for example, updating a file fixes it and all other programs, even if the original author isn't around anymore.

That's a good thing in general, but operating system maintainers have to watch out for the DLL hell problem. If subsequent versions of the operating system change the interface's semantics behind an application's back, the application will misbehave.

nornagon wrote:
HyperHacker wrote:
Why dynamic link?
One, it saves space.

Uh, what? Where does it save space, on your SD card? You're honestly worried about the few extra kB of space per program that linking statically consumes?

It saves space in RAM. If you need one font at a given point but not another, you can unload the fonts you're using to save memory. Likewise, if you need the rich text editor library at a given point, but you don't need the Vorbis decoder library, you can unload the Vorbis decoder to make more room for the rich text editor. Likewise with the Vorbis decoder vs. the MP3 decoder vs. the MOD decoder.

nornagon wrote:
HyperHacker wrote:
MP3 players, for example, generally stream the file from disk

Okay, fair. How can this easily be put in a multithreading context? Are you just going to read the data during VDraw or when the program's otherwise idle?

As of right now, Luminesweeper's GSM streaming and decoding run during unused time in vdraw.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#113802 - Mighty Max - Sat Dec 30, 2006 9:19 pm

For the ones that test in Desmume, i located (but didnt exactly pin down) another bug in it, handling STM/LDM with writeback including the writeback register (like LDMIA sp! {....,sp,...})

Causing the asm() sections (which use such instructions in the overhead) in main.dle to create a sp corruption that will cause false jumpes and a reset request after some time.

Unfortunally the attribute naked does not create naked asm code, but instead tries to write at a then uninitialized r11 .... anyhow, the fix:

Replace these functions:
Code:


void __attribute((naked)) printChar__(void) {
   asm volatile (
      ".word 0xE1A03002   \n" /* mov r3,r2 using that creates a header? in devkitARM, so hide opcode in .word */
      ".word 0xE1A02001   \n" /* mov r2,r1 */
      ".word 0xE1A01000   \n" /* mov r1,r0 */
      ".word 0xE3A00001   \n" /* ldr r0,=1 */
      "swi 0x010101   \n"
   ) ;
   asm volatile (
      "BX lr         \n"
   ) ;
}
typedef void (*printChar_Type)(int x,int y,char ch) ;
printChar_Type printChar = (printChar_Type)&printChar__ ;

/* createThread
   will call system service swi
      function r0 = 3
         r1 = entrypoint of the thread
         r2 = size of ram to be reserved for stack
         r3 = parameter passed to the entrypoint
*/
//void __attribute((naked)) createThread(unsigned long entryPoint,unsigned long stacksize,unsigned long param) {
void __attribute((naked)) createThread__(void) {
   asm volatile (
      ".word 0xE1A03002   \n" /* mov r3,r2 using that creates a header? in devkitARM, so hide opcode in .word */
      ".word 0xE1A02001   \n" /* mov r2,r1 */
      ".word 0xE1A01000   \n" /* mov r1,r0 */
      ".word 0xE3A00003   \n" /* ldr r0,=3 */
      "swi 0x00      \n"
   ) ;
   asm volatile (
      "BX lr         \n"
   ) ;
} ;
typedef void (*createThread_Type)(unsigned long entryPoint,unsigned long stacksize,unsigned long param) ;
createThread_Type createThread = (createThread_Type)&createThread__ ;

void __attribute((naked)) idle(void)  {
   asm volatile(
      "ldr r0,=0      \n"
      "swi 0x00      \n"
      "BX lr         \n"
   ) ;
} ;


That's just for desmume compatibility right now. If you don't use them with desmume, you are fine with the old version.
_________________
GBAMP Multiboot

#113824 - wintermute - Sun Dec 31, 2006 1:43 am

You'd be much better off placing these functions in .s files where the compiler can't interfere with them.

I assume by header you mean a function prologue.
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#113837 - HyperHacker - Sun Dec 31, 2006 4:59 am

tepples wrote:
HyperHacker wrote:
Similarly, if Program X has some sort of touch-screen problem for example, updating a file fixes it and all other programs, even if the original author isn't around anymore.

That's a good thing in general, but operating system maintainers have to watch out for the DLL hell problem. If subsequent versions of the operating system change the interface's semantics behind an application's back, the application will misbehave.

Simple solution: Don't do this. If you're writing the library, write your functions such that they continue to work as expected with old versions. If you're writing an app that uses it, DO NOT RELY ON OBVIOUSLY INCORRECT BEHAVIOUR. You'd think this would be common sense...

Quote:
nornagon wrote:
HyperHacker wrote:
Why dynamic link?
One, it saves space.

Uh, what? Where does it save space, on your SD card? You're honestly worried about the few extra kB of space per program that linking statically consumes?

It saves space in RAM. If you need one font at a given point but not another, you can unload the fonts you're using to save memory. Likewise, if you need the rich text editor library at a given point, but you don't need the Vorbis decoder library, you can unload the Vorbis decoder to make more room for the rich text editor. Likewise with the Vorbis decoder vs. the MP3 decoder vs. the MOD decoder.

Yes, but I was actually referring to the cards themselves. I have 28 .nds files on my card, which means 27 redundant copies of at least the libnds routines. If these apps use FAT then that's additional redundant copies of gba_nds_fat and/or libfat. If you add up all the various libraries and shared routines/resources DS apps use, and have a fair number of them, you could be looking at at least a few hundred KB. On such small cards (as little as 32MB) it's not uncommon to be pressed for space; with a 128MB card, a very small subset of my music collection filled it almost entirely, leaving about 1MB free at any given time.


BTW, I forgot to mention last time... people keep expecting a fancy GUI, windowing system, etc... that's not going to happen, but some form of GUI is necessary. I've already explained how I think it should be done, but I'll point out a key factor again: On a 256x192 screen, a windowing system is impractical. Apps should simply have zero to two 256x192 areas to draw in, minus however much space the shell uses for a taskbar/whatever, and possibly windows tied to these for things like toolboxes (effectively child windows that are only visible above the app's display area).
_________________
I'm a PSP hacker now, but I still <3 DS.

#113844 - tepples - Sun Dec 31, 2006 7:21 am

HyperHacker wrote:
tepples wrote:
operating system maintainers have to watch out for the DLL hell problem. If subsequent versions of the operating system change the interface's semantics behind an application's back, the application will misbehave.

Simple solution: Don't do this. If you're writing the library, write your functions such that they continue to work as expected with old versions. If you're writing an app that uses it, DO NOT RELY ON OBVIOUSLY INCORRECT BEHAVIOUR. You'd think this would be common sense...

What is obvious to one may not be obvious to another. Developers rely on behaviors, not knowing that they are incorrect. Look at Windows backward compatibility to see a hack on top of a hack on top of a hack.

Quote:
I have 28 .nds files on my card, which means 27 redundant copies of at least the libnds routines. If these apps use FAT then that's additional redundant copies of gba_nds_fat and/or libfat. If you add up all the various libraries and shared routines/resources DS apps use, and have a fair number of them, you could be looking at at least a few hundred KB. On such small cards (as little as 32MB) it's not uncommon to be pressed for space

Nowadays, 32 MB isn't common except for pure NOR cards in SLOT-2. More common are NAND cards an order of magnitude or more bigger. I can pick up 1 GB SD card for under $22 (incl. sales tax) at an office supply store. I've upped my storage, so up yours ;-)

Quote:
On a 256x192 screen, a windowing system is impractical. Apps should simply have zero to two 256x192 areas to draw in, minus however much space the shell uses for a taskbar/whatever, and possibly windows tied to these for things like toolboxes (effectively child windows that are only visible above the app's display area).

I agree, for the most part. But there should be a provision for toolboxes that can slide in or fade in on demand. If anything, pull-down menus are exactly that.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#113846 - Mighty Max - Sun Dec 31, 2006 8:46 am

wintermute wrote:
You'd be much better off placing these functions in .s files where the compiler can't interfere with them.

I assume by header you mean a function prologue.



Yes, and i would, but at the current state of the dynamical loading just a single .o file is loaded, and putting it in an own .s file would create a second .o ;)
_________________
GBAMP Multiboot

#113871 - tepples - Sun Dec 31, 2006 5:45 pm

You can compile several .c files to assembly language (gcc -S D5.c -o D5.s) and then compile multiple .s files into one .o file.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#113878 - Mighty Max - Sun Dec 31, 2006 6:24 pm

Thanks Tepples

... i should really read up on the command line options / Makefiles :D



:edit: just added prefetch abort code to my local desmume (and ofcourse sent the changes in again) hope to get swapping working on desmume at some time too, instead of the dirty behaviour to detect desmume and the gba romspace as wram replacement. And it massively helps to debug :D
_________________
GBAMP Multiboot

#113892 - wintermute - Sun Dec 31, 2006 8:35 pm

Mighty Max wrote:
wintermute wrote:
You'd be much better off placing these functions in .s files where the compiler can't interfere with them.

I assume by header you mean a function prologue.



Yes, and i would, but at the current state of the dynamical loading just a single .o file is loaded, and putting it in an own .s file would create a second .o ;)


It's reasonably easy to write a loader for fully linked relocatable code - chishm uses such a system for the dldi patching.

Personally I'd think writing a loader for an elf format object would be a bit more hassle.

Then again you're going to have to deal with shared objects for this system I guess?
_________________
devkitPro - professional toolchains at amateur prices
devkitPro IRC support
Personal Blog

#113921 - chishm - Mon Jan 01, 2007 4:51 am

wintermute wrote:
It's reasonably easy to write a loader for fully linked relocatable code - chishm uses such a system for the dldi patching.

Unfortunately, none of the libraries included with DevkitARM are compiled for postion-independence (-fPIC). This makes relocating anything that has a large reliance on them (including C++ code -- the global constructor and destructor functions aren't position-independent) non-trivial. Also, the current link-sripts need fixing for EABI compiled position-independent code.
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com

#114068 - Mighty Max - Wed Jan 03, 2007 2:08 pm

Probably better to do so, yes. The .o system was easiest to check right now without digging deep into the specs/ld scripts.


Anyhow, i have the last days worked on the arm7 side of the system. Access to wram is a bit difficult now, as the arm7 doesnt know which page is blended at the physical address, like the arm9 does. It could be solved by mutexes, but this would slow down the memory swapping.

Theefor i decided to use VRAM to extend the memory available on the arm7 from 32 to 160kB. The wifi recvs are stored there and can be swapped to the arm9 by xchanging the allocation for Bank C vs Bank D (one is allways arm9 0x06040000, the other arm7 blended) ... could be done by one also (hold arm7 while vram is not blended in) , but wanted to have as much speed as possible for now (as im trying to get a wifi stack done).
_________________
GBAMP Multiboot

#114072 - nornagon - Wed Jan 03, 2007 3:32 pm

@Mighty Max: So what if we need that vram for, you know, displaying things? :)

I'm interested in getting some dynamic code loading stuff happening for World of Sand in order to manage interchangeable physics systems. It's pretty tricky to manage on my own; how feasible would it be for me to hook into this OS of yours to do that?

#114076 - Mighty Max - Wed Jan 03, 2007 5:01 pm

I should have put more hints to "for now" ;)
Page lockdowns and system level pagechecking on access are not done yet done, so using wram access from arm7 would have produced more errors then what i expect it to help me remotely debug the system.

I would recomment a scripting system (i.e. lua) for your purpose. The speed malus can easily avoided for the sand, as you want to do the same processing to a lot of object instances.

I would declare c functions for calculating over the set of all particles of one kind (like SIMD instructions) and have the script just call these functions to process them all at a single run. (the few calls the script has to make shouldnt take too much time)

This would allow you to not only have dynamically loaded physics but also to change the physics on the fly.
_________________
GBAMP Multiboot

#114088 - HyperHacker - Wed Jan 03, 2007 10:12 pm

tepples wrote:
Nowadays, 32 MB isn't common except for pure NOR cards in SLOT-2. More common are NAND cards an order of magnitude or more bigger. I can pick up 1 GB SD card for under $22 (incl. sales tax) at an office supply store. I've upped my storage, so up yours ;-)

Lol. Where are you shopping? 1GB cards are still bloody expensive everywhere I've been in Canada.
_________________
I'm a PSP hacker now, but I still <3 DS.

#114089 - Rockviech - Wed Jan 03, 2007 10:23 pm

look at ebay, 2gb mini sd 30? here

#114097 - tyraen - Wed Jan 03, 2007 11:35 pm

Check [Please ask SimonB to make a topic in Retailer Feedback for this retailer. -- MOD]

I see a 1GB there for <$50, mind you there's tax and shipping. If you're on their newsletter I find they often have pretty nice deals, especially on SD where it's fairly old now.

#114107 - tepples - Thu Jan 04, 2007 1:28 am

HyperHacker wrote:
tepples wrote:
I can pick up 1 GB SD card for under $22 (incl. sales tax) at an office supply store. I've upped my storage, so up yours ;-)

Lol. Where are you shopping?

Sorry. Apart from the obvious "how do I run roms?", "where are you shopping?" is the most commonly asked question that we aren't allowed to answer:
SimonB wrote:
No promotion of any retailer outside the Retailer Feedback forum.

That's why I answer so generically.

I also shop in the United States, which has a (slightly) more valuable dollar.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#114121 - nornagon - Thu Jan 04, 2007 5:18 am

Mighty Max wrote:
I would recomment a scripting system (i.e. lua) for your purpose. The speed malus can easily avoided for the sand, as you want to do the same processing to a lot of object instances.

I would declare c functions for calculating over the set of all particles of one kind (like SIMD instructions) and have the script just call these functions to process them all at a single run. (the few calls the script has to make shouldnt take too much time)

This would allow you to not only have dynamically loaded physics but also to change the physics on the fly.


Ahem. Good luck getting a lua function to run over 49,152 pixels twenty times a second on the DS. It's just not going to work like that.

#114135 - Mighty Max - Thu Jan 04, 2007 11:32 am

Read again nornagon: you need a lua script that runs ... what 10 instructions once for ALL particles at once.

Iterate for the set, not for the particle in lua. Applying the given math by the lua to all would be the job of the c code.
_________________
GBAMP Multiboot

#114143 - nornagon - Thu Jan 04, 2007 2:55 pm

My 'particles' are just pixels, nothing more. I keep a 42K (192*256*2bytes) buffer and iterate over that in different ways (left-to-right/right-to-left) and perform an action of some kind based on the palette index of the pixel. The action usually involves some calls to a random number generator and a few if statements, followed by a couple of memory sets and a return. I'm not quite sure what your direction is in telling me to use lua.

#114146 - Mighty Max - Thu Jan 04, 2007 3:58 pm

You are currently iterating like (PseudoCode)

Code:

for (x=0;...;x++) {
   for (x=0;...;x++) {
      calculationStep0(x,y) ;
      ....
      calculationStepN(x,y) ;
   }
}


Doing lua at that point for calculationSteps is not suitable, yes.

However instead of doing all pixels complete in one iteration step, you can do a single step in the calculation for all pixels before doing the next step.

I.e. lets say you defined the following c functions to walk through all pixels:
- Set,Add,Sub,Mul,Div Constant
- Set,Add,Sub,Mul,Div Component
- SelectAll,SelectMatching(component,compareValue,relation)

now the lua script could look like
Code:

function FRAME(num)
    AddConstant(YComponent,-9.81)               -- apply linear gravity
    SelectMatchin(YComponent,0,LESS_THEN)  -- if Y < 0
    SetConstant(YComponent,0)                     -- dont move further
    SelectMatchin(YComponent,0,GREATER_THEN)  -- if Y >0
    AddComponent(XComponent,Randomizer) -- do random move
end


It is still more work for the DS to do (multiple looping through the same dataset) but it is much faster then doing the lua for every pixel and allows modifying the physics without access to a compiler.

For loading precompiled i'd point to chishm's method atm. Or just simply reserve a set region, and compile+link the physic functions to use that not changing base address. (You just need to create the specs/ld and crt0)
_________________
GBAMP Multiboot

#114215 - nornagon - Fri Jan 05, 2007 12:00 pm

The pixels have no velocity. They only thing they have is color and a 'knowledge' of the eight pixels immediately surrounding them.

My code looks more like this:

Code:

void calculate(u8* buf) {
  static bool counter = false;
  for (int y = 190; y > 0; y--)
    for (int x = counter?1:254; counter?x<255:x>0; counter?x++:x--)
      doWorkOn(buf, x, y);
  counter = !counter;
}


That's just a rough approximation, but it's more or less how things happen.

I've decided to go the path of dynamic recompilation, though. Doesn't seem that hard now that some people have told me how to do it :P

#121119 - SpacedCowboy - Fri Mar 09, 2007 4:18 am

So, this looked really interesting, but seems to have withered away ? Are people still working on it ?

Just curious :-)

Simon

#121133 - OOPMan - Fri Mar 09, 2007 11:09 am

Well, Might Max released the course to his V16 proto-OS, but I think he's been a bit busy of late and isn't planning to take V16 too much further...

I recently moved and am getting settled in a new job, so the only DS-related things I've been doing of late have been pretty minor and low-turbulence :-)

As for the others, I'm not sure :-)

I STILL want to implement an exokernel on the DS at some point though, but I need to learn a lot more about OS programming before I can do that :-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#121196 - SpacedCowboy - Sat Mar 10, 2007 3:05 am

So I was interested, but not really following technically what was being said. Where does one find the technical docs for controlling things like 'mirroring', the memory-management unit (the MPU ?), etc. Are these ARM-specific things, or NDS-specific ones ? (respectively, easy to find docs on, and not-necessarily-easy :-)

I'm assuming that mirroring is just the same RAM appearing in different memory locations, but it sounds like there's some control being exerted over it, to our advantage, which is intriguing...

You're all using devices that use the GBA port, right ? I'm currently using a DS-X cartridge, and don't seem to have access to the GBA memory area... Perhaps I ought to get an M-3/G-6 (or whatever the current best-way-to-do-it-is. Suggestions welcome :-)

Simon.

#121595 - OOPMan - Tue Mar 13, 2007 10:17 am

Hmmmm, well, I think the mirroring was a clever thing which Might Max worked out himself, so you'd probably want to talk to him about it.

As for more general NDS hardware stuff, various resources are available. Specifically for the NDS, we have the hardware specs over at GBATek.

With regards to the ARM, there are various books and manuals available that detail programming for ARM-based systems.

With regards to devices, no, things have diversified a lot, so having a DS-X is no longer a bad thing. With regards to the OS thing, nothing Max did with V16 actually required a SLOT-2 device...
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#121713 - SpacedCowboy - Wed Mar 14, 2007 6:33 am

Ok, so I started to try and understand what's going on here in the 'virtual16' code. Hoping MightyMax can chime in and help me ... I've done assembly-programming before (a couple of decades ago!) but never ARM assembly. I guess this is as good a way as any to start :-)

I was looking at swi.s, and the thread-store/restore registers code, specifically:

Code:

      ...
      // store r11 - r0 in reverse order, the values are on stack
      LDR r1,[r13,#0x30]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x2C]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x28]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x24]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x20]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x1C]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x18]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x14]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x10]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x0C]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x08]
      STMIA r0!,{r1}
      LDR r1,[r13,#0x04]
      STMIA r0!,{r1}
      
      // load previous mode r13,r14 and store them to [r0] and following
      MRS r3,spsr
      AND r2,r3,#0x1F
      CMP r2,#MODE_USR
      LDREQ r2,=MODE_SYS
      MRS r3,cpsr
      BIC r3,r3,#0x1F
      ORR r2,r2,r3
      MRS r3,cpsr
      MSR cpsr,r2
   
      STMIA r0!,{r13}
      STMIA r0!,{r14}
      
      MSR cpsr,r3
      
      // store return address as previous mode r15
      LDR r1,[r13,#0x38]
      STMIA r0!,{r1}
      // store r12
      LDR r1,[r13,#0x34]
      STMIA r0!,{r1}
      ...


I have a question about that. Given that the thread-storage structure is...
Code:

//   typedef struct THREADCONTEXT {
//      unsigned long      bios_stack,
//                     bios_return,
//                     r11,r10,r9,r8,r7,r6,r5,r4,r3,r2,r1,r0,
//                     r13,r14,r15,
//                     r12,
//                     cpsr,
//                     cp15_status ;
//   } THREADCONTEXT, *LPTHREADCONTEXT ;      


... it looks to me as though the storage of r12 ought to be from offset 0x3C, not 0x34, right ? From interpreting the way he's using the offsets, 0 appears to be at the top of the structure, (bios_stack), so r12 ought to be *after* r15, not before it ?

The thing is, that if that is right, he'd be over-writing r14 (the link register), and if you do that, I'd expect chaos to ensue. Obviously, it does actually work, so I'm wrong - I just don't see why [sigh]. I'm confused, and I thought I was starting with the simple stuff :-( I'm going to bed :-)

#121721 - OOPMan - Wed Mar 14, 2007 8:34 am

Hehehehe, yeah, those ARM manuals could come in use around about now...

There's also a very good ARM assembly tutorial that's linked to from the stickied Tutorials thread.

Good luck. Hopefully Max will chime in and help you. You could always PM him though ;-)
_________________
"My boot, your face..." - Attributed to OOPMan, Emperor of Eroticon VI

You can find my NDS homebrew projects here...

#121729 - strager - Wed Mar 14, 2007 10:53 am

SpacedCowboy wrote:
Code:

      ...
      // store r11 - r0 in reverse order, the values are on stack
      LDR r1,[r13,#0x30]
      STMIA r0!,{r1}
      [snip]
      LDR r1,[r13,#0x04]
      STMIA r0!,{r1}
      
      [snip]
      
      // store return address as previous mode r15
      LDR r1,[r13,#0x38]
      STMIA r0!,{r1}
      // store r12
      LDR r1,[r13,#0x34]
      STMIA r0!,{r1}
      ...

Code:

//   typedef struct THREADCONTEXT {
//      unsigned long      bios_stack,
//                     bios_return,
//                     r11,r10,r9,r8,r7,r6,r5,r4,r3,r2,r1,r0,
//                     r13,r14,r15,
//                     r12,
//                     cpsr,
//                     cp15_status ;
//   } THREADCONTEXT, *LPTHREADCONTEXT ;      


Notice how the first two LDR instructions I didn't cut: They load r11 and r0. The first, r11, would be expected to load from an offset of 0x08, right? Well, it seems that the THREADCONTENT pointer is already offset by four (thus the bios_stack is at -0x04). Since the entire structure is shifted four bytes forward, the offset of r12 would be 0x38, as the offset of r15 would be 0x34. I think the author kinda switch those last two comments; either that, or I'm wrong and am reading this code wrong. Hey, it's very early in the morning and I haven't eaten since Monday. xD

Hope you find your problem,
Strager Neds

#121761 - SpacedCowboy - Wed Mar 14, 2007 5:15 pm

Fresh eyes in the morning ... I think I see what's going on now. Of course as soon as you see it, it's blindingly obvious [blush] :-)

store_context: is being called from
Code:

            
   softwarei_code:                 // swi:
      STMDB r13!,{r0-r12,r14}      //   store registers
      MRS r7,CPSR
      ORR r7,r7,#0xC0
      MSR CPSR,r7                  //   disable irq/fiq while system mode (will be unset when MOVS r15,r14)
      BL store_context             //   store thread context
      ...


... so the offsets are due to the STMDB statement a few opcodes before the call to store_context. r12 is indeed 1 word deeper in the stack than r11 (0x34), and r14 is the PC from the caller of softwarei_code (assuming it's been jump-and-linked, which I guess is the case), and is positioned at the next word (0x38).

I was confusing the source and destination addresses - r0 is just stepping through the thread-context struct, r1 is indexing out of the stack...

Note to self - wait until the morning before posting in future :-)

Simon.

#153969 - anomalous_underdog - Tue Apr 08, 2008 7:41 pm

have you guys checked out the source code for moonshell's msp plugin sdk? that's a working example of how to make a .nds file act as a dll.

http://mdxonlinemirror.dyndns.org/moonshell/files/moonshellpluginv51sdk.7z

if you look at your moonshell plugins folder, you'll see some .msp files, they're actually just .nds files renamed. they don't have a int main() function so they're not meant to be called directly.

#153990 - Creebo - Wed Apr 09, 2008 1:02 am

Why would you bump this? It's a year old :/

#153991 - Darkflame - Wed Apr 09, 2008 1:12 am

Moonshells plugs are just nds files?
Thats news to me...so, in theory,it might be possible to extend moonshells format support?
_________________
Darkflames Reviews --
Make your own at;
Rateoholic:Reviews for anything, by anyone.

#154002 - anomalous_underdog - Wed Apr 09, 2008 8:48 am

Darkflame wrote:
Moonshells plugs are just nds files?
Thats news to me...so, in theory,it might be possible to extend moonshells format support?


yup, I was surprised myself when I found out. look at the source code link I gave. he's got some really weird makefiles there, somewhat similar to what you guys are discussing


Creebo wrote:
Why would you bump this? It's a year old :/


Its a worthy cause. I approve of the DS having standardized homebrew launching code. I really hate it when I have to power off, then power on again just to switch to a different app, then do the same thing just to get back to what I was working on.

#154008 - thoduv - Wed Apr 09, 2008 10:34 am

Darkflame wrote:
Moonshells plugs are just nds files?
Thats news to me...so, in theory,it might be possible to extend moonshells format support?

No, they're not "nds files": they have a different header, are linked with a different linkscript, are compiled with different options (namely -fPIC, which allows code to be run from any place in memory) and have a different behavior (communicate with main program via callbacks).

#154018 - anomalous_underdog - Wed Apr 09, 2008 3:08 pm

thoduv wrote:
Darkflame wrote:
Moonshells plugs are just nds files?
Thats news to me...so, in theory,it might be possible to extend moonshells format support?

No, they're not "nds files": they have a different header, are linked with a different linkscript, are compiled with different options (namely -fPIC, which allows code to be run from any place in memory) and have a different behavior (communicate with main program via callbacks).


well then "nds" may not have been an accurate word to describe what I meant. i mean .msp files are simply arm compiled executable binary files, the same way .nds files are. of course they'd have a different makefile and options, they're meant to be called by other processes.

#161897 - hacker013 - Sun Aug 17, 2008 7:24 pm

I want to try to continue this project but when i try to compile it (have ported it to devkitARM r23) it gives an error that he don't knows the command "elf2dle" that is a program, and when i want to run it as a standalone windows gives an error that the config of that program is wrong. Can somebody help me with this??

EDIT:

I have it now that the compiler sees the program elf2dle and now it says: execvp: elf2dle: bad file number.

does anyone knows a solution for this??
_________________
Website / Blog

Let the nds be with you.