DSLinux in 2024
I was curious to try and run DSLinux to see if I can turn my original DS into a pocket Linux PC which could interact with stuff on my local network. Here, I am just documenting some of the stuff I had to go through to get it working.
Requirements
(1) You need a flash cart called DSTT. It’s important to get this specific cartridge, as other cartridges may not work (I have tried others, like the R4i Gold, and it did not work). When I decided to buy a cart specifically for this, I went with this one because it was the only one I could find video evidence of someone actually booting with it. I have also seen video evidence of a cart called “M3” working, but apparently you have to manually apply a patch to get it to work, something you don’t have to do with this. The M3 is also more rare. I found this card for $8 excluding shipping.
(2) A Memory Expansion Pak. The DS has only 4 MB of RAM and a lot of it will be used by the operating system itself. This is not enough to boot the full version of DSLinux. It will just straight up crash without it. This also isn’t very rare as it comes with the official Nintendo DS Browser. I found it for only $15 excluding shipping.
(3) A microSD card. Doesn’t need to be very large, even a 4 GB one would be fine. Apparently, if you have the M3 cart, you cannot use SDHC cards so you need an old card for it to work. With the DSTT, though, I did not have an issue with SDHC cards. If you do end up with SD card issues, try a 1 GB SD card as they would likely have better compatibility.
Software
(1) YSMenu. See the link below. Extract the content of the folder relevant to the version for your flash cart to the root of the SD card, in the case of DSTT it is the contents of the “DSTTi-Clone YSMenu” folder.
(2) DSLinux. Specifically, get the DLDI build from the link below and extract the contents to the root of the SD card.
That’s all you should need. You should be able to just put both carts into your NDS and boot it up and select “dslinuxm.nds” from YSMenu and it will boot into DSLinux. Below is a screenshot of the contents of my MicroSD card.
As you can see, successfully booting it we can see that we have an ARM946E CPU and about 10 MB of RAM… 10 MB? The NDS has 4 MB, and the expansion pack has 8 MB. Why 10 and not 12? Not entirely sure. Also, the NDS technically has two CPUs, a less powerful one that controls the WiFi and lets you boot into GBA games.
Autoboot
You can have the NDS boot straight into Linux without you having to do anything at all the moment of power on. This simply requires you opening the TTMenu folder and inside of it looking for YSMenu.ini. In that folder, uncomment the line “;AUTO_BOOT=” by removing the semicolon, and then after the equal sign, put dslinuxm.nds. Once you change this setting, the moment you press the power button on your NDS, without touching anything, it will boot into Linux automatically.
If you hold B at startup, it will boot into YSMenu rather than right into your ROM, meaning, if you decide later you want to try another ROM, you can still access the other ROMs on your flash cart without having to remove the autoboot parameter.
File Transfer
If you want to transfer files to your NDS and back, the easiest way to do it is just through the microSD card, but this is maybe not the most convenient since you will constantly have to power down the NDS, remove the cart, the remove the microSD card, put it in a converter, plug that converter into the USB port in your computer, and then repeat in the reverse.
Sadly, the NDS does not have any ports (except for the audio ports… maybe minimodem could be ported one day?), and so the only other way to transfer files is through its WiFi. The problem, however, is that the WiFi chip does not support any modern encryption protocols, so in practice you will not be able to get it to connect to your router unless it is an open, unencrypted network, which presents its own obvious problems, especially since for some reason DSLinux doesn’t seem to connect to hidden WiFi networks, so it must be open and unhidden.
The “best” solution I have come up with is to use a Raspberry Pi as a middle-man drop box. It works like this: your PC connects to your Pi over a physical connection over USB (which also powers the Pi), and the NDS connects to the Pi over WiFi. The Pi itself would not be connected the rest of the network, so even if your neighbor decides to connect to your Pi with its open WiFi, they won’t get access to your network. However, they do get the ability to connect to the Pi itself over SSH, meaning, you will need a password to actually connect to the Pi (so if the neighbor lacks the password, they could not do anything). Finally, your PC will not need to disconnect from your main router WiFi to connect to the Pi because it is plugged into the Pi directly and thus could interface with it over UART.
PC to Pi over UART
You need this cable below. It will both power the Pi and allow you to communicate with the Pi.
You will also need to edit the boot settings. You should have something in the /boot/cmdline.txt by default as shown below. Notice that it is creating a serial device with a baud rate of 115200 on device /dev/serial0. If you don’t have an entry like that, you will need to add it. You should be able to also do it through raspi-config in the interfacing section.
console=serial0,115200 console=tty1 root=PARTUUID=8b65616c-02 rootfstype=ext4 fsck.repair=yes rootwait cfg80211.ieee80211_regdom=UThen, you will need to add these three lines to the bottom of /boot/config.txt.
enable_uart=1
init_uart_baud=115200
dtoverlay=disable-btSometimes, this still isn’t enough and you will need to set the speed a third time from the command line using the command below.
stty -F /dev/serial0 115200You can probably set the baud rate even higher, but in my experience 115200 is good enough for most purposes, but if you find file transfers are too slow, you can experiment with placing this higher. The highest speeds that seem stable for me is 921600. Interestingly, the NDS file transfer over SCP is not very fast and so I actually find files transfer over serial from my PC to my Pi faster than they copy over WiFi from my Pi to my NDS.
After both are set, reboot the Pi and install screen on your main PC, and then through the UART cable you should be able to connect to the Pi using the first command below. After connected to the Pi you can then control it similarly to being SSH’d into it. You can “detatch” from the Pi using Ctrl+A+D which will keep screen running in the background which you can later resume with the second command below. If you want to entirely shut down screen, using Ctrl+A+\.
sudo screen /dev/ttyUSB0 115200
sudo screen -rIf screen is the UART equivalent of SSH, what is the UART equivalent for SCP to transfer files? The answer to that is a program called Kermit. Specifically, you will want to install ckermit on both the Pi and your machine connecting to the device. Once you install it, you need to create a configuration file, which I personally like to create at /kermcfg on both devices which should look like something below. Note that /dev/ttyUSB0 is the device on your PC side, but on your Pi side it will need to be /dev/serial0.
set line /dev/ttyUSB0
set speed 115200
set carrier-watch off
set flow-control none
set prefixing all
set parity none
set stop-bits 1
set modem noneSince the Pi is running a serial terminal, it will automagically accept files if you send a file using the first command below from your PC where myfile is the file to transfer. However, because your PC probably is not running a serial terminal on the device connected to the Pi, it may not automagically accept files if you try to send one from the Pi to the PC using this method. Instead, you will need to explicitly put the PC into receiving mode first before sending a file using the second line below.
sudo kermit /kermcfg -s myfile
sudo kermit /kermcfg -rMake sure to put the Pi in sending mode before putting the PC in receiving mode. The reasoning for this is that the Pi is running a serial terminal while the PC is not, so if you place the PC into receiving mode first, it will conflict with the Pi’s serial terminal, causing it to freeze. If you place the Pi into sending mode first, there will be no conflict and you can then place the PC into receiving mode and it will receive the file.
Also, if you are sending files to the Pi, make sure to close out of screen before sending your file with kermit. They seem to interfere with each other and your transfer speeds will be far slower.
NDS to Pi Over WiFi
The easiest way to set this up is to install something like RaspAP or OpenWRT onto your Pi. This will turn your Pi into a router, and like a router, you can connect to it and get to the admin panel in the browser. From there, you will want to make sure you setup an open network with no password on it as well as change the admin password. This latter one is very important as, remember, the network is open to everyone, meaning anyone could try to access your admin panel settings.
The next steps you can achieve just by editing the /etc/hostapd/hostapd.conf file and add the two lines below to the bottom. These two lines will add a MAC address filter. Basically, the router will refuse to connect to any device that does not have a MAC address explicitly listed in the /etc/hostapd/hostapd.accept file. In that file, you will want to put the MAC address of your NDS (you can find this by running ifconfig -a) in lowercase and absolutely nothing else in the file.
macaddr_acl=1
accept_mac_file=/etc/hostapd/hostapd.acceptMAC address filters aren’t completely secure as MAC addresses are shared through plaintext and thus someone with the right tools cooled potentially figure it out. However, this does prevent just your random neighbor from trying to click your open network and connect to it out of curiosity. If they do so, it will fail to connect entirely due to incorrect MAC address.
Connecting to WiFi is rather simple. Just run the wificonf command and select Create and then give the new profile a name and put in your SSID from your Pi router and leave the channel and WEP key fields empty and don’t do static IP (unless you want). Once you create it, you can connect with it by running wificonf again and going to Load and loading that profile. For some reason, it always seems to throw an “Unknown error 3,” but this seems to have no consequences. If you see “Sending discover…” three times followed by an error, it failed to connect. If you see something about “Lease” then it succeeded in connecting.
Next, you will want to configure SSH so when your Pi connects to your router it can SSH into it. The version of SSH and SCP on DSLinux is rather outdated so you need to update it. Scroll down in this article to the “Compiling Code on DSLinux” section and you will find a link at the bottom to a repository of code I have ported. In that repository, you need to download /www/dropbear.tar which is an updated version of the SSH client, and you will need to extract that to the /linux folder on the MicroSD card.
It is possible to get the outdated version of the SSH client on DSLinux to connect to a modern machine, you just have to modify the config file of the SSH server (in this case, on the Raspberry Pi) to use downgraded encryption. To do this, you will need to add the lines below to the /etc/ssh/sshd_config file in order to enable deprecated protocols.
KexAlgorithms +diffie-hellman-group1-sha1
HostkeyAlgorithms ssh-dss,ssh-rsa
Ciphers aes128-cbc,3des-cbc,aes256-cbcIf you run ip a on the Pi, you can get its gateway IP address (the IP address you type into the browser to get to the router settings when you connect to it), which when using RaspAP it created that address at 10.3.141.1. You can then use the first command below to SSH into the Pi from the NDS to control it, the second command to copy files from the NDS to the Pi, and the third command to copy files from the Pi to the NDS.
ssh pi@10.3.141.1
scp /path/to/my/file pi@10.3.141.1:/path/to/dropoff/directory/
scp pi@10.3.141.1:/path/to/my/file /path/to/dropoff/directory/That’s about it. I, again, highly recommend not actually connecting your Pi to your network because at that point, the only thing preventing your neighbor from getting onto your network is the MAC address filter, which is not very secure. This means this isn’t a great solution if you actually want to play online games on your NDS, but it’s great simply for sharing files between your PC and NDS. It’s good for DSLinux purposes, but maybe not for other purposes.
While WEP is not very secure, it would still be preferable to have that over an open network, especially if you do plan to plug your Pi into your network to play NDS games online. However, I cannot figure out how to get WEP working on my Pi. I have tried configurations for /etc/hostapd/hostapd.conf I’ve found online which caused my open network to appear as a WEP network, yet nothing could actually connect to it even with the right password. None of the router software like RaspAP or OpenWRT support WEP either. WEP is very outdated and it is hard to find support for it, but simply for legacy/NDS purposes, if someone wants to share how to enable WEP on their Pi rather than an open network as presented here (and you have actually tested it to work with the NDS), please do so.
Compiling Native Code for DSLinux
Besides the rather cumbersome WiFi situation with the NDS, the biggest disappointment with DSLinux itself is the inability to compile code on the platform itself. There is no C compiler that you can run on DSLinux. The only way to compile binaries is to compile them on your PC and transfer them over to the NDS. Doing so also requires setting up the entire DSLinux toolchain, which is not particularly easy either.
Due to the outdated nature of the toolchain, I found it difficult to get working on any modern system. I ended up emulating an older version of Debian that may have been used around that time period and had good luck getting it to work following the guide below without much issue.
The only strange issue I ran into is that, for some reason, the binutils stuff (such as the GCC compiler) is built in 32-bit, but you cannot compile DSLinux on a 32-bit system. This means you need a 64-bit system with 32-bit support. By default, if you install 64-bit Debian, it will not have 32-bit support and you will need to run the commands below to enable it.
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install libc6:i386Once that is all setup, you should be able to build the entire DSLinux operating system by following the guide. This means not only can you port your own software to it, you should be able to modify anything about the operating system and really customize it to your liking. However, in my experience, porting code is not very straight-forwards, although I did manage to get a few things ported.
When I successfully ported code, most of the time I ported it using a simple strategy. First, you need a Makefile, and some code requires you to run ./configure to generate it. Do NOT run this in the make xsh environment. Run it outside the environment. It will build the code for x86, which is not want you want, but it will generate a Makefile.
The problem with running the configure script in the make xsh build environment is that it will almost certainly fail and you will not get a Makefile. Without the Makefile, it’s pretty much impossible to get it ported. It is better to get a bad Makefile which you can then modify to make work, than not get one at all. You will likely have to modify the generate config.h file to disable options manually which aren’t compatible with DSLinux as well as to modify the Makefile itself.
How I would modify the Makefile is to change lines with CC= to whatever the output of $CC $CFLAGS $LDFLAGS is while in the make xsh build environment. I would then change CCFLAGS= to the output of $CFLAGS and LDFLAGS= the output of $LDFLAGS and then just run make while in the make xsh environment, and quite often that was just enough. You can use the file command to verify it built to the proper flat file format.
Compiling Code on DSLinux
Sadly, DSLinux does not come with an onboard compiler. You have to compile native code on the PC and transfer it to DSLinux. There will likely never a GCC compiler ported to DSLinux due to the fact that the exotic memory layout means GCC has to be patched to compile code properly or it will crash due to memory issues. The only way to get GCC onto DSLinux would be to compile GCC on the PC using the patched version of GCC in the toolchain for porting code to DSLinux. The problem with this, however, is that, while the developers have given us a patched toolchain, they have not provided the source code that is actually compilable, so it will likely remain unfeasible for now.
If you really want to write code on the NDS itself, I have ported the very latest version of Lua at the time of writing this to DSLinux along with the Lua compiler. This will allow you to write code on the NDS itself in Lua, and once you compile it to Lua bytecode, it actually runs decently fast in the Lua interpreter, way faster than shell scripts.
See the repository below for code I have ported to DSLinux including Lua.
If you really want to write C code, DSLinux by default does come with picoc which is a C interpreter that interprets C code as scripts. I have, in the repository above, also ported a later version of that (the last version? the developer seems to have abandoned it). DSLinux also comes with Perl, so you could write Perl scripts as well (…what does a Perl script even look like? Who is actually using Perl?).
Network File System
It’s possible to mount a drive over the network onto the NDS. This can be more convenient than transferring files over SCP although less secure. I’m not really sure why, by the “official” version of DSLinux on their website does not have this feature enabled in the kernel, and you have to compile the kernel with these settings to get it to work, or you can just click my repository link above and get the kernel.tar I uploaded there.
To enable NFS server on your Raspberry Pi, use the commands below. This will created a shared folder at /nfs which will be open to all IP addresses under 10.3.141.X. The 0/24 means it is open to all IP addresses. NFS does not have much security, it’s basically public. The only thing you can really do here is restrict it specifically to the IP of your NDS. This will, of course, only work consistently if you setup your NDS to have a static IP in the wificonf settings, but now let’s just keep it public.
sudo bash
apt install nfs-kernel-server
mkdir /nfs
cat "/nfs 10.3.141.0/24(rw,sync,no_subtree_check)" >> /etc/exports
systemctl restart nfs-kernel-server.serviceI also added two new kernels with support for NFSv2 and NFSv3. This lets you mount drives over the network as if they are plugged directly into your device. For example, you can create a folder on your Raspberry Pi and then mount it on the NDS. When either the Pi or the NDS edit a file, changes will be immediately visible between both parties in that folder.
On your NDS side, all you need to do is connect to the Pi over the WiFi, create an empty folder, and mount the Pi to that folder.
mkdir /usr/nfs
mount -o noblock,nfsvers=3,noac 10.3.141.1:/nfs /usr/nfsOther Core Utilities
There are a lot of useful commands in a /usr/bin/coreutils folder which are not in your $PATH automatically on boot, might be due to the fact some are buggy, but some of them actually work great (like bc and wc). If you check my repository above, I have a coreutils-init.sh script that if you run it, it will simply copy over all unique files (ones that aren’t already in your $PATH) in /usr/bin/coreutils to your /usr/bin folder so they will be available on system startup.
Pixil
There is supposed to be a Pixil graphical environment, but I could never get it to work. Maybe it even needs even more RAM than the web browser expansion pak provides. There are apparently other carts out there you can get that gives you up to 32 MB of RAM according to the DSLinux website, but they are much rarer. Who knows? If anyone knows why Pixil doesn’t work, be sure to comment.
Debugging
A very useful utility the original developers ported is gdbserver which can be used to step through the code of a program as it’s running on the NDS on your PC over the internet, which they mention here. One thing I will add, however, is that you do not need to use their toolchain gdb to actually debug. You can use any version of gdb. You will need to use their toolchain to actually compile programs and output the debugging gdb file, but as long as you have the file you can connect to the NDS and step through the code on any machine with any version of gdb, even a machine without their toolchain on it.
Shell Scripting
They mention on the website that you can’t use functions with shell scripts, which is a major limitation. Although, you can use something akin to function by creating and executing temporary files since DSLinux both has temporary file support and the shell supports multiline quotes.
#!/bin/sh
#create the function
myfunc=`mktemp`
echo '
echo "Hello, $1"
' > $myfunc
#call the function
sh $myfunc fish
#clean up the function
rm $myfunc