Installing Raspbian on a RaspberryPi Through a Serial Console
First some backstory, because I feel like writing a fucking post to make up for the past year I haven't:
I picked up a Raspberry Pi some months back without much of a need for it. Most of my electronics stuff is bought without a use, so I guess it's no surprise I jumped on the bandwagon. I ended up ordering what is called the ModelB, which is the earlier model with 256MB of ram. To be honest, I didn't really even know what the hell the board did, I just heard other tech junkies babble on about how it was going to revolutionize home computing (hint: it didn't and won't). Since it's a full computer, not just a microcontroller like an Arduino makes it a relatively poor tinkering device compared to booting up a vanilla Debian, Ubuntu or ArchLinux VM. But, none of that really makes the device useless. I just haven't found it's use yet, thought I'm still fucking around with it.
Days after I put in my order, an article came to my attention where a FreeBSD hacker successfully booted into multi-user on the device. This is particularly interesting to me, as someone who prefers the BSD over GNU, and so the first couple weeks I had the device I had followed his instructions multiple times, installing FreeBSD onto the SD card and booting up, and then PXE booting from another box, and just doing some weird network booting I never really have had the opportunity to mess around with before. But, there are only so many FreeBSD installations you can do on a new computer before you actually want to start playing with the hardware and turning the computer into something that computes things. Unfortunately at the time, all communication was restricted to the UART serial console. This really put a kink in doing anything more than a little C or Python hacking. Within a couple weeks the Pi was collecting a bit of dust, quite literally, so I threw it in a bag and tossed it in with the seldom used Arduinos.
Cut to this weekend, where I have spent the past few months at a new job as a Ruby developer full time, instead of just when I had the chance to do Ruby and where I'm required to know enough sysopts to keep my designated projects up and running on Debian servers. I've always like Debian the most of all the Linuxes, anyways, but now I get to do it consistently. An article from ArsTechnica came across the stream this week about the two guys that bootstrapped the Raspbian project, which brings Debian to the armv6 platform (armv6 is kinda the bastard child of the ARMs, not a lot of support since there aren't many enterprisey uses for it. armv7 is more popular). It's an interesting read, and it manged to re-spike my interest in the device. My first issue when reading the article though is the lack of WiFi, and the fact that it's kind of a fragile little snowflake. So, I hopped on Amazon to pick up a Linux compatible USB mini-wifi adapter based on the RTL8188CUS RealTek chipset and then over to Adafruit and picked up a case, and after realizing the case would prevent serial communication by blocking access to the GPIO pins, picked up a kind of breakout board dubbed the Raspberry PI Cobbler. Because the internet is amazing, I was able to receive these items within days of ordering. I'm still amazed at how far the internet has come since the days it took tens of minutes to load a single JPEG.
But, to the point of the fucking story, I now had a case, a way to tie into the GPIO pins, and the ability to not have it wired into my router. The last step is to just install Raspbian, right? If it was only so fucking easy. Even though I'm using a Debian based OS instead of FreeBSD, I still don't care much for a graphical display. But, I also wanted a minimal installation, something that all the dozens of images floating around the internet seem to not get (Apache, X11 and LXDE DOES NOT A FUCKING MINIMAL IMAGE MAKE!!!). This leaves me with the Raspbian Installer, which is essentially a Debian NetInstall built around Raspbian. Perfect, just a barebones installation as soon as it finishes running. I copied the installation files to a clean SD card, threw the RPi into the enclosure, plugged it into my TV, which is the only device I own with HDMI input, plugged in my trusty Aluminum Apple keyboard and sat down for a quick install. Except, the damn thing doesn't seem to want to respond to my fucking keyboard. A quick overview of what the fuck I'm doing reveals that my keyboard is actually an un-powered USB hub that happens to have a bunch of buttons on it. The RPi isn't powerful enough to run it. Great. Luckily I have a powered hub I can use to send enough power to the keyboard, but it's tightly coupled to my desktop setup, so after grudgingly pulling that off I try again and receive the same damned result. I've tried all sorts of combinations but was never able to actually get the keyboard to respond. Fuck fuck fuck.
Well, the next step is what? Try for a serial installation? This is where things get grey. There isn't a lot of documentation around the internals of Raspbian, and almost every fucking Google search on "installing raspbian" results in some shitshow about DDing some goddamned image onto an SD card and patting yourself on the back with the "Hacker" merit badge. I'm glad there are a lot of *nix newbies getting into this, but it gets aggrivating trying to find information about cool shit to do with the RPi when every blog post is "10 ways to hack your PI", and it's just 10 different
apt-get install commands. Give me 10 ways people have made cool things with this fucker, not 10 ways people have used a cheap ass computer to watch porn on a TV or saved money on not buying a TimeCapsule.
So, I started poking around with the installer. In the rpi_installer-08-19-12.zip archive there are some unsurprising files, like
loader.bin, typical linux boot shit (sans vzimage and initrd). But, nothing too revealing except for the textfile
cmdline.txt. In here we have a long ass line of arguments to what I am assuming is the bootloader (which I'm unsure as to what that is exactly, if it's completely custom from here, or if it's something like uBoot, nether of which I have any experience with). Three of these are dealing with tty settings:
console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1
The first is obviously the standard console, and the second appears to be the kernel debugger (gdb) output console. The third appears to just be a repeat of the first, but it's configured to talk to tty1, which in the default case ends up enabling the installer to output to the HDMI port. You'll see that it's a different format as well, since it's a different kind of tty.
ttyAM* devices on the Raspberry Pi are hardware ttys, where as the ttyN (where N is a digit) are software. This makes the initial configuration changes easy, just change
ttyAMA0,115200, and magically, we can boot the RPi's installer all the way to the ncurses screen while viewing the output on the serial console.
But, and this is the reason I'm writing this up, things don't work right just yet. We need to be able to connect to the serial line, and send keyboard commands as well. I've normally just been using GNU screen to connect through my FTDI cable and in this instance it works, except for it doesn't. Everything goes well until ncurses comes up, and then all the UI elements are sent to be as garbage. They're in the right place, and if I managed to find a Youtube Video of somebody walking through the process with screenshots, I might have been able to fake it (wouldn't have been the first time I've blindly installed an OS, or had to reconfigure one manually when I've locked myself out just by typing commands at a headless keyboard), but alas, there really are no such videos I could find. There are hundreds of videos showing you how to use DD or some other tool for windows to copy an image onto an SD card though :(
So, I needed to find a new serial interface client.
minicom came to the rescue, and is readily available on all Linux distributions, as well as in Homebrew for OS X. A quick command later and I'm able to connect into the device and get legible text back, though not as colorful and pretty as it might be on a standard monitor. I was almost giddy at this point, but my excitement quickly turned sour once again as soon as I realized my commands weren't being sent. After all this work just to figure out how to install a fucking OS, I'm back at the same spot I initially started at, staring at an installation screen that isn't responding to my commands.
So, to recap, I had my Raspberry Pi running an installer and outputting to the serial console, and I could either send commands and not understand what I was typing or what I was aking for and responding with, or I could be mute, but read what it was asking for. What a fucking mess. I fucked around with using different terminal clients with GNU screen, fucked around with my encoding and locale settings, and fucked with all the configuration variables I could find in minicom, but nothing worked. My permissions on the local tty device wre fine (0666), and the fact that one program could send, but the other couldn't made for a confusing debugging session.
And, I guess a fair bit of warning, I'm not exactly sure what this command does outside of changing the tty flow control from hardware to software, but to solve my particular dilemma, running this command fixes everything:
stty -f /dev/tty.usbserial-A182342O -crtscts -ixon -ixoff
Now I can properly talk to my RPi. I've finally got a root console on the device.
I'm wondering why the installation took a couple hours to complete though, since I can't remember Debian ever taking this long to install even with a NetInstall image. Either way, I can't complain too much. And I get a chance to write a new blog post, since I've slacked on this for so long.