Writing Custom OS for OUYA

Started by
6 comments, last by henryksienkiewicz 10 years, 10 months ago

This is probably outside of the scope of GameDev.Net, but I thought I'd ask. I'd like to write a custom distro on Linux for the OUYA console. I've started looking at the "Linux from Scratch" project Nothing too fancy, just the following:

-Basic Linux kernel (EDIT: obtained from http://www.kernel.org)

-OES 2.0 driver support for Tegra 3 (EDIT: NVIDIA has drivers for this)

-Controller support API (I'm not sure where to go)

-Bluetooth, wi-fi, ethernet, and USB support (I think libusb should be enough)

-Pleasing visual interface in both 720p and 1080p

-An App Portal that'll act as a repository for apps, possibly as a store

EDIT: I'm sure I'm missing some things here.

The reason I'd want to go with this is so that people can build games natively in C/C++ without having to work with JNI. Java's a nice language, but it's geared towards RAD, not games. There's no stack allocation for complex data types as far as I know, and even though Java is ran natively in Android's implementation, I think the way C/C++ leaves memory management up to the programmer and C++'s operator overload are both quite valuable. They're also important to me.

I'm also assuming that more game programmers who would most-likely have a background in C/C++ already as opposed to Java. Picking up Java wouldn't be too much of an issue, but most of these programmers probably already have a large code base for existing games in C/C++ or are using an open source engine in those languages...

This also gives me a chance to make up my own user interface as OUYA's is getting some criticism in its current state. I'd like a chance to make my own user interface.

Advertisement
Hi,

I don't know details on OUYA hardware specs, but basically if you want to make an embedded Linux distribution one way to do it is to use some existing build systems like buildroot: http://buildroot.uclibc.org/ or open embedded: http://www.openembedded.org/ and customize them.
Such distributions are crafted in a way that it's possibly to make a "clean" customization - like by adding patches, component configurations and "recipes" to existing build system. You probably will want to use OUYA's patches to Kernel and possibly boot-loader (for early HW initialisation), or use their own build loader and integrate it with the build system and simply choose the components you like (and add your own).
In general there are really good free resources on porting Linux to embedded devices on free electrons: http://free-electrons.com/ .
Personally I had some good experiences with buildroot and openembedded (with buildroot being a bit more "clean" + it's much easier to start with, you even get ready configurations for running your distro in qemu environment).
Good thing is that it seems they already published the kernel (on github: https://github.com/ouya/ouya_1_1-kernel), you'll probably want to get some info on boot loader.

br and good luck,
hs.

Thanks! I'll have to check out buildroot. A been doing my research since I started this thread and my results have raised some questions.

I eventually realized the OUYA's Tegra 3 chip is really a system on a chip (SoC) like you'd find with Apple's devices, and not just a GPU. I keep forgetting this. It's really a slab of silicon with an ARC CPU, NVIDIA's GeForce GPU (Android-based version), and some shared memory modules attached to it. I downloaded the Linux kernel source from http://www.kernel.org, and found under the extract source's "arch" subdirectory, both two folders called "arm" and "arm64". Looking on NVIDIA's website revealed that it has a package that contains all of the drivers needed for Tegra 3 hardware as well. I think it might also have an entire Linux distro ready to go even, but I'm not sure.

I'll check out free-electrons.com for more info, and also look over the OUYA kernel. Thanks for pulling that info up! Also, is it common for Linux distros to have different kernels? I could see this being true since it seems quite common for software to be provided as source, and built on the Linux platform using a gcc compiler that outputs the executable in a proper readable format the OS can interpret.

Here's the questions I'm currently wondering:

1) How to build the Linux source for Tegra 3's ARM CPU (I'm going to check out buildroot for this answer)

2) How do I access the OUYA's hard drive to install it? Would it be possible to access it from my computer?

3) How do I configure the boot loader to recognize my OS once it's working and boot it automatically from the internal HDD?

4) How do I get the Tegra 3 drivers found on NVIDIA's website to work correctly?

5) Would it be ok to use the GPU to render the OS's GUI? This OS will only be designed to have 1 app launched at a time, and so I can unload the GUI resources at launch time, and reload them when the app closes. It's just a matter of OpenGL ES 2.0 programming for that once I have the proper hooks in place, I believe. Does this sound practical?

Not only this, but I'm pretty new to OS development or ASM. I'm sure this project is quite adventurous for me with my current knowledge, and there's some skills I'm going to have to learn before moving on.

Hi,
I don't have ready answers to most of your questions. I can give you some general tips though.
arch/ directory in Linux kernel tree contains various architecture-specific code (not whole kernel for given architecture), majority of Linux kernel code can be used on all architectures. Regarding arm vs arm64 - arm64 refers to new ARM architecture (ARMv8), which AFAIK is not yet very popular, in Tegra-3 you have CortexA9 MP Core, which is bases on ARMv7-A architecture, so you're more interested in "arm" arch sub-directory.

I doubt there's single distribution dedicated to Tegra itself, as Tegra is "only" a SoC - this determines which drivers for interrupt controller, memory, storage, ethernet, i2c, spi, usb, graphics etc. you will need. This is only part of the story, as there are board-specific components, which also affect the kernel image and needed drivers (like the flash layout and other peripherals connected to SoC over i2c or spi for example).

You can download linux sources, and try to configure and compile a kernel (without buildroot - which will automate things for you later on, when you will have a ready configuration and learn how to use it). With Linux you'll have a number of ready board-specific configurations, but usually when porting linux to embedded devices you will want to create your own configuration file which will have all needed drivers (this is probably already done for OUYA and most probably is part of their repo). You can get a lot of information about what's supported in Linux by simply running "make xconfig" or "make menuconfig" and reading help for various configuration options. Just make sure to export ARCH variable so you will get configuration options for ARM instead of your host architecture.

Note that using and creating Linux on embedded is slightly different compared to how it's done on PCs. For PC it's easy to prepare a generic kernel image which will run on most (if not all) of PCs. In embedded world you'll want to have a kernel which is tailored for your board, this also applies to the boot loader. Boot loaders here do what you would expect from typical "boostrap" bootloader which simply starts the OS, but also does pretty much ALL what is done by BIOS in PC (that is e.g. configuring your memory, initializing your CPU, caches, etc. - some things most of people receive for free and usually aren't even aware it happens ;] by simply booting their PC's. That's why boot loader is so important.

Deployment also differs and may be sometimes (depending on hardware) pretty risky without HW debugger. When you're developing your OS, e.g. on a board where U-Boot is used as boot-loader you usually have rootfs image mounted via NFS, and kernel image fetched over Ethernet. When you have your flash image ready with your distro you can flash it using boot-loader (if it has such functionality, U-Boot has), over the OS (if you have one running and properly configured so it allows that) or over JTAG (if you have hardware debugger, appropriate software & hardware (on board) in place and configuration for your board&SoC). I don't think OUYA has HDD btw, most probably you will want your rootfs to be read-only with your distro + some journaled fs NAND partitions for user's data. (But of course it's all up to you as the system designer).

From what I understood from the kickstarter project the authors claim the project is "open" thus most proabably you could try to get some documents from them regarding memory layout, board schematics, flash size, etc. it's usually helpful during development.
Regarding the renderer - I don't know how ambitious your plans are - but there are several "display servers" or graphical environments available for Linux, most popular is X.org which most probably supports Tegra's GPU out of the box (or with appropriate drivers from nvidia's site).

This is long story in general, you'll find a lot of usefull knowledge on free electrons, Internet, books, etc. I think it's too large topic to cover it in a forum post ;].
BTW - Android is actually Linux distro, for a good start you could try to get root there, mount a filesystem with your user-space applications over the network and try to get them running. Maybe even there's U-boot there with shell/console available over UART (getting this done on a commercial-ready product may require some soldering, but if you know someone specialized with electronics and have the schematics of the board, it should be easy to get it done, it's also possible without the board schematics, if you have datasheet of the SoC or a lot of time and patience), so you could start your OS by simply instructing the boot-loader/kernel to boot your OS over ethernet.

Good luck,
hs.

EDIT: Sorry for this lengthy wall of text, added some spacing before paragraphs ;-). Found some interesting stuff btw - there are high-res photos of OUYA board here: http://www.ifixit.com/Teardown/Ouya+Teardown/14224/1 which say a lot about the board itself.
There's also a concept document from nVidia regarding how Tegra boots: http://http.download.nvidia.com/tegra-public-appnotes/tegra-boot-flow.html - it seems it has a boot-rom which does early initialization of storage with actual boot-loader, configures RAM and copies the boot-loader there, and starts it. By taking a brief look at the board layout it doesn't seem there's any other persistant storage there except the NAND flash. Thus if you'll work hard enough to break things on flash you may brick the board (which most probably may be revertable if you get the jtag working).

You are aware that one can write C++ apps for Ouya via the NDK (just like any other android device), right?

It's also hard to imagine that you wouldn't be able to replace the launcher (just like any other android device).

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

@swiftcoder: I am aware that I can use C/C++ using the NDK, which I have already got working. The problem is that you need to use expensive JNI calls for anything ODK-related which is expensive, such as controller input. The OUYA forums have a few threads on performance issues related to controller input as it is. I've also been wanting to make my own distro of Linux and my own mobile device for a while now as a hobby.

I thought the OUYA would be a great way to start, but now I find that modifying the bootloader at all can easily brick the OUYA by design, and developers don't have any tools to fix this: http://randomfoo.net/2013/05/10/hacking-the-ouya.

@henry: Thanks for the wealth of insight and resources. I checked out the screenshots, and I actually have a retail version that'll be here in a few days to check out the motherboard under a magnifying glass. I noticed the Tegra 3 has a heat sync on top of it, which isn't too common with SoC IIRC. I heard that the OUYA's Tegra 3 is modified. You bring up other topics such as file systems and partitions. Sounds like quite a bit going on. I'm going to check out ifixit. I've been looking through free-electrons.com some more on my free time. I'm also going to buy "Professional Linux Kernel Architecture" by Wolfgang Mauerer.

You're right though, I one post won't cover it, and I really need to find a forum that's specific to device engineering once I get comfortable with the Linux Kernel. I want to learn how to write drivers for the OUYA controller for Linux, how ASM works in general, how to apply the concept of SIMD via ASM on ARM-based devices, file systems, security, etc. There's a LOT of things I want to learn now that I'm out of college. I think it's safe to say I'm going to have to start by building the Linux Kernel for x86, and test out my builds on VirtualBox. Also, I really want to learn how to build my own GUI. I really want to make my OS support 3D backgrounds, video backgrounds, and animated 3D models for app icons. All of which, are unloaded when a game starts, and there will probably be no multitasking support regarding multiple "apps" (daemons, yes though).

NOTE: I didn't write your entire name because I kept spelling it wrong lol

I'm leaning closer just building my own Linux distro designed for x86 since I can test it all from VirtualBox. Also, when building Linux, can I use gcc on any existing Linux/Cygwin installation to build an arm version of it by exporting the ARCH variable to "arm" and setting the correct config?

For what's it's worth, I think the OUYA's aesthetic design is really cool. Some ppl say it's too basic, but both the cube and controller look cool, IMO.

@swiftcoder: I am aware that I can use C/C++ using the NDK, which I have already got working. The problem is that you need to use expensive JNI calls for anything ODK-related which is expensive, such as controller input. The OUYA forums have a few threads on performance issues related to controller input as it is.

JNI calls really aren't all that expensive, and controller input is done, what, once per frame at most? As long as you aren't doing anything silly (like thread synchronisation) on the java side, a few hundred JNI calls shouldn't even be noticeable.

I've also been wanting to make my own distro of Linux and my own mobile device for a while now as a hobby... I thought the OUYA would be a great way to start, but now I find that modifying the bootloader at all can easily brick the OUYA by design, and developers don't have any tools to fix this: http://randomfoo.net/2013/05/10/hacking-the-ouya.

This is true of pretty much all branded Android-based hardware. Something stock like a Nexus won't have the same bootloader protections, and would let you do what you want.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Hi,

I'm leaning closer just building my own Linux distro designed for x86 since I can test it all from VirtualBox. Also, when building Linux, can I use gcc on any existing Linux/Cygwin installation to build an arm version of it by exporting the ARCH variable to "arm" and setting the correct config?


You will need a toolchain (an ARM cross compiler and C runtime libraries), you can get it from linaro: http://www.linaro.org/downloads/ source of nice tools & stuff for ARM development. You'll need to have the arm compiler in path, ARCH variable set and also CROSS_COMPILE having with the prefix of your toolchain. There are couple of slides about cross compiling the kernel here: http://free-electrons.com/doc/training/embedded-linux/slides.pdf
And I'd recommend getting a Linux instead of Cygwin on your workstation for Linux system building, in practice it's very convinient (but I think not a must).

NOTE: I didn't write your entire name because I kept spelling it wrong lol


;] I chosen nickname after Henryk Sienkiewicz, Polish writer (and Nobel prize laureate in literature ;]).

br,
hs

This topic is closed to new replies.

Advertisement