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.
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.
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=yCONFIG_ARCH_SUNXI=yCONFIG_MACH_SUN5I=yCONFIG_DRAM_CLK=408CONFIG_DRAM_EMR1=0CONFIG_MMC0_CD_PIN="PG0"CONFIG_USB0_VBUS_DET="PG1"CONFIG_USB0_VBUS_PIN="PB10"CONFIG_DEFAULT_DEVICE_TREE="sun5i-ttymay"CONFIG_SPL=yCONFIG_AXP_GPIO=y# CONFIG_VIDEO_HDMI is not setCONFIG_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 setCONFIG_USB_EHCI_HCD=yCONFIG_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"
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.
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
in device tree it is possible to invert card detect pin so you can put CD property in DTS file
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.
you can also look at sunxi guild to look for how to prepare sd card .
sudo dd if=u-boot-sunxi-with-spl.bin of=/dev/sdc bs=1024 seek=8
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=10load mmc 0 0x43000000 sun5i-ttymay.dtbload mmc 0 0x42000000 uImagebootm 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