 And welcome to the RC3, the remote chaos experience on the R3S stage, the remote Rhein-Ruhr stage. So today I have the honor of introducing Jot-en with his talk about porting Linux to your favorite Opsico ARM SOC. But before we go to that, we want you to tell us about things that are happening in the digital world, some things that you initiated or some things that you know about. And with that, please write us an email at newsshowatrc3.world or write us in our blog newsshow.rc3.world. Furthermore, this talk will be translated in German. This talk will be translated in German. You will find the translations below the video, under the rider, I don't know the rider anymore. In any case, you will see it below the video. Furthermore, if you have questions, we want you to contact us and tell us the questions due to the infrastructure right now. I cannot see you when you're standing in front of the microphone. So you can go either to hack into the channel RC3-R3S or you can write us on Twitter or Mastodon. The hashtag for that would be RC3R3S, all three are numbers or all three are numbers. Or if the stream happens to cut out, we also stream to Twitch and YouTube. The link can be found by searching in the corresponding platform for remote Rhein-Ruhr stage. If you are unsure how that is written, you can see the various titles of this video. So, about Jot-N, I asked him what should I tell about you and I can only tell you what I know about Jot-N. He is part of the Cows community and he certainly loves to hack some hardware. So give it up for Jot-N and his talk, Porting Linux to your favorite obscure ARM SOC. Alright, as he said, I'm J-N and the slides have a bit of delay. So sometimes I find a piece of hardware that has embedded Linux on it, which is cool because we know Linux, we can do things with Linux. But then it has a really old version of the Linux counter. Like this, for example, is the management controller in a Supermicro mainboard, like a server mainboard, the thing that does IPMI and stuff. But it runs kernel version 2.6.17, which was released in 2006, 14 years ago. I'd rather have a modern kernel. So, how do you go about that? First of all, you should collect basically all the information you can find about that chip you're interested in. Reference manuals, datasheets, a source code that was released by the Vandals due to the license of the kernel, the GNU general public license, GPL. Vandals have to publish their Linux source code. But sometimes you have to send them a request first. And sometimes you have to be really persistent with your request, so you get a source code table. It's also useful to look at other chips, which might be similar. For example, I searched for some of the register names in this chip and I found a datasheet with descriptions for a different chip, which uses the same interrupt controller and ethernet MAC. Finally, you should consider writing your own documentation, even if it's just to collect all the other information sources that you found in one convenient place. The next thing to do is looking for serial ports. Most embedded devices that you can find have a serial port somewhere. It's very useful, especially in embedded devices that aren't particularly secure. You can just get a root shell if you connect a serial adapter to the right pins. They're usually not populated, so you have to search a bit. In this example, it's two pads of unpopulated resistors. It's really small, but if you use an oscilloscope, you can find the right signal and then find your serial port. You can also find a bootloader shell sometimes. The bootloader is basically the first thing that runs when you power on anything. It's responsible for basic hardware initialization, making sure that RAM is usable and also for loading the actual operating system. Bootloaders often have debug facilities in them, so you can do interesting things with them. Sometimes they have a menu of interesting commands like peak and poke in memory and load files from storage like SD cards or flash. You can even download data over network protocols like TFTP. TFTP is terrible, but it works. Usually, when you have control over such a bootloader shell, you can also tell it to run your own code. That's obviously very interesting if you want to run your own Linux kernel. But you should start simple, like write the simplest possible program that can demonstrate code execution. For example, these four ARM instructions, they just load the address of the serial port, the UART, load a character and then repeatedly write that character to the serial port. And what it does, you can see on the right side, it just screams. And once you have that down, you could basically start running Linux. It won't be useful, but it will print something. But sometimes if the bootloader doesn't have all these interesting commands, it's useful to add your own little program that can do peak and poke and maybe some scripting and running code and whatever you need. Just so you have an interactive environment to experiment with the hardware. So the next step is to configure Linux. The Linux kernel has this configuration system called Kconfig, where you can configure all kinds of things. And if you just want a good basic configuration that's known to work on most systems, you use make arch equals ARM multi v7 dev config or that's a different one for the older architecture versions. And then you can use make arch equals ARM and config or menu config to configure all these options interactively. And because the dev configs usually include all kinds of drivers, you most likely want to disable some of those drivers. And then there's a few things that can help you in early debugging. For example, the config debug option. And if you enable that, you can also specify the UART base address and register with. So you can have a usable serial port. That's an option for early print K, which just means you get log messages earlier during boot. And that's another option to specify a built in kernel command line. So the boot loader doesn't have to provide a reasonable command line. All right, once you've configured and built Linux, you can use your boot loader to load the Zimage file into RAM and run it. The Zimage is a self-extracting compressed version of the kernel. But once you do that, you'll get something like this. And it says invalid DTB or unrecognized unsupported machine ID, which basically means you need a thing called DTB. DTB means device tree binary device to blob. The device tree is a special data structure that describes to the kernel how the hardware is structured at which addresses you can find which peripherals. How to write the device tree is defined in the device tree bindings in documentation slash device tree slash bindings in the kernel source. And you write those device trees in DTS files for device resource that compile to DTB files, device tree blob. And if you want to use it now, you can enable another kernel option, which is config ARM appended DTB. And then just concatenate the Zimage and the device tree blob together into one file and give it to your boot loader so it runs those together. The kernel will then just find the device tree and use it. And it will boot a little further. Now I did this and I got a problem. It booted about this far and then just stopped for no apparent reason. The reason was a bit difficult to debug. It turned out that the vendor kernel on this bot uses only 100 megabytes of the RAM that is actually installed. Actually, the bot has 128 megabytes, but some of it is used for something else that I haven't figured out. So that was really difficult to debug. But once I reduced the amount of memory that is used to those 100 megabytes, it worked with a problem. And it got a little further until the point where it complains about no matching timers being found. Linux needs timer interrupts so it can schedule work. So it can switch between different tasks. For example, when you run two programs in parallel. For timer interrupts to work, you need two things. First, you need a driver for your interrupt controller. An interrupt controller is a little piece of hardware that just collects the interrupts from different peripherals on the chip and signals to the CPU that there was an interrupt. The code running on the CPU can then ask the interrupt controller which interrupt was it and acknowledge that the interrupt was received and so it can just process the interrupts one by one. With older ARM CPUs, you had custom hardware from the chip vendor. In this case, it was Nuviton. But with newer ARM CPUs, you will usually find that a generic part is used, the ARM GIC, generic interrupt controller. The next thing you need in order to get timer interrupts is a driver that tells the timer hardware to generate interrupts. That's a clock event driver. There's something related in Linux called a clock source driver which is just responsible for asking the hardware what time is it on a nanosecond scale. Then there's something else that also has clock in the name, which is the clock subsystem, called CLK. It manages basically everything that has a clock frequency. Like when you have a CPU that can run at different clock speeds on an ARM system where Linux runs, the different frequencies are managed through the clock subsystem. Sometimes when you specify a timer in device tree, it wants a reference to the input clock so it can scale the frequency down correctly. So now it's which number to enter to wait for two seconds, for example. When you don't know how the clock hardware works, but you know the clock frequency, you can just make a dummy note in device tree and say compatible equals fixed clock and then enter the clock frequency and that will work for the moment. Now, once you have timer interrupts, Linux should boot to a panic, which is a success. We didn't have a panic before. It panics now because it says VFS unable to mount root FS. It needs a file system, the root file system, where it can find programs to run because everything you do on a Linux system is basically in programs that are not the kernel itself, but those user space programs like init and shell and wget or curl. Now, where do you store that root file system? At this point, you don't have a driver for any kind of storage like SD cards or, I don't know, Zata. So you need to load the file system together with the kernel in something that's called an init-dramfs, initial run file system. And if you find the right kernel configuration option, you can then put this file root FS, the CPIO, into the kernel. So it's in the end just this one file, the image DTB that you can load with a bootloader run. Now, if you want to do this manually, just collect all the files that you need in a system, that's a bit tedious, but there are good options like build root, for example, go to buildroot.org for more information, where you can just configure Linux user space with all the features you need. When you boot to user space, it's useful to specify on the kernel command line console equals tgys0,15200. It says the console where the interaction happens is the first zero port and it runs at 115200 bots. Otherwise, the kernel will just assume the wrong bot rate and that's a bit difficult to debug. Another useful driver is Ethernet. It's a bit more complex than the previous things like interrupt controllers and timers, just because the hardware is a little more complex usually. But it's very useful. Once you have Ethernet running or some kind of other networking thing, you can just use wget to download your kernel and then use kexec to run your kernel. So you don't have to deal with your bootloader anymore. You can basically use Linux as your bootloader now. Of course, there are many other functions in a typical system. But once you have the basic drivers like for serial ports and timers and interrupts and stuff like that, it gets easier to just try different things and you could let different people work on different parts of the chip because they don't depend on each other now. That's a lot of things that can go wrong. If you use the wrong kconfig settings, it might happen that all your programs crash. That happened to me. So it's better to start from a non-good kconfig defconfig file and not change any of the obscure things unless you just want to try out what happens when you change them. If you use ram that is not actually available, weird things will happen. It's difficult to debug. If you don't specify a boardrate, you will get 9600, which is these days probably not what you want and not what you expect. I got stuck a dozen times during this project. So in the end, it still turned out to be useful and I got through the problems that I had. So don't give up. You can do it. When your kernel port works to some degree, you might think about bringing it to the official releases from kernel.org, which are released by Linus Torvalds and Greg Cage. Contributing to the upstream mainline Linux kernel works with patches and mailing lists. So you send an email with your change to the right mailing list. They will try to give you a thorough review, tell you what's wrong with it. Then you send a second version, which has all these things fixed. It iterates a bit, but in the end, it should get accepted. It's a bit tedious, but in the end, this is what should result in good quality code in the kernel. If you're interested in upstreaming, I recommend that you watch Greg Crow Hartman's talk right and submit your first kernel patch. All right. Thank you for listening. All of the example code used in this project can be found on GitHub at Neuschaffer-slash-wpcm450. For general discussions about kernel development, I recommend the double hash kernel IRC channel on FreeNode. You can also find me on the usual IRC-free channels later when I get home. All right. If there's any time for questions, I could answer questions now. And also thanks to the stage crew who made it possible to speak here. Sorry about the technical difficulties. Due to the technical difficulties, we don't have any questions from the audience. Unfortunately, the stream was not reachable at the end. I can't ask questions about this talk. But maybe what I would be interested in now, or maybe our viewers, would be interested in your first steps in the direction of porting something on a board that you wanted to have and Linux on it. Okay. I'll translate to English because the talk was in English. What were my first steps in ARM and Linux on ARM? The first things I did on ARM were basically I did some hacking on my Nintendo Wii U and I ran my own code in the service processor, which is an ARM CPU. My first steps on a Linux on ARM were that I tried to port a Linux on an ebook reader that had a broken screen. Now I see a video. It seems that you get a grip, but I don't hear any audio. Okay, now the video is gone again. Ah, now I hear what? Do you hear me? Yes, I hear you. Ah, wonderful. Now to my question. Yes, my first steps with some of my own code on ARM were that I played around with my Nintendo Wii U. There is a service processor that is an ARM processor. There I put a bit of my own code on it for fun. And Linux on ARM, that was when I tried to bring my own kernel to an ebook reader that has a broken screen. Okay, cool. And then you want to integrate the ebook reader into your home automation or something? That would be an option. I don't have very specific plans right now. Okay, cool. I'm happy. We still don't have any questions from the community. Then I would like to thank you at this point. If you want to reach JN, then the next guarantee will be on GitHub. Yes, or IRC and the usual RC3 channels on Hackend. Sure, also a CCC-AC channel, right? Right. Okay, wonderful. Then I thank you and I apologize for the technical interference on our side. And I hope that you still enjoy this lecture. David, back to the break.