Monday, December 7, 2015

DIY Homemade ARM Board Running Linux with LCD: Part 4 U-boot Bootloader Porting and Cross Compile


    This post is going to be 4th part in series of making a Linux capable ARM Board at home. click First, Second and Third to go to previous Parts,so lets start.

what is a Bootloader, Why do we need it? 

a boot loader is a program which is the first one to be executed by the CPU. it severs some very specific purpose "configuring few very essential things before loading the main program (may be OS) into main memory" , that is why it is called boot loader. depending on needs boot loader may do some other task(we will cover them here).
there are various shape and sizes of the bootloaders , they all serve almost same purpose.

with microcontrollers , some times it does not actually load the main program into memory but pass on the executing pointer to main program so that main program can run directly form the memory where it is.
Board With 4.3 inch LCD running Qt5 application to display JPEG Image and Time

        Need of a bootloader in mircocontroller is different than CPU , for MCU bootloaders are generally ment to have capablity of software update. MCU are capable of executing without bootloader at all. bootloader are not required but they add some luxury. 
      Lets start with a simple mircontroller bootloader which updates the MCU firmware, there may be different type here also, depending on from where they receive main program and to where they write. like you may have a UART bootloader , which will come up every time CPU resets , in case of program update required or requested. Bootloader receive executable  program over UART and program it into flash or just put into RAM(some Mircocontrollers have only RAM for execution like cypress  CY7C68013A they always need to receive program on startup either via USB or external EEPROM , CY7C68013A  has ROM based bootloader which is onchip , supplied by the cypress).another Bootloader may be  USB based Bootloader will also do same , but it receive program over USB bus and program into flash or put it into RAM.

          
       For mircontroller almost all the absolutely crucial peripherals (like RAM , Clock ,Power) are initialized by the chip in the hardware itself. microcontroller hardware know where exactly to look for  program in the flash or in any other memory.with MCU everthing thing is onchip , hardware know where it what . he knows mebmory size and all the buses too. almost nothing can change or go wrong. all the peripherals on the MCU are hard-wired by the chip designer.

     

     Need of  Bootloader with CPU is different , they are responsible to configure some of hardware like external RAM parameters Size,Memory Bus width , timings , Power subsystem etc. they are also responsible to load the kernel file from a sophisticated file system rather than a fixed memory location. Bootloader is almost always required if you are trying to run some resource consuming main progam.

      With CPU , hardware generally have a very basic ability "same as mircocontrollers" to load some "small" executable program from some fixed external memory (few processors have more than one option . like few CPU reads a particular sector in SD card or NAND flah. or even few processor are capable of loading the program from USB or UART. "almost" no CPU has onchip flash for customer code. after loading the program from external ROM into internal memory CPU start executing bootloader . please note that all descent CPU has  large amount of RAM off Chip. but they still bootloader get  into onchip RAM instead off chip RAM. because at the time of reset CPU doen't even know even the external RAM is connected , or even if it is connected then how it is connected. so the only way you can execute bootloader progam is onchip RAM , CPU start executing bootloader from onchip RAM and all the information about the hardware will be available with bootloader. Allwinner A13 has 48K SRAM onchip.  all CPU are capable of running only with onchip RAM you don't need any external memory but as application demands we need to connect more RAM. 

it is the same reason CPU can't just go and load OS out of external memory and start executing. because at the start-up , there is only a tiny amount of onchip RAM is considered to be usable.and you can not load comparably  large size OS image into this small onchip RAM start executing. 

you need some light weight program which can be loaded into limited amount of internal RAM , and configure all other stuff including Large External RAM, load OS file from some sophisticated source like , FAT or ext file system or even network into the Large RAM. and transfer the executing control to that. 

only after configuration of  RAM parameters ,external RAM is considered to be usable. bootloader also configure clock , PMU power regulator setting , during boot GPIO and other peripheral state like LCD Splash Screen and so on.

U-boot

 u-boot is just one of many bootloader programs , the good things about this is , as then name says in it is universal bootloader , it already support many different architecture. because it is already ported by large community to many different Architecture so it is very famous. it is open source.

u-boot already ported to the CPU which we are using here the Allwinner A13, u-boot already support the booting medium we need "FAT File system".

so it is always a wise choice to chose already ported U-boot rather than making your own . it is even worse to try porting some architecture specific bootloader to your platform.

but still as every hardware is different in one way or another, some modification to u-boot required to support your new Hardware.  like we have some RAM configuration changes, LCD power and Backlit controls are with the PMU and u-boot manage them. there can be many such things depending your hardware configuration.

sunxi is linux community that support allwinner procesosor 

the sunxi uboot already ported to A13 CPU "not to our board" is availalb at this github repo 
https://github.com/linux-sunxi/u-boot-sunxi   ( this version is old , have not much use) 

there are two branches there , one is "sunxi" branch  which is leagcy u-boot , it support linux kernel 3.4 , and very very stable. but i will be using standard u-boot as we will be having mainline linux kernel (4.12 ) so it is better to port standard u-boot from denx website . 

New version of kernel does not support many features like 3D graphics GPU acceleration etc. if you need Mali GPU to work you need to use old version of kernel. 

this guild can be take as  "how to  port u-boot to custom  board"

clone  u-boot from denx git

git clone git://git.denx.de/u-boot.git




before you do any thing you need a config file for your board

config file for all board  persend in u-boot/configs directory

here is look at few of the board config files present in config directory.



key to making a new config file is , locate a Board file with same processor , similar RAM and other peripheral .

as we are using sunxi A13 , may files are already present with same processor , olimax micro is the closest match.

i have created a default board file for my board which you can see in image blow.



CONFIG file give blow is also present in my repo of u-boot in my github account.
https://github.com/circuitvalley/u-boot-ttymay

config file specify various parameters , which CPU is this, How much RAM frequency , which is card detect pin for cd card, verious hardware control pin , PMU settings , a really important device tree file name. LCD need to be configured or not.




CONFIG_ARM=y
CONFIG_ARCH_SUNXI=y
CONFIG_MACH_SUN5I=y
CONFIG_DRAM_CLK=408
CONFIG_DRAM_EMR1=0
CONFIG_MMC0_CD_PIN="PG0"
CONFIG_USB0_VBUS_DET="PG1"
CONFIG_USB0_VBUS_PIN="PB10"
CONFIG_DEFAULT_DEVICE_TREE="sun5i-ttymay"
CONFIG_SPL=y
CONFIG_AXP_GPIO=y
# CONFIG_VIDEO_HDMI is not set
CONFIG_VIDEO_LCD_POWER="AXP0-1"
CONFIG_SPL_I2C_SUPPORT=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_ISO_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
CONFIG_USB_EHCI_HCD=y
CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:40,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0"

https://github.com/circuitvalley/u-boot-ttymay/blob/v2017.05/configs/ttymay_defconfig


i have to modify Driver file for MMC also as my board has inverted CARD dectect pin . in U-boot as far as i know there is no runtime way to invert Card detect.so i have to invert this in driver code.

drivers/mmc/mmc.c

@@ -853,7 +853,7 @@ int mmc_getcd(struct mmc *mmc)
853853
    cd = 1;
854854
  }
855855
 
856
- return cd;
856
+ return !cd;
857857
 }
858858
 #endif
859859
 


now you need to add device tree file for your board ,  device tree file are present in u-boot/arch/arm/dts  directory .


just make a copy of your board file which you are using for defconfig file , in my case made a copy of sun5i-olimex-micro board.

in device file you specify everything about the hardware of your board , this config will also be used by linux kernel.

specify model and compatible of your board , you can put any string you like but as we depend on tons of allwinner sun5i-a13 files , so allwinner entry remains same.

model = "circuitvalley ttymay";
compatible = "circuitvalley,ttymay", "allwinner,sun5i-a13";

you can take a look at commit what exactly i modified 
https://github.com/circuitvalley/u-boot-ttymay/commit/f217e3640df4478e2503050bc50f4686dfb2a700

in device tree it is possible to invert card detect pin so you can put CD property in DTS file

Now we have all of our source ready. lets apply ttymay_defconfig and cross compile

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- ttymay_defconfig

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8 


if compiled successfully it should give u-boot-sunxi-with-spl.bin file , you need to put file into SDcard onto a specific location using dd.


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

you can also  look at sunxi guild  to look for how to prepare sd card .

you will also need boot.cmd file which you will parse using mkimage comand to have boot.scr

boot.scr have necessary instruction to u-boot , like from where to get kernel file and so on.

here is content of boot.cmd file
setenv bootargs console=ttyS0,115200  root=/dev/mmcblk0p2 rootwait panic=10
load mmc 0 0x43000000 sun5i-ttymay.dtb 
load mmc 0 0x42000000 uImage 
bootm 0x42000000 - 0x43000000


you need to put boot.scr on first partition of sd card. which is a FAT partition where kernel image is also present.
mkimage -C none -A arm -T script -d boot.cmd boot.scr










7 comments:

  1. Hello
    Can you help me ,to customize this project?

    ReplyDelete
    Replies
    1. Yes i can help you to make custom Linux board.

      Delete
    2. Thank you so how can i start?
      I am an electronic bachelor, and I have microcontroller board design experience. I can also work with the Altium software. And I want to design a simple Linux board, but I have no idea. what do I do ?
      Thanks a lot

      Delete
  2. hi how we can add a wifi module to it
    tanks for your project

    ReplyDelete
    Replies
    1. Easy way would be to add USB wifi module on USB port. or with PCB redesign add WIFI module to SDIO or USB or even if slow speed tolerable then use UART.

      Delete
  3. wow awesome really..
    thank you so much..

    ReplyDelete