
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>Viciouss' brain.txt</title>
 <link href="https://viciouss.github.io//atom.xml" rel="self"/>
 <link href="https://viciouss.github.io//"/>
 <updated>2023-06-20T21:12:00+00:00</updated>
 <id>https://viciouss.github.io/</id>
 <author>
   <name>Martin</name>
   <email></email>
 </author>

 
 <entry>
   <title>Can I has Android now pls?</title>
   <link href="https://viciouss.github.io//2023/06/20/note-10_1-buildroot/"/>
   <updated>2023-06-20T21:00:00+00:00</updated>
   <id>https://viciouss.github.io//2023/06/20/note-10_1-buildroot</id>
   <content type="html">&lt;h2 id=&quot;next-steps&quot;&gt;Next Steps&lt;/h2&gt;

&lt;p&gt;There is a kernel image which might or might not boot, it has the device tree attached at the end of it, the inner workings of the boot image and the bootloader are no longer a mystery. Sounds like everything is in place to assemble the boot image, put it on the device and boot right into Android, right? Well, I have to tell you something.&lt;/p&gt;

&lt;p&gt;Android has a history of heavily modifying the mainline kernel, introducing new and changing existing code. When the p4note device family was still new and shiny, there were hundreds of patches on top of mainline. This modified kernel is called the Android common kernel. These kernels were then picked up by the vendors who put another couple of hundred patches on top to get a device up and running. The end result were kernel trees that went up to hundreds of thousands of lines of code away from mainline. Upgrading from an old downstream kernel to mainline is therefor guaranteed to fail miserably. The system and vendor userspace parts (like the Android HAL and vendor binaries) expect certain files to exist, like sysfs and devfs entries, as well as certain uevents to be triggered. All this is missing.&lt;/p&gt;

&lt;p&gt;Building Android from scratch is quite a huge task as well. It’s not like throwing in a kernel and then building it, the hardware abstraction layer will kick your butt if you are missing a required implementation for memory management, graphics and other things. A lot of configuration needs to be done before an image even comes out at the end of the build process. This is putting way too much complexity on top and with drivers missing, it will be an awful user experience anyway.&lt;/p&gt;

&lt;p&gt;Ok then, how about starting small? There are a couple of options to chose from. The simplest solution is compiling a little init program to print out a hello world and packaging it with the kernel. But what to do with it next?&lt;/p&gt;

&lt;p&gt;Maybe grabbing a copy of &lt;a href=&quot;https://www.busybox.net/&quot; target=&quot;_new&quot;&gt;busybox&lt;/a&gt; and assembling a small system with a shell sounds great? For sure it does, but the goal is to write more driver code and not setting up an embedded system from scratch with half the drivers not working. So how about something more “usable” with tools already available?&lt;/p&gt;

&lt;p&gt;Luckily, there are projects that provide small base systems with lots of customization options. They will provide a wide range of libraries and programs to be included in a linux system. Those projects also have build systems in place that will pick up all the tedious work and throw out a boot and system image at the end. Let’s have a look at one of them.&lt;/p&gt;

&lt;h2 id=&quot;introducing-buildroot&quot;&gt;Introducing Buildroot&lt;/h2&gt;

&lt;p&gt;I chose buildroot for no apparent reason, I liked the name and it looked easy to get started with, so I just went with it.&lt;/p&gt;

&lt;p&gt;So what is buildroot? It’s basically a collection of Make files, package descriptions and patches that, combined with a config file, will assemble a custom root filesystem tailored to your specific needs. There are hundreds of software packages to chose from and it uses the Linux kernel kconfig system for configuration. Sounds great for mainline development!&lt;/p&gt;

&lt;h2 id=&quot;buildroot-in-10-minutes&quot;&gt;Buildroot in 10 Minutes&lt;/h2&gt;

&lt;p&gt;First, let’s download a copy of &lt;a href=&quot;https://www.buildroot.org/download.html&quot; target=&quot;_new&quot;&gt;Buildroot&lt;/a&gt;. Anything not too old will be fine for this example. For the p4note project (see the end of this post), at least version 2023.02 is required for the 6.1 mainline kernel that is used.&lt;/p&gt;

&lt;p&gt;To work with buildroot, there needs to be a board description for the target. This is either located in buildroot itself if it is officially maintained or in a so called external tree in a separate directory/repository. The board description usually contains config files and an overlay to the root file system for files that will be packaged along with it. A small skeleton project can be assembled in as little as three files:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Config.in&lt;/li&gt;
  &lt;li&gt;external.mk&lt;/li&gt;
  &lt;li&gt;external.desc&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A defconfig file describes the selected options in buildroot. It is not mandatory, only the above files are, but for reasons you will see in a minute, it makes sense to already create it:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;configs/p4note_defconfig&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Only the external.desc file actually needs content to get started, the other files can be empty. It holds a name and a description for the board. For the p4note, I chose the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;name: P4NOTE
desc: The Samsung Galaxy Note 10.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The name should be A-Z0-9 all caps, as it will be part of the kconfig entries. Lowercase letters are technically allowed, but who would do such cruel thing? The description can be freely chosen, but it should fit in one line as it will be displayed in the menuconfig.&lt;/p&gt;

&lt;p&gt;With this created, the configuration part can begin. In the buildroot directory, this command will copy the defconfig from the external tree to buildroot:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;make BR2_EXTERNAL=/path/to/external/tree p4note_defconfig
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It also sets up the external path as current context. All the following commands can be executed without the BR2_EXTERNAL. The next step is setting the configuration values:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;make menuconfig
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are quite some options to chose from, I will describe the important ones in the next section. Afterwards, use F8 to save to the current file (which is .config in the buildroot dir) and quit.&lt;/p&gt;

&lt;p&gt;The changes to the configuration are currently only in the buildroot directory, to finally apply these configuration changes to the external tree, do this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;make savedefconfig
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This will update the defconfig in the configs directory of the external tree, as the current setup has the &lt;a href=&quot;https://www.buildroot.org/downloads/manual/manual.html#customize-dir-structure&quot; target=&quot;_new&quot;&gt;recommended directory structure&lt;/a&gt; and that’s how buildroot rolls.&lt;/p&gt;

&lt;p&gt;As a last step, of course, a call to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;make&lt;/code&gt; will build the project.&lt;/p&gt;

&lt;h2 id=&quot;important-configuration&quot;&gt;Important Configuration&lt;/h2&gt;

&lt;p&gt;Buildroot uses a lot of sane defaults. It will use the latest available kernel for the buildroot release, recommended build utils, standard libaries and more. Of course there might be differences depending on what you need for your board, but for the p4note I only had to adjust the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Target options
    &lt;ul&gt;
      &lt;li&gt;all the sub options&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;System configuration
    &lt;ul&gt;
      &lt;li&gt;root password&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Kernel -&amp;gt; Linux Kernel
    &lt;ul&gt;
      &lt;li&gt;defconfig name, binary format for appended DTB and DTB name&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Filesystem images
    &lt;ul&gt;
      &lt;li&gt;an ext4 root file system to put the selected packages on&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Have a look around, it’s not too scary and you should find your way through the menu. After this is done, you can go wild in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Target Packages&lt;/code&gt; menu, there are a ton of options in there. It’s possible to add custom packages in the external tree, have custom pre and post build scripts and more.&lt;/p&gt;

&lt;h2 id=&quot;the-final-product&quot;&gt;The Final Product&lt;/h2&gt;

&lt;p&gt;If you navigate to &lt;a href=&quot;https://github.com/Viciouss/buildroot_external_p4note&quot; target=&quot;_new&quot;&gt;https://github.com/Viciouss/buildroot_external_p4note&lt;/a&gt;, there is a repository which contains a working configuration with wifi, bluetooth and touch screen already prepared. Wifi and Bluetooth is definitely working for the 3G version (N8000) and should also work for the other two variants, but I haven’t tested this.&lt;/p&gt;

&lt;p&gt;Don’t forget to update wpa_supplicant.conf before building, this way it will connect to your wifi and automatically print the IP on the screen after boot so that you can easily SSH into the device. It will also print the USB ethernet IP as well if your prefer to connect this way. Make sure to change the USB IP of the host machine accordingly.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;the &lt;a href=&quot;https://www.buildroot.org/downloads/manual/manual.html&quot;&gt;buildroot documentation&lt;/a&gt; is very good and provides lots of useful information&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>The Boot Image</title>
   <link href="https://viciouss.github.io//2022/01/24/note-10_1-boot_image/"/>
   <updated>2022-01-24T18:00:00+00:00</updated>
   <id>https://viciouss.github.io//2022/01/24/note-10_1-boot_image</id>
   <content type="html">&lt;h2 id=&quot;get-to-know-your-boot-image&quot;&gt;Get to know your Boot Image&lt;/h2&gt;

&lt;p&gt;To boot the device with S-Boot as boot loader, you need to provide an image that has a special format. This format is described on the &lt;a href=&quot;https://source.android.com/devices/bootloader/boot-image-header&quot; target=&quot;_new&quot;&gt;Boot Image Header&lt;/a&gt; page of the AOSP project. In our case, as the device was released with Android 4, this is the legacy header or version 0. It contains the following entries:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;kernel image size and address&lt;/li&gt;
  &lt;li&gt;ramdisk size and address&lt;/li&gt;
  &lt;li&gt;second bootloader size and address&lt;/li&gt;
  &lt;li&gt;some meta data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The interesting part here is the kernel image and ramdisk, on the Galaxy Note 10.1 the second stage boot loader (S-Boot) is not part of the boot image. It resides on its own partition.&lt;/p&gt;

&lt;h2 id=&quot;creating-a-boot-image&quot;&gt;Creating a Boot Image&lt;/h2&gt;

&lt;p&gt;Fortunately, there is a tool to extract and assemble boot images for Android. It’s called &lt;strong&gt;abootimg&lt;/strong&gt; and can be installed with the package manager on probably any of the popular linux distros. The man page should provide enough information to understand how it works.&lt;/p&gt;

&lt;p&gt;What is not explained in detail is the boot image configuration file format. What does it look like? As I mentioned, you can extract boot.img files, so for your device this would be the way to go. Looking at the cfg file for the Note 10.1 and the AOSP description of the header format, you will probably see where this goes:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;bootsize &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 8388608
pagesize &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0x800
kerneladdr &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0x40008000
ramdiskaddr &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0x42000000
secondaddr &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0x40f00000
tagsaddr &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0x40000100
name &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With this information, a sample call to create a boot.img for my case looks like this:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;abootimg &lt;span class=&quot;nt&quot;&gt;--create&lt;/span&gt; myboot.img &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; bootimg.cfg
        &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; ramdisk.xyz
        &lt;span class=&quot;nt&quot;&gt;-k&lt;/span&gt; zImage-dtb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;bootloader-and-the-boot-image&quot;&gt;Bootloader and the Boot Image&lt;/h2&gt;

&lt;p&gt;Now that you know how the image looks like, let’s have a look at the boot process, especially how the boot image is taken care off.&lt;/p&gt;

&lt;p&gt;The second stage boot loader first looks at the boot partition and the boot image header. Depending on the numbers you provided, it puts everything in the right place in the memory of your device and then calls the kernel image entry point. As the device is from 2012 and neither uses nor supports a Device Tree entry in the boot image, parameters are still fed to the kernel with the ATAGS mechanism - that’s what the &lt;strong&gt;tagsaddr&lt;/strong&gt; attribute is for.&lt;/p&gt;

&lt;p&gt;The ATAGS or kernel tagged list is an area in RAM where the boot loader puts parameters for the kernel to consider. There is a hand full of parameters, from memory size and location, ramdisk size and location to serial number, revision and command line. The bootloader then puts the address of this list into the R2 register, next to the R1 register which contains the machine type id. Only with those two pieces of information, the kernel can chose the right path of what to do next.&lt;/p&gt;

&lt;p&gt;Technically, you don’t need the R1 and R2 registers and the parameters from the kernel tagged list, as the Device Tree describes all necessary parameters for a specific device. Remember the config option to attach the DTB file at the end of the kernel? That’s what will work for the mainline kernel. Nevertheless, it is interesting to have these parameters from the boot loader to build the device tree in the first place.&lt;/p&gt;

&lt;p&gt;Let’s have a look at what they are for the Note 10.1 and how the vendor boot image deals with them:&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ATAG_CORE: 5 54410001 0 0 0
ATAG_MEM: 4 54410002 20000000 40000000
ATAG_MEM: 4 54410002 20000000 60000000
ATAG_MEM: 4 54410002 20000000 80000000
ATAG_MEM: 4 54410002 1FC00000 A0000000
ATAG_SERIAL: 4 54410006 aaaaaaaa aaaaaaaa
ATAG_INITRD2: 4 54420005 42000000 3a50bc
ATAG_REVISION: 3 54410007 6
ATAG_CMDLINE: ad 54410009 'console=ttySAC2,115200 loglevel=4 bootmode=2 sec_debug.level=0 sec_watchdog.sec_pet=5 androidboot.debug_level=0x4f4c sec_log=0x200000@0x46000000 sec_tima_log=0x200000@0x46202000 sec_avc_log=0x40000@0x46404000 s3cfb.bootloaderfb=0x5ec00000 sysscope=0xee000000 lcdtype=1 consoleblank=0 lpj=3981312 vmalloc=256m oops=panic pmic_info=1 cordon=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa connie=GT-N8000_OPEN_EUR_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa androidboot.emmc_checksum=3 androidboot.odin_download=1 androidboot.bootloader=N8000XXSDQA7 androidboot.selinux=enforcing androidboot.warranty_bit=0 androidboot.sec_atd.tty=/dev/ttySAC2 androidboot.serialno=aaaaaaaaaaaaaaaa snd_soc_core.pmdown_time=1000'
ATAG_NONE: 0 0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;ATAG_MEM - describes the ram in four banks of 512 MiB each. The last one is actually 4 MiB short, my guess is that this is related to the bootloader process.&lt;/p&gt;

&lt;p&gt;ATAG_SERIAL - the serial number of the device.&lt;/p&gt;

&lt;p&gt;ATAG_INITRD2 - is set to the memory position of the ramdisk that was written to the boot.img configuration with &lt;strong&gt;abootimg&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;ATAG_REVISION - holds a revision number which is used in several places in the vendor kernel to distinguish some board details.&lt;/p&gt;

&lt;p&gt;ATAG_CMDLINE - again rather obvious.&lt;/p&gt;

&lt;p&gt;ATAG_NONE - the end of the tagged list.&lt;/p&gt;

&lt;p&gt;About the revision, this comes to play in &lt;a href=&quot;https://github.com/Viciouss/samsung_p4note_kernel_backup/blob/da306e1846bb4b9682f46be1b23b05d6fbebffba/arch/arm/mach-exynos/p4note-gpio.c#L609&quot; target=&quot;_new&quot;&gt;GPIO configuration&lt;/a&gt;, &lt;a href=&quot;https://github.com/Viciouss/samsung_p4note_kernel_backup/blob/da306e1846bb4b9682f46be1b23b05d6fbebffba/arch/arm/mach-exynos/midas-sensor.c#L287&quot; target=&quot;_new&quot;&gt;sensor positions&lt;/a&gt; or even which &lt;a href=&quot;https://github.com/Viciouss/samsung_p4note_kernel_backup/blob/da306e1846bb4b9682f46be1b23b05d6fbebffba/arch/arm/mach-exynos/p4-input.c#L747&quot; target=&quot;_new&quot;&gt;touch screen IC&lt;/a&gt; is installed. Although both ot the ICs are actually enabled in the defconfig, I’ve never come across one of the international versions of this device that haven’t had the Atmel IC. The Synaptics touch screen might have been in a prototype version or maybe one of the &lt;a href=&quot;https://redmine.replicant.us/projects/replicant/wiki/Exynos4412Devices#Galaxy-Note-101-2012-Edition&quot; target=&quot;_new&quot;&gt;many variants&lt;/a&gt; of the South Korean market which I haven’t been able to spot on any hardware info sites yet.&lt;/p&gt;

&lt;p&gt;After evaluating all those parameters and finishing loading the kernel, the &lt;a href=&quot;https://www.kernel.org/doc/html/latest/admin-guide/initrd.html&quot; target=&quot;_new&quot;&gt;initrd logic&lt;/a&gt; will be executed on the vendor kernel. The ramdisk will be mounted at root and then the kernel runs /sbin/init. As this is already Android territory, we are done here.&lt;/p&gt;

&lt;p&gt;As usual, the kernel docs have some more on booting ARM, e.g. the &lt;a href=&quot;https://www.kernel.org/doc/Documentation/arm/Booting&quot; target=&quot;_new&quot;&gt;ARM boot documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;the original &lt;a href=&quot;https://github.com/Viciouss/samsung_p4note_kernel_backup&quot; target=&quot;_new&quot;&gt;vendor sources&lt;/a&gt; I requested from the &lt;a href=&quot;https://opensource.samsung.com/&quot; target=&quot;_new&quot;&gt;Samsung Open Source&lt;/a&gt; page.&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Building the kernel</title>
   <link href="https://viciouss.github.io//2021/07/17/note-10_1-building_the_kernel/"/>
   <updated>2021-07-17T16:30:00+00:00</updated>
   <id>https://viciouss.github.io//2021/07/17/note-10_1-building_the_kernel</id>
   <content type="html">&lt;h2 id=&quot;the-sobering&quot;&gt;The sobering&lt;/h2&gt;

&lt;p&gt;With the serial connection working, I could get my hands dirty building kernels, right? Well there, not so fast. Where to actually start on a 5.2 kernel? Aside from all the vendor changes and Android kernel patches, there have been 43 major updates in between the Samsung kernel and mainline with lots of internal API changes.Knowing only the old vendor kernel and how it is booted with a &lt;a href=&quot;https://github.com/Viciouss/android_kernel_samsung_smdk4412/blob/cm-14.1/arch/arm/mach-exynos/mach-p4notepq.c&quot; target=&quot;_new&quot;&gt;board file&lt;/a&gt;, I had to learn what a &lt;a href=&quot;https://www.kernel.org/doc/html/latest/devicetree/usage-model.html&quot;&gt;device tree&lt;/a&gt; is. Very disappointing at first, as there was this big hurdle before even being able to build the kernel, but after a while it clicked and as it turned out, I could very much benefit from this right in the next step.&lt;/p&gt;

&lt;h2 id=&quot;device-trees&quot;&gt;Device Trees&lt;/h2&gt;

&lt;p&gt;Both the board file and the device tree describe the hardware of the device. The board file is explicit in this regard as it is written in C code and it loads the drivers directly, it’s rather inflexible and if you want to share code with similar devices, it can get messy quickly. The “modern” approach for ARM devices is a  device tree. It’s a language and data structure on its own, it is abstract and can be split up in smaller parts. You have a common SoC for a dozen devices? Just include the SoC device tree in your board tree and add the additional drivers on top, you are good to go. The abstract nature of device tree files also enables them to be used in other places than the kernel, e.g. a bootloader like U-Boot.&lt;/p&gt;

&lt;p&gt;For the linux kernel, device tree files are compiled into device tree binaries (dtb files) which can then be read on boot to set up the system accordingly. I could gather a lot of information from the existing Exynos4 &lt;a href=&quot;https://github.com/torvalds/linux/blob/v5.2/arch/arm/boot/dts/exynos4412-midas.dtsi&quot; target=&quot;_new&quot;&gt;dts files&lt;/a&gt; which powered &lt;a href=&quot;https://github.com/torvalds/linux/blob/v5.2/arch/arm/boot/dts/exynos4412-i9300.dts&quot; target=&quot;_new&quot;&gt;some&lt;/a&gt; &lt;a href=&quot;https://github.com/torvalds/linux/blob/v5.2/arch/arm/boot/dts/exynos4412-i9305.dts&quot; target=&quot;_new&quot;&gt;Samsung&lt;/a&gt; &lt;a href=&quot;https://github.com/torvalds/linux/blob/v5.2/arch/arm/boot/dts/exynos4412-n710x.dts&quot; target=&quot;_new&quot;&gt;devices&lt;/a&gt; in mainline at that time. I added a new device tree, included the Exynos4412 one and looked for matching nodes in the midas tree, changed IRQ and GPIO configurations and then added some other nodes like the max17042 battery monitor for example. With this minimal tree in place, only the defconfig was missing to create an initial kernel image.&lt;/p&gt;

&lt;h2 id=&quot;defconfig-and-building-the-kernel&quot;&gt;defconfig and building the kernel&lt;/h2&gt;

&lt;p&gt;A defconfig file describes which architecture code and drivers get compiled in the kernel image. The exynos_defconfig looked promising, it already contains all the Exynos4 base drivers and some more, so I added the missing drivers and build the kernel:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# compile for a different architecture, the kernel build needs to know this&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ARCH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;arm
&lt;span class=&quot;c&quot;&gt;# a cross compiler toolchain is needed to do this of course&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CROSS_COMPILE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/opt/gcc-linaro-arm-linux-gnueabihf/bin/arm-linux-gnueabihf- 
&lt;span class=&quot;c&quot;&gt;# this command takes the existing exynos_defconfig and copies it as .config to the &lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# out directory which is then used later on to build the kernel&lt;/span&gt;
make &lt;span class=&quot;nv&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;out exynos_defconfig
&lt;span class=&quot;c&quot;&gt;# before building, edit the .config file, there are some drivers needed for the note 10.1&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# start the kernel config GUI, I prefer nconfig, there is others, use 'make help' for more&lt;/span&gt;
make &lt;span class=&quot;nv&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;out nconfig
&lt;span class=&quot;c&quot;&gt;# everything is in place, build the kernel, the -j parameters tells the compiler&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# how many threads to use, nproc --all returns the number of processors in the system&lt;/span&gt;
make &lt;span class=&quot;nv&quot;&gt;O&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;out &lt;span class=&quot;nt&quot;&gt;-j&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nproc&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--all&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The build usually only takes a couple of minutes on current hardware, from the result there are two files of interest:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;out/arch/arm/boot/zImage&lt;/li&gt;
  &lt;li&gt;out/arch/arm/boot/dts/exynos4412-p4note-n8010.dtb&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The first file is the kernel image itself with all the architecture code and drivers that have been selected. It may contain drivers that are not needed, as is the case for the exynos_defconfig. This defconfig file compiles a kernel that can be used across all the existing exynos devices. But then, how does the kernel know which drivers to load? That’s where the dtb file comes in. But now there is a problem. The version of S-BOOT installed on the Exynos4 devices only knows about a kernel image that includes the board init code, it doesn’t know how to handle a device tree. Luckily, there is a kernel option for this fallback case: CONFIG_ARM_APPENDED_DTB.&lt;/p&gt;

&lt;p&gt;With this enabled, the kernel will look for the DTB file immediately after the kernel code itself. This means that assembling the kernel image with attached DTB file is as easy as:&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cat &lt;/span&gt;out/arch/arm/boot/zImage out/arch/arm/boot/dts/exynos4412-p4note-n8010.dtb &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; zImage-dtb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Going from board file to device tree was an interesting learning experience and it makes sharing device configurations among similar devices an easy process without littering your code with #ifdefs.&lt;/p&gt;

&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;the &lt;a href=&quot;https://bootlin.com/docs/&quot; target=&quot;_new&quot;&gt;training material&lt;/a&gt; from bootlin in general
    &lt;ul&gt;
      &lt;li&gt;in this case the Device Tree 101 presentation from Thomas Petazzoni&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Sk9TatW9ino&quot; target=&quot;_new&quot;&gt;Tutorial: Building the Simplest Possible Linux System&lt;/a&gt; from Rob Landley&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Starting the Samsung Galaxy Note 10.1 Journey</title>
   <link href="https://viciouss.github.io//2020/11/18/note-10_1-journey/"/>
   <updated>2020-11-18T16:00:00+00:00</updated>
   <id>https://viciouss.github.io//2020/11/18/note-10_1-journey</id>
   <content type="html">&lt;p&gt;When I began working on the Note 10.1 at the end of 2018, I thought it can’t be that difficult to patch the device up. Add some lines here, fix a compiler issue there. I’m a software developer after all, how difficult can kernel and Android development be? Oh boy was I wrong.&lt;/p&gt;

&lt;p&gt;I started from not even knowing how to compile a kernel. Luckily, the XDA community has a large forum dedicated to topics like this. I found a &lt;a href=&quot;https://forum.xda-developers.com/android/software-hacking/reference-how-to-compile-android-kernel-t3627297&quot;&gt;tutorial&lt;/a&gt; and got going.&lt;/p&gt;

&lt;p&gt;Fast forward some weeks and a lot of tutorials later, I was going through the old 3.0.x sources from the Note 10.1. The kernel being 7 years old at the time with all the code Samsung introduced, more #ifdefs than I can count and a lot of unusual approaches to solve their user space needs, the learning curve was a roller coaster. From &lt;strong&gt;This looks like fun!&lt;/strong&gt; to &lt;strong&gt;You know nothing Jon Snow&lt;/strong&gt; in mere seconds. It was quite demotivating at times.&lt;/p&gt;

&lt;p&gt;Fast forward again, I somehow stumbled across &lt;a href=&quot;https://web.archive.org/web/20210228191820/https://blog.forkwhiletrue.me/&quot;&gt;forkbombs blog (archive.org)&lt;/a&gt; - and from there the goal was clear. There was no way around getting the Note 10.1 into mainline. The first thing I’d need to start would be a serial connection, unfortunately the Note 10.1 has a 30pin proprietary connector, but it is shared across a hand full of devices. For example on the &lt;a href=&quot;https://forum.xda-developers.com/showthread.php?t=1010314&quot;&gt;Galaxy Tab&lt;/a&gt; - my day was saved.&lt;/p&gt;

&lt;p&gt;After some amateur soldering and wiring things up to a CP2102 module, I got my first lines on the serial connection:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Samsung S-Boot 4.0 for GT-N8000 (Jan  5 2017 - 16:48:45)

EXYNOS4412(EVT 1.1) / 2044MB / 0MB / Rev 6 / N8000XXSDQA7 /(PKG_ID 0xc071018)

BOOTLOADER VERSION : N8000XXSDQA7

BUCK1OUT(vdd_mif) = 0x05
BUCK3DVS1(vdd_int) = 0x20
cardtype: 0x00000007
SB_MMC_HS_52MHZ_1_8V_3V_IO
mmc-&amp;gt;card_caps: 0x00000311
mmc-&amp;gt;host_caps: 0x00000311
[mmc] capacity = 30777344
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
 </entry>
 

</feed>
