DIY Fully working Alpine Linux for Allwinner and Other ARM SOCs: Difference between revisions

From Alpine Linux
No edit summary
No edit summary
Line 51: Line 51:
Notice I have combined SPL with U-boot, it is now possible to generate a single file say '''"u-boot-sunxi-with-spl.bin"'''
Notice I have combined SPL with U-boot, it is now possible to generate a single file say '''"u-boot-sunxi-with-spl.bin"'''


For other ARM SOC based products like
| Area              | ODROID-[C1(+)](http://odroid.com/dokuwiki/doku.php?id=en:c1_partition_table) | ODROID-[C2](http://odroid.com/dokuwiki/doku.php?id=en:c2_partition_table) | ODROID-[U3](http://odroid.com/dokuwiki/doku.php?id=en:u3_partition_table)/[XU3/XU4](http://odroid.com/dokuwiki/doku.php?id=en:xu3_partition_table) | [CuBox-i](http://wiki.solid-run.com/doku.php?id=products:imx6:software:development:u-boot) | [PINE64(+)](https://www.pine64.com/product)
|:---                    |        ---:|        ---:|        ---:|        ---:|          ---:|
| SPL (BL1/BL2)          |    0 -    6 |    0 -  96 |    1 -  62 |    1 -  83 | 16 - 143      |
| U-boot executable      |  64 - 1023 |  97 -  1431|  63 -  718 |  84 -  767 | 38192 - 40959 |
| **U-boot environment** | **1024 - 1087** | **1440 - 1503** | **1231 - 1262** | **768 - 783** | **file based** |
| 1st partition          | 3072 -  ... | 3072 -  ... | 3072 -  ... | 2048 -  ... | 40960 - ...  |
== Boot-loaders aka U-Boot ==
== Boot-loaders aka U-Boot ==
Let us being. The first is to understand U-boot.
Let us being. The first is to understand U-boot.
Line 105: Line 113:


--------------------------------------------------------------------
--------------------------------------------------------------------
Let us write to the SD-Card, I will assume here you already have compiled you kernel, u-boot and move forward. Dont worry we will come back to it at the last. When we need to actually put things on the SD card, be careful with dd it can and will wipe your hard disk if you make a mistake. In my case I had an SD card reader so I set things to point at that slot only by using the by-id links from udev. These by-id links which include the serial number which helped to avoid mistakes. The following commands assume you have done the same and are using by-id links.
Let us write to the SD-Card, I will assume here you already have compiled you kernel, u-boot and move forward. Dont worry we will come back to it at the last.  


Remember to leave sufficient space for all u-boot files when partitioning the card. The u-boot will not have any partition type defined. Recommended to have first fat partition start at sector 2048 (1MB)
When we need to actually put things on the SD card, be careful with dd it can and will wipe your hard disk if you make a mistake. In my case I had an SD card reader so I set things to point at that slot only by using the by-id links from udev. These by-id links which include the serial number which helped to avoid mistakes. The following commands assume you have done the same and are using by-id links.


In linux blank the first 1MB of the card using the following (my sd-card is /dev/sda1
In linux blank the first 1MB of the card using the following (my sd-card is /dev/sda1
Line 115: Line 123:
But you need to be careful when using dd on special files (i.e., devices).   
But you need to be careful when using dd on special files (i.e., devices).   


For example, dd if=(whatever input) of=(a magnetic tape device) bs=1024 count=1 will write one tape block of 1024 bytes;
For example, the below command will write one tape block of 1024 bytes;
 
* dd if=(whatever input) of=(a magnetic tape device) bs=1024 count=1  


dd if=(whatever input) of=(a magnetic tape device) bs=1 count=1024 will write 1024 small blocks of one byte each. 
However, the below command will write 1024 small blocks of one byte each
* dd if=(whatever input) of=(a magnetic tape device) bs=1 count=1024  


These are not the same; the 1024 small blocks will take up more room on the tape than the one large block, because of inter-record gaps, and may cause problems for reading the tape.
These are not the same; the 1024 small blocks will take up more room on the tape than the one large block, because of inter-record gaps, and may cause problems for reading the tape.


Assuming you have got the file u-boot-sunxi-with-spl.bin, it just has to be burned to sd card using the following command:
Now Assuming you have got the file u-boot-sunxi-with-spl.bin, it just has to be burned to sd card using the following command:


* dd if=u-boot-sunxi-with-spl.bin of=/dev/sda bs=1024 seek=8
* dd if=u-boot-sunxi-with-spl.bin of=/dev/sda bs=1024 seek=8
Line 135: Line 147:
* dd if=u-boot.bin of=/dev/sdX bs=1024 seek=32
* dd if=u-boot.bin of=/dev/sdX bs=1024 seek=32


Typically for understanding this is how the layout for SD-Card in above cases is
Typically for understanding, this is how the layout for SD-Card in above cases is;
 
 
Remember to leave sufficient space for all u-boot files when partitioning the card. The u-boot will not have any partition type defined. Recommended to have first fat partition start at sector 2048 (1MB)

Revision as of 13:12, 10 April 2016

This is taken from multiple sources and is copyright of the respective authors, albiet copied shamelessly. If you are an author of a particular section and wish to be listed please dont hesitate to contact me at oneinsect@gmail.com

Comprehensive Introduction

Why do we need alpine linux when there are so many xyz distros available? Well it is one the most lightweight platforms with hot swap support for SD-cards and USB devices. There are options for allocation of SD-card free space for application storage.

There are possibilities to completely upgrade a device running remotely with minimum downtime. Console logins are possible with USB null modems for field servicing. Most importantly you can be rest assured that it can survive against power cuts, restarts. For devices without onboard mmc, especially working on sd-card its way more important.

The philosophy of commit only when required, keeps the entire OS read-only and in-memory without touching the storage at all. Thus devices can survive for longer times without crash.

Arm devices unlike x86 dont come with bios in general. BIOS in x86 PCs is generally, a firmware configuring and connecting the hardware to the operating system and it offers support for a variety of OS and supports new OS versions.

ARM use a different approach involving a boot loader for hardware configuration and operating system start-up. The boot loader is developed specifically for the application, adapted to one well-defined hardware SOC configuration, one operating system and only one version of it, which means you cannot probably use it for other SOCs without significant changes.

We here generally talk about Allwinner especially H3 SOCs but you could probably apply this philosophy to other SOCs. The nanopi m1, Orange pi pc and Orange pi lite are only around $10 making them great home servers, firewalls for lowest possible cost.

A linux os cannot be started just like that on an ARM Device, without a small amount of machine specific code to initialize that system.

There are typically 4 stages involved in the ARM Device boot-up process

  • (stage 1) ROM - Reads from initialized persistent storage (selected by boot mode), loads SPL into internal Ram
  • (stage 2) SPL Loader - SPL once loaded does additional setup and loads from persistent storage bootloader (u-boot) into DDR RAM
  • (stage 3) U-boot - U-boot once loaded continues the processor setup and reads the Linux Kernel into DDR RAM
  • (stage 4) Kernel - Once Kernel is loaded, it boots Linux and initializes the user run time environment

Each stage adds functionality. It is important to note that SPL, U-Boot and the Linux Kernel are all statically linked to start running at specific locations from a memory map defined by the CPU. That memory map is nothing but a layout that defines where both internal memory and DDR are mapped to.

In here we are concerned with SD-Cards, and depending on how the SD card is connected, the location to where to write the data to can be different.

OKAY WAIT!!! WRITING DATA???

Dont be confused, yes you will need to compile from source the SPL Loader and write it to SD-Card in a particular way and then compile u-boot from source and write it in a particular and same goes for the rest. Otherwise how will you boot our favorite alpine linux?

But where do you get the sources? Generally if the SOC is supported in Linux (its called mainline) you can directly use the latest kernel, otherwise you will need to get the sources from the SOC manufacturer.

Below is a SD-CARD layout for typical Allwinner which generally combine U-boot with the SPL loader from block 8. This then loads initramfs etc.

"start" is a 1k-block number here. (Multiply it by two to get the corresponding sector number - assuming 512 byte sectors). This layout works generally for Linux Mainline Kernels 4.x and above

start size usage
0 8KB Unused, available for partition table
8 1024KB Initial SPL loader + u-boot (raw format preferred/vfat)
1024 till end vmlinuz + initramfs + modloop + dtb (format fat + enable boot flag)

Notice I have combined SPL with U-boot, it is now possible to generate a single file say "u-boot-sunxi-with-spl.bin"

For other ARM SOC based products like

| Area | ODROID-[C1(+)](http://odroid.com/dokuwiki/doku.php?id=en:c1_partition_table) | ODROID-[C2](http://odroid.com/dokuwiki/doku.php?id=en:c2_partition_table) | ODROID-[U3](http://odroid.com/dokuwiki/doku.php?id=en:u3_partition_table)/[XU3/XU4](http://odroid.com/dokuwiki/doku.php?id=en:xu3_partition_table) | [CuBox-i](http://wiki.solid-run.com/doku.php?id=products:imx6:software:development:u-boot) | [PINE64(+)](https://www.pine64.com/product) |:--- | ---:| ---:| ---:| ---:| ---:| | SPL (BL1/BL2) | 0 - 6 | 0 - 96 | 1 - 62 | 1 - 83 | 16 - 143 | | U-boot executable | 64 - 1023 | 97 - 1431| 63 - 718 | 84 - 767 | 38192 - 40959 | | **U-boot environment** | **1024 - 1087** | **1440 - 1503** | **1231 - 1262** | **768 - 783** | **file based** | | 1st partition | 3072 - ... | 3072 - ... | 3072 - ... | 2048 - ... | 40960 - ... |

Boot-loaders aka U-Boot

Let us being. The first is to understand U-boot.

Distros like alpine linux for that matter any linux do not need to manipulate any kind of bootloader-specific configuration data to indicate which storage device the system should boot from.

Distros simply need to copy the boot configuration files in an ext2/3/4 or FAT partition, mark the partition bootable (via the MBR bootable flag, or GPT legacy_bios_bootable attribute), and U-Boot (or any other bootloader) will find those boot files and execute them. This is conceptually identical to creating a grub2 configuration file on a desktop PC.

Note that in the absence of any partition that is explicitly marked bootable, U-Boot falls back to searching the first valid partition of a disk for boot configuration files. Other bootloaders are recommended to do the same, since I believe that partition table bootable flags aren't so commonly used outside the realm of x86 PCs.

U-Boot can also search for boot configuration files from a TFTP server. The standard format for boot configuration files is that of extlinux.conf, as handled by U-Boot's "syslinux" (disk) or "pxe boot" (network).

U-Boot searches for /extlinux/extlinux.conf then /boot/extlinux/extlinux.conf on disk, or pxelinux.cfg/default over the network.

One example extlinux.conf generated by the Alpine Linux installer is:


 LABEL grsec
 MENU DEFAULT
 MENU LABEL Linux grsec
 LINUX /boot/vmlinuz-grsec
 INITRD /boot/initramfs-grsec
 DEVICETREEDIR /boot/dtbs
 APPEND BOOT_IMAGE=/boot/vmlinuz-grsec modules=loop,squashfs,sd-mod,usb-storage modloop=/boot/modloop-grsec console=${console}

Another example extlinux.conf is:


 LABEL Linux Mailine 4.6RC2
 LINUX /boot/vmlinuz-4.6.0-rc1-sunxi
 INITRD /boot/initramfs-new.uImage
 FDT /boot/sun8i-h3-orangepi-pc.dtb
 APPEND BOOT_IMAGE=/boot/vmlinuz-4.6.0-rc1-sunxi modules=loop,squashfs,sd-mod,usb-storage modloop=/boot/modloop-sunxi console=${console}

First Steps Compiling

What are you basically looking for? What files do you need to compile, how and where do you need to compile from? And where do you need to put them? How do you need to put them? Well dont worry we will cover them here.

You will need the following files (incase of mainline or 4.x latest kernels incase your SOC is supported - In our case yes Allwinner H3)


  • U-boot bootloader (aka u-boot-sunxi-with-spl.bin file say for Orange pi pc Allwinner H3) - compiled separately
  • Device specific .dtb file (in here called sun8i-h3-orangepi-pc.dtb) generated as part of your mainline kernel compilation
  • Linux Kernel Image either uImage/zImage (In our case zImage called vmlinuz-4.6-rc1-sunxi)
  • Initramfs file (what is it? you will learn as we progress)
  • modloop file (what is it again? you will learn as we progress)
  • boot.scr or extlinux.conf file for telling U-boot where to find all our files

Incase of legacy kernels (3.x etc) you will need the following which we will not cover here


  • uImage (linux kernel)
  • script.bin (converted from fex format, notice we dont talk about dtb files here)
  • ext4/ext3 rootfs file system
  • U-boot bootloader etc

Let us write to the SD-Card, I will assume here you already have compiled you kernel, u-boot and move forward. Dont worry we will come back to it at the last.

When we need to actually put things on the SD card, be careful with dd it can and will wipe your hard disk if you make a mistake. In my case I had an SD card reader so I set things to point at that slot only by using the by-id links from udev. These by-id links which include the serial number which helped to avoid mistakes. The following commands assume you have done the same and are using by-id links.

In linux blank the first 1MB of the card using the following (my sd-card is /dev/sda1

  • dd if=/dev/zero of=/dev/sda bs=1M count=1

But you need to be careful when using dd on special files (i.e., devices).

For example, the below command will write one tape block of 1024 bytes;

  • dd if=(whatever input) of=(a magnetic tape device) bs=1024 count=1

However, the below command will write 1024 small blocks of one byte each

  • dd if=(whatever input) of=(a magnetic tape device) bs=1 count=1024

These are not the same; the 1024 small blocks will take up more room on the tape than the one large block, because of inter-record gaps, and may cause problems for reading the tape.

Now Assuming you have got the file u-boot-sunxi-with-spl.bin, it just has to be burned to sd card using the following command:

  • dd if=u-boot-sunxi-with-spl.bin of=/dev/sda bs=1024 seek=8

Sometimes depending on you compile you can generate spl and u-boot separately (it is not recommended by me) you can install the components separately using

  • dd if=spl/sunxi-spl.bin of=/dev/sda bs=1024 seek=8
  • dd if=u-boot.img of=/dev/sda bs=1024 seek=40

Please note, if you are using old source (v2013.07 or earlier, then the procedure is slightly different)

  • dd if=spl/sunxi-spl.bin of=/dev/sdX bs=1024 seek=8
  • dd if=u-boot.bin of=/dev/sdX bs=1024 seek=32

Typically for understanding, this is how the layout for SD-Card in above cases is;


Remember to leave sufficient space for all u-boot files when partitioning the card. The u-boot will not have any partition type defined. Recommended to have first fat partition start at sector 2048 (1MB)