U boot porting guide for SoC

12,119 views

Published on

Published in: Technology

U boot porting guide for SoC

  1. 1. U-boot porting guide for SoC. Take NDS32 architecture as an example. Macpaul Lin macpaul <at> gmail.com 2012/Jan/13
  2. 2. Outline <ul><li>Introduction. </li></ul><ul><li>Directory structure of u-boot. </li></ul><ul><li>Architecture and SoC related parts. </li></ul><ul><li>Board specific files. </li></ul><ul><li>Configuration files. </li></ul><ul><li>Device driver related parts. </li></ul><ul><li>Documents and miscs. </li></ul><ul><li>Debug techniques. </li></ul><ul><li>Commit techniques. </li></ul><ul><li>Debug techniques. </li></ul><ul><li>Summary. </li></ul>
  3. 3. Introduction <ul><li>This presentation tell you how to port u-boot for a SoC chip. </li></ul><ul><ul><li>This presentation is based on NDS32 architecture CPU core. </li></ul></ul><ul><ul><li>This presentation is based on release ftp://ftp.denx.de/pub/u-boot/u-boot-2011.12.tar.bz2 </li></ul></ul><ul><li>You will need to read the bootstrap process of u-boot as your background to continue on this slide. </li></ul><ul><li>CPU and memory controller (lowlevel_init.S) setup procedure didn’t covered in this slide. </li></ul>
  4. 4. Introduction <ul><li>The software framework of u-boot follows Linux’s category and directory placement concepts. </li></ul><ul><li>u-boot uses the following terminologies to identify which SoC and board to be build. </li></ul><ul><li>boards.cfg </li></ul><ul><ul><li>Target </li></ul></ul><ul><ul><li>ARCH </li></ul></ul><ul><ul><li>CPU </li></ul></ul><ul><ul><li>Board name </li></ul></ul><ul><ul><li>Vendor </li></ul></ul><ul><ul><li>SoC </li></ul></ul><ul><ul><li>Options </li></ul></ul>
  5. 5. Directory structure of u-boot. <ul><li>u-boot </li></ul><ul><ul><li>|-- api </li></ul></ul><ul><ul><li>|-- arch </li></ul></ul><ul><ul><li>|-- board </li></ul></ul><ul><ul><li>|-- common </li></ul></ul><ul><ul><li>|-- disk </li></ul></ul><ul><ul><li>|-- doc </li></ul></ul><ul><ul><li>|-- drivers </li></ul></ul><ul><ul><li>|-- examples </li></ul></ul><ul><ul><li>|-- fs </li></ul></ul><ul><ul><li>|-- include </li></ul></ul><ul><ul><li>|-- lib </li></ul></ul><ul><ul><li>|-- mmc_spl </li></ul></ul><ul><ul><li>|-- nand_spl </li></ul></ul><ul><ul><li>|-- net </li></ul></ul><ul><ul><li>|-- onenand_ipl </li></ul></ul><ul><ul><li>|-- post </li></ul></ul><ul><ul><li>|-- spl </li></ul></ul><ul><ul><li>`-- tools </li></ul></ul><ul><li>api </li></ul><ul><ul><li>API for standalone applications. </li></ul></ul><ul><li>arch </li></ul><ul><ul><li>Architecture and SoC related basics. </li></ul></ul><ul><li>board </li></ul><ul><ul><li>Board setup and configuration relatives. </li></ul></ul><ul><li>common </li></ul><ul><ul><li>Commands and some middleware. </li></ul></ul><ul><li>drivers </li></ul><ul><ul><li>Middleware and APIs for peripherals, as well as device drivers are included. </li></ul></ul><ul><li>fs </li></ul><ul><ul><li>Supported various filesystems. </li></ul></ul><ul><li>include: </li></ul><ul><ul><li>Board configuration files and common include headers. </li></ul></ul><ul><li>lib </li></ul><ul><ul><li>Common libraries such as sorting, compress, crc, hashtable, etc. </li></ul></ul><ul><li>net </li></ul><ul><ul><li>Protocol stack of network library and network APIs. </li></ul></ul><ul><li>tools: </li></ul><ul><ul><li>Miscellaneous supporting tools. </li></ul></ul>
  6. 6. Directory structure ARCH – CPU/SoC <ul><li>arch/nds32/cpu </li></ul><ul><li>`-- n1213 </li></ul><ul><li>|-- Makefile </li></ul><ul><li>|-- ag101 </li></ul><ul><li>| |-- Makefile </li></ul><ul><li>| |-- asm-offsets.c </li></ul><ul><li>| |-- cpu.c </li></ul><ul><li>| |-- lowlevel_init.S </li></ul><ul><li>| |-- timer.c </li></ul><ul><li>| `-- watchdog.S </li></ul><ul><li>|-- ag102 </li></ul><ul><li>| |-- Makefile </li></ul><ul><li>| |-- asm-offsets.c </li></ul><ul><li>| |-- cpu.c </li></ul><ul><li>| |-- lowlevel_init.S </li></ul><ul><li>| |-- timer.c </li></ul><ul><li>| `-- watchdog.S </li></ul><ul><li>|-- start.S </li></ul><ul><li>`-- u-boot.lds </li></ul><ul><li>${arch}/${arch name}/${cpu type} </li></ul><ul><li>n1213: CPU model </li></ul><ul><ul><li>(one of the configuration type of N12 CPU core family. </li></ul></ul><ul><ul><li>start.S </li></ul></ul><ul><ul><ul><li>Common start up (ASM code) of n1213 cpu core. </li></ul></ul></ul><ul><ul><li>U-boot.lds </li></ul></ul><ul><ul><ul><li>Common linker script of n1213 cpu core. </li></ul></ul></ul><ul><ul><li>ag101/ </li></ul></ul><ul><ul><ul><li>${SoC} with peripherals functions support basic operations. </li></ul></ul></ul><ul><ul><li>ag102/ </li></ul></ul><ul><ul><ul><li>The other ${SoC} using n1213 CPU core with peripherals functions support basic operations. </li></ul></ul></ul>
  7. 7. Directory structure ARCH – include headers <ul><li>arch/nds32/include/ </li></ul><ul><li>`-- asm </li></ul><ul><li>|-- arch-ag101 </li></ul><ul><li>| `-- ag101.h </li></ul><ul><li>|-- bitops.h </li></ul><ul><li>|-- byteorder.h </li></ul><ul><li>|-- cache.h </li></ul><ul><li>|-- config.h </li></ul><ul><li>|-- global_data.h </li></ul><ul><li>|-- io.h </li></ul><ul><li>|-- mach-types.h </li></ul><ul><li>|-- macro.h </li></ul><ul><li>|-- posix_types.h </li></ul><ul><li>|-- processor.h </li></ul><ul><li>|-- ptrace.h </li></ul><ul><li>|-- string.h </li></ul><ul><li>|-- system.h </li></ul><ul><li>|-- types.h </li></ul><ul><li>|-- u-boot-nds32.h </li></ul><ul><li>|-- u-boot.h </li></ul><ul><li>`-- unaligned.h </li></ul><ul><li>asm/arch-ag101/ag101.h </li></ul><ul><ul><li>Memory mapped hardware addresses. </li></ul></ul><ul><li>global_data.h: </li></ul><ul><ul><li>Architecture specific configuration of register to global data structure for u-boot. </li></ul></ul><ul><li>mach-types.h </li></ul><ul><ul><li>Machine model and ID for SoC and variants, should be sync with Linux kernel. (as well as ARM’s) </li></ul></ul><ul><li>u-boot-nds32.h </li></ul><ul><ul><li>NDS32 specific global symbol and function reference for u-boot. </li></ul></ul><ul><li>u-boot.h </li></ul><ul><ul><li>Board information supported by NDS32 architecture used in u-boot. </li></ul></ul><ul><li>Other’s header files are implemented for I/O operations and byte-order swapping functions. </li></ul>
  8. 8. Directory structure ARCH – lib (common part) <ul><li>arch/nds32/lib/ </li></ul><ul><li>|-- Makefile </li></ul><ul><li>|-- board.c </li></ul><ul><li>|-- bootm.c </li></ul><ul><li>`-- interrupts.c </li></ul><ul><li>${arch}/${arch name}/lib </li></ul><ul><ul><li>board.c </li></ul></ul><ul><ul><ul><li>Common initialization process for all SoC and boards. </li></ul></ul></ul><ul><ul><ul><li>init_sequence() </li></ul></ul></ul><ul><ul><ul><ul><li>Peripheral setup in board_init_f(). </li></ul></ul></ul></ul><ul><ul><ul><li>board_init_f() </li></ul></ul></ul><ul><ul><ul><ul><li>Counting reserved stack size and address before relocation and entering C environment. </li></ul></ul></ul></ul><ul><ul><ul><li>board_init_r() </li></ul></ul></ul><ul><ul><ul><ul><li>Board setup and peripheral probing after relocation. </li></ul></ul></ul></ul><ul><ul><ul><li>Other devices initialization wrapper. (Dispatch functions into board/${board}.c </li></ul></ul></ul><ul><ul><li>bootm.c </li></ul></ul><ul><ul><ul><li>Boot from memory implementation for Linux and other OS. </li></ul></ul></ul><ul><ul><li>interrupts.c </li></ul></ul><ul><ul><ul><li>Generic interrupt implementations of NDS32 architecture. </li></ul></ul></ul>
  9. 9. Directory structure Board <ul><li>board/AndesTech/ </li></ul><ul><li>|-- adp-ag101 </li></ul><ul><li>| |-- Makefile </li></ul><ul><li>| `-- adp-ag101.c </li></ul><ul><li>|-- adp-ag101p </li></ul><ul><li>| |-- Makefile </li></ul><ul><li>| `-- adp-ag101p.c </li></ul><ul><li>`-- adp-ag102 </li></ul><ul><li>|-- Makefile </li></ul><ul><li>`-- adp-ag102.c </li></ul><ul><li>board/${vendor} </li></ul><ul><ul><li>${board name} </li></ul></ul><ul><ul><ul><li>C files. </li></ul></ul></ul><ul><ul><ul><ul><li>On chip or on board peripheral setup. </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Board (product model) specific peripheral setup. </li></ul></ul></ul></ul><ul><ul><ul><li>board_init() </li></ul></ul></ul><ul><ul><ul><ul><li>MACHINE_TYPE </li></ul></ul></ul></ul><ul><ul><ul><li>dram_init() </li></ul></ul></ul><ul><ul><ul><ul><li>Get actual ram size. </li></ul></ul></ul></ul><ul><ul><ul><li>board_eth_init() </li></ul></ul></ul><ul><ul><ul><li>board_mmc_init() </li></ul></ul></ul><ul><ul><ul><li>pci_init() </li></ul></ul></ul><ul><ul><ul><li>board_init() will be called by lib/board.c </li></ul></ul></ul>
  10. 10. Directory structure Common <ul><li>common/ </li></ul><ul><li>|-- Makefile </li></ul><ul><li>|-- bedbug.c </li></ul><ul><li>|-- cmd_ambapp.c </li></ul><ul><li>|-- cmd_bdinfo.c </li></ul><ul><li>|-- cmd_bedbug.c </li></ul><ul><li>|-- cmd_bmp.c </li></ul><ul><li>|-- cmd_boot.c </li></ul><ul><li>|-- cmd_bootldr.c </li></ul><ul><li>... </li></ul><ul><li>Common functions implemented for all SoC and all boards. </li></ul><ul><ul><li>User commands. </li></ul></ul><ul><ul><li>Common API between user commands and middleware. </li></ul></ul><ul><ul><li>“ dlmalloc” memory management implementation. </li></ul></ul><ul><ul><li>Other protocol adaptable middleware. </li></ul></ul>
  11. 11. Directory structure Drivers <ul><li>drivers/ </li></ul><ul><li>|-- bios_emulator </li></ul><ul><li>|-- block </li></ul><ul><li>|-- dma </li></ul><ul><li>|-- fpga </li></ul><ul><li>|-- gpio </li></ul><ul><li>|-- hwmon </li></ul><ul><li>|-- i2c </li></ul><ul><li>|-- input </li></ul><ul><li>|-- misc </li></ul><ul><li>|-- mmc </li></ul><ul><li>|-- mtd </li></ul><ul><li>|-- net </li></ul><ul><li>|-- pci </li></ul><ul><li>|-- pcmcia </li></ul><ul><li>|-- power </li></ul><ul><li>|-- qe </li></ul><ul><li>|-- rtc </li></ul><ul><li>|-- serial </li></ul><ul><li>|-- spi </li></ul><ul><li>|-- tpm </li></ul><ul><li>|-- twserial </li></ul><ul><li>|-- usb </li></ul><ul><li>|-- video </li></ul><ul><li>`-- watchdog </li></ul><ul><li>Drivers collection for middleware APIs and device drivers. </li></ul><ul><ul><li>API definition and software stack of middleware. </li></ul></ul><ul><ul><li>Device driver implemented according to APIs of specific driver category. </li></ul></ul><ul><ul><li>ex. </li></ul></ul><ul><ul><ul><li>drivers/mmc/mmc.c </li></ul></ul></ul><ul><ul><ul><ul><li>API and internal software middleware implemented against to MMC/SD specification. </li></ul></ul></ul></ul><ul><ul><ul><li>drivers/mmc/ftsdc010_esdhc.c </li></ul></ul></ul><ul><ul><ul><ul><li>ftsdc010 device driver hooked to mmc.c </li></ul></ul></ul></ul>
  12. 12. Directory structure FS <ul><li>fs/ </li></ul><ul><li>|-- cramfs </li></ul><ul><li>|-- ext2 </li></ul><ul><li>|-- fat </li></ul><ul><li>|-- fdos </li></ul><ul><li>|-- jffs2 </li></ul><ul><li>|-- reiserfs </li></ul><ul><li>|-- ubifs </li></ul><ul><li>`-- yaffs2 </li></ul><ul><li>Supported file system used on </li></ul><ul><ul><li>SATA </li></ul></ul><ul><ul><li>USB storage </li></ul></ul><ul><ul><li>SD cards </li></ul></ul><ul><ul><li>etc. </li></ul></ul>
  13. 13. Directory structure Include <ul><li>include/ </li></ul><ul><li>|-- andestech </li></ul><ul><li>|-- asm-generic </li></ul><ul><li>|-- bedbug </li></ul><ul><li>|-- configs </li></ul><ul><li>| |-- km </li></ul><ul><li>| `-- manroland </li></ul><ul><li>|-- cramfs </li></ul><ul><li>|-- faraday </li></ul><ul><li>|-- galileo </li></ul><ul><li>|-- jffs2 </li></ul><ul><li>|-- linux </li></ul><ul><li>| |-- byteorder </li></ul><ul><li>| |-- mtd </li></ul><ul><li>| |-- unaligned </li></ul><ul><li>| `-- usb </li></ul><ul><li>|-- lzma </li></ul><ul><li>|-- mtd </li></ul><ul><li>|-- pcmcia </li></ul><ul><li>|-- synopsys </li></ul><ul><li>|-- u-boot </li></ul><ul><li>`-- usb </li></ul><ul><li>Header files used for all SoC, boards, middleware and other software. </li></ul><ul><li>include/configs </li></ul><ul><ul><li>board configuration files. </li></ul></ul><ul><li>include/andestech </li></ul><ul><ul><li>Header files of device controllers develop by Andestech Corporation. </li></ul></ul><ul><ul><li>Includes export functions which will be called by device driver and other files (like board.c). </li></ul></ul><ul><li>include/faraday </li></ul><ul><ul><li>Header files of device controllers develop by Faraday Corporation. </li></ul></ul><ul><ul><li>Includes export functions which will be called by device driver and other files (like board.c). </li></ul></ul><ul><li>include/linux </li></ul><ul><ul><li>Header files ported from Linux for generic byte operations and device drivers ported from Linux. </li></ul></ul>
  14. 14. Directory structure Tools <ul><li>tools/ </li></ul><ul><li>|-- Makefile </li></ul><ul><li>|-- aisimage.c </li></ul><ul><li>|-- aisimage.h </li></ul><ul><li>|-- bin2header.c </li></ul><ul><li>|-- bmp_logo.c </li></ul><ul><li>|-- checkpatch.pl </li></ul><ul><li>|-- default_image.c </li></ul><ul><li>|-- easylogo </li></ul><ul><li>| |-- Makefile </li></ul><ul><li>| |-- easylogo.c </li></ul><ul><li>| |-- linux_blackfin.tga </li></ul><ul><li>| |-- linux_logo.tga </li></ul><ul><li>| `-- runme.sh </li></ul><ul><li>|-- env </li></ul><ul><li>| |-- Makefile </li></ul><ul><li>| |-- README </li></ul><ul><li>| |-- fw_env.c </li></ul><ul><li>| |-- fw_env.config </li></ul><ul><li>| |-- fw_env.h </li></ul><ul><li>| `-- fw_env_main.c </li></ul><ul><li>|-- envcrc.c </li></ul><ul><li>|-- mingw_support.c </li></ul><ul><li>|-- mingw_support.h </li></ul><ul><li>|-- mkenvimage.c </li></ul><ul><li>|-- mkimage.c </li></ul><ul><li>|-- mkimage.h </li></ul><ul><li>|-- mpc86x_clk.c </li></ul><ul><li>|-- mxsboot.c </li></ul><ul><li>Tools for integrating u-boot </li></ul><ul><li>checkpatch.pl </li></ul><ul><ul><li>Patch examination tool for coding style correction. </li></ul></ul><ul><ul><li>Must use this to check your patch before sending it to mailing list. </li></ul></ul><ul><li>mkimage.c: </li></ul><ul><ul><li>Tools for generating Linux binary which could be booted by u-boot. </li></ul></ul>
  15. 15. Architecture and SoC related parts <ul><li>arch/nds32/cpu </li></ul><ul><li>`-- n1213 </li></ul><ul><li>|-- Makefile </li></ul><ul><li>|-- ag101 </li></ul><ul><li>| |-- Makefile </li></ul><ul><li>| |-- asm-offsets.c </li></ul><ul><li>| |-- cpu.c </li></ul><ul><li>| |-- lowlevel_init.S </li></ul><ul><li>| |-- timer.c </li></ul><ul><li>| `-- watchdog.S |-- ag102 </li></ul><ul><li>| |-- Makefile </li></ul><ul><li>| |-- asm-offsets.c </li></ul><ul><li>| |-- cpu.c </li></ul><ul><li>| |-- lowlevel_init.S </li></ul><ul><li>| |-- timer.c </li></ul><ul><li>| `-- watchdog.S </li></ul><ul><li>|-- start.S </li></ul><ul><li>`-- u-boot.lds </li></ul><ul><li>${arch}/${arch name}/${cpu type} </li></ul><ul><li>n1213: CPU model </li></ul><ul><ul><li>(one of the configuration type of N12 CPU core family. </li></ul></ul><ul><ul><li>start.S </li></ul></ul><ul><ul><ul><li>Common start up (ASM code) of n1213 cpu core. </li></ul></ul></ul><ul><ul><li>U-boot.lds </li></ul></ul><ul><ul><ul><li>Common linker script of n1213 cpu core. </li></ul></ul></ul><ul><ul><li>ag101 SoC </li></ul></ul><ul><ul><ul><li>asm-offsets.c </li></ul></ul></ul><ul><ul><ul><ul><li>C structure to ASM offset conversion file. </li></ul></ul></ul></ul><ul><ul><ul><li>cpu.c </li></ul></ul></ul><ul><ul><ul><ul><li>Generic operation of this CPU core. (Cache, reset, etc.) </li></ul></ul></ul></ul><ul><ul><ul><li>lowlevel_init.S </li></ul></ul></ul><ul><ul><ul><ul><li>Memory controller initialization code. </li></ul></ul></ul></ul><ul><ul><ul><li>watchdog.S </li></ul></ul></ul><ul><ul><ul><ul><li>Disable watchdog to prevent non-expected reset during booting secquence. </li></ul></ul></ul></ul><ul><ul><ul><li>timer.c </li></ul></ul></ul><ul><ul><ul><ul><li>Timer driver and initialization code for specific SoC. </li></ul></ul></ul></ul>
  16. 16. Architecture and SoC related parts <ul><li>ag101.h </li></ul><ul><ul><li>Define memory mapped device address (base address) tables. </li></ul></ul><ul><ul><li>Write this table at first when you start to port a SoC. </li></ul></ul><ul><li>arch/nds32/include/ </li></ul><ul><li>`-- asm </li></ul><ul><li>|-- arch-ag101 </li></ul><ul><li>| `-- ag101.h </li></ul><ul><li>`-- arch-ag102 </li></ul><ul><li>`-- ag102.h </li></ul><ul><li>ag101.h: </li></ul><ul><li>/* AHB Controller */ </li></ul><ul><li>#define CONFIG_FTAHBC020S_BASE 0x90100000 </li></ul><ul><li>/* Static Memory Controller (SRAM) */ </li></ul><ul><li>#define CONFIG_FTSMC020_BASE 0x90200000 </li></ul><ul><li>/* FTSDMC021 SDRAM Controller */ </li></ul><ul><li>#define CONFIG_FTSDMC021_BASE 0x90300000 </li></ul><ul><li>/* DMA Controller */ </li></ul><ul><li>#define CONFIG_FTDMAC020_BASE 0x90400000 </li></ul><ul><li>/* AHB-to-APB Bridge */ </li></ul><ul><li>#define CONFIG_FTAPBBRG020S_01_BASE 0x90500000 </li></ul><ul><li>/* LCD Controller */ </li></ul><ul><li>#define CONFIG_ FTLCDC100 _BASE 0x90600000 </li></ul>Use full model name of your peripheral devices
  17. 17. Architecture and SoC related parts <ul><li>arch/nds32/cpu </li></ul><ul><li>`-- n1213 </li></ul><ul><li>|-- Makefile </li></ul><ul><li>|-- ag101 </li></ul><ul><li>| `-- asm-offsets.c </li></ul><ul><li>|-- ag102 </li></ul><ul><li>| `-- asm-offsets.c </li></ul><ul><li>asm-offsets.c </li></ul><ul><ul><li>C structure to ASM offset conversion file. </li></ul></ul><ul><ul><li>This will be converted into “include/generated/asm-offsets.h” automatically when compiling. </li></ul></ul><ul><li>asm-offsets.c: </li></ul><ul><li>#include <common.h> </li></ul><ul><li>#include <linux/kbuild.h> </li></ul><ul><li>int main(void) </li></ul><ul><li>{ </li></ul><ul><li>#ifdef CONFIG_FTSMC020 </li></ul><ul><li>OFFSET(FTSMC020_BANK0_CR, ftsmc020, bank[0].cr); </li></ul><ul><li>OFFSET(FTSMC020_BANK0_TPR, ftsmc020, bank[0].tpr); </li></ul><ul><li>#endif </li></ul><ul><li>BLANK(); </li></ul><ul><li>... </li></ul><ul><li>return 0; </li></ul><ul><li>} </li></ul><ul><li>include/generated/asm-offsets.h: </li></ul><ul><li>#define FTSMC020_BANK0_CR (0) /* offsetof(struct ftsmc020, bank[0].cr) */ </li></ul><ul><li>#define FTSMC020_BANK0_TPR (4) /* offsetof(struct ftsmc020, bank[0].tpr) */ </li></ul><ul><li>#define FTAHBC020S_SLAVE_BSR_6 (24) /* offsetof(struct ftahbc02s, s_bsr[6]) */ </li></ul><ul><li>#define FTAHBC020S_CR (136) /* offsetof(struct ftahbc02s, cr) */ </li></ul>Traditional “defined” address offsets. (in decimal bytes.) Use the same conversion method as Linux.
  18. 18. Board specific files. <ul><li>board/AndesTech/ </li></ul><ul><li>|-- adp-ag101 </li></ul><ul><li>| |-- Makefile </li></ul><ul><li>| `-- adp-ag101.c </li></ul><ul><li>|-- adp-ag101p </li></ul><ul><li>| |-- Makefile </li></ul><ul><li>| `-- adp-ag101p.c </li></ul><ul><li>`-- adp-ag102 </li></ul><ul><li>|-- Makefile </li></ul><ul><li>`-- adp-ag102.c </li></ul><ul><li>board/${vendor} </li></ul><ul><ul><li>${board name} </li></ul></ul><ul><ul><ul><li>C files. </li></ul></ul></ul><ul><ul><ul><ul><li>On chip or on board peripheral setup. </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Board (product model) specific peripheral setup. </li></ul></ul></ul></ul><ul><li>adp-ag101.c: </li></ul><ul><li>int board_init(void) </li></ul><ul><li>{ </li></ul><ul><li>... </li></ul><ul><li>gd->bd->bi_arch_number = MACH_TYPE_ADPAG101 ; </li></ul><ul><li>gd->bd->bi_boot_params = PHYS_SDRAM_0 + 0x400; </li></ul><ul><li>ftsmc020_init(); /* initialize Flash */ </li></ul><ul><li>return 0; </li></ul><ul><li>} </li></ul><ul><li>int board_eth_init(bd_t *bd) </li></ul><ul><li>{ </li></ul><ul><li>return ftmac100_initialize(bd); </li></ul><ul><li>} </li></ul>Setup MACH_TYPE Setup On-chip or Onboard Ethernet Setup On-chip flash controller
  19. 19. Board specific files. <ul><li>board/AndesTech/ </li></ul><ul><li>|-- adp-ag101 </li></ul><ul><li>| |-- Makefile </li></ul><ul><li>| `-- adp-ag101.c </li></ul><ul><li>|-- adp-ag101p </li></ul><ul><li>| |-- Makefile </li></ul><ul><li>| `-- adp-ag101p.c </li></ul><ul><li>`-- adp-ag102 </li></ul><ul><li>|-- Makefile </li></ul><ul><li>`-- adp-ag102.c </li></ul><ul><li>Board_init() will be called by “arch/nds32/lib/board.c”. </li></ul><ul><ul><li>Dram size configuration. </li></ul></ul><ul><ul><li>Flash initialization. </li></ul></ul><ul><ul><li>etc. </li></ul></ul><ul><li>arch/nds32/lib/board.c: </li></ul><ul><li>void board_init_r(gd_t *id, ulong dest_addr) </li></ul><ul><li>{ </li></ul><ul><li>... </li></ul><ul><li>extern void malloc_bin_reloc(void); </li></ul><ul><li>gd = id; </li></ul><ul><li>bd = gd->bd; </li></ul><ul><li>gd->flags |= GD_FLG_RELOC; /* tell others: relocation done */ </li></ul><ul><li>monitor_flash_len = &_end - &_start; </li></ul><ul><li>debug(&quot;monitor flash len: %08lXn&quot;, monitor_flash_len); </li></ul><ul><li>board_init() ; /* Setup chipselects */ </li></ul>Start board setup in adp-ag101.c
  20. 20. Configuration files. <ul><li>include/configs </li></ul><ul><li>|-- adp-ag101.h </li></ul><ul><li>|-- adp-ag101p.h </li></ul><ul><li>`-- adp-ag102.h </li></ul><ul><li>adp-ag101.h: </li></ul><ul><li>#include <asm/arch/ag101.h> </li></ul><ul><li>/* </li></ul><ul><li>* CPU and Board Configuration Options </li></ul><ul><li>*/ </li></ul><ul><li>#define CONFIG_ADP_AG101 </li></ul><ul><li>#define CONFIG_USE_INTERRUPT </li></ul><ul><li>#define CONFIG_SKIP_LOWLEVEL_INIT </li></ul><ul><li>#ifndef CONFIG_SKIP_LOWLEVEL_INIT </li></ul><ul><li>#define CONFIG_MEM_REMAP </li></ul><ul><li>#endif </li></ul><ul><li>... </li></ul><ul><li>#ifdef CONFIG_FTSMC020 </li></ul><ul><li>#include < faraday/ftsmc020.h > </li></ul><ul><li>... </li></ul><ul><li>/* SD (MMC) controller */ </li></ul><ul><li>#define CONFIG_MMC </li></ul><ul><li>#define CONFIG_CMD_MMC </li></ul><ul><li>#define CONFIG_GENERIC_MMC </li></ul><ul><li>#define CONFIG_DOS_PARTITION </li></ul><ul><li>#define CONFIG_FTSDC010 </li></ul><ul><li>#define CONFIG_FTSDC010_NUMBER 1 </li></ul><ul><li>#define CONFIG_CMD_FAT </li></ul><ul><li>... </li></ul><ul><li>/* Command line configuration. */ </li></ul><ul><li>#include < config_cmd_default.h > </li></ul><ul><li>#define CONFIG_CMD_DATE </li></ul><ul><li>#define CONFIG_CMD_PING </li></ul><ul><li>... </li></ul><ul><li>#define CONFIG_STACKSIZE (128 * 1024) </li></ul><ul><li>... </li></ul><ul><li>#define CONFIG_SYS_HZ 1000 </li></ul><ul><li>#define CONFIG_SYS_CLK_FREQ 48000000 </li></ul><ul><li>#define VERSION_CLOCK CONFIG_SYS_CLK_FREQ </li></ul>Enable or disable lowlevel_init Enable or disable memory remap Include driver functions called by adp-ag101.c Include middleware stack Enable user commands Include driver for this middleware. Enable common user commands This must be 1000 System reference clock
  21. 21. Device driver related parts <ul><li>drivers/net </li></ul><ul><li>|-- ftgmac100.c </li></ul><ul><li>|-- ftgmac100.h </li></ul><ul><li>|-- ftmac100.c </li></ul><ul><li>`-- ftmac100.h </li></ul><ul><li>ftgmac100.h: </li></ul><ul><li>/* The registers offset table of ftgmac100 */ </li></ul><ul><li>struct ftgmac100 { </li></ul><ul><li>unsigned int isr; /* 0x00 */ </li></ul><ul><li>unsigned int ier; /* 0x04 */ </li></ul><ul><li>unsigned int mac_madr; /* 0x08 */ </li></ul><ul><li>unsigned int mac_ladr; /* 0x0c */ </li></ul><ul><li>... </li></ul><ul><li>} </li></ul><ul><li>... </li></ul><ul><li>/* </li></ul><ul><li>* Interrupt timer control register </li></ul><ul><li>*/ </li></ul><ul><li>#define FTGMAC100_ITC_RXINT_CNT(x) (((x) & 0xf) << 0) </li></ul><ul><li>#define FTGMAC100_ITC_RXINT_THR(x) (((x) & 0x7) << 4) </li></ul><ul><li>#define FTGMAC100_ITC_RXINT_TIME_SEL (1 << 7) </li></ul><ul><li>ftgmac100.c: </li></ul><ul><li>struct ftgmac100_data { </li></ul><ul><li>struct ftgmac100_txdes txdes[PKTBUFSTX]; </li></ul><ul><li>struct ftgmac100_rxdes rxdes[PKTBUFSRX]; </li></ul><ul><li>int tx_index; </li></ul><ul><li>int rx_index; </li></ul><ul><li>int phy_addr; </li></ul><ul><li>}; </li></ul><ul><li>int ftgmac100_initialize(bd_t *bd) </li></ul><ul><li>{ </li></ul><ul><li>struct eth_device *dev; </li></ul><ul><li>struct ftgmac100_data *priv; </li></ul><ul><li>dev = malloc(sizeof *dev); </li></ul><ul><li>memset(dev, 0, sizeof(*dev)); </li></ul><ul><li>memset(priv, 0, sizeof(*priv)); </li></ul><ul><li>sprintf(dev->name, &quot;FTGMAC100&quot;); </li></ul><ul><li>dev->iobase = CONFIG_FTGMAC100_BASE; </li></ul><ul><li>dev->init = ftgmac100_init; </li></ul><ul><li>dev->halt = ftgmac100_halt; </li></ul><ul><li>... </li></ul><ul><li>}; </li></ul><ul><li>static int ftgmac100_recv(struct eth_device *dev) </li></ul><ul><li>{ </li></ul><ul><li>struct ftgmac100_data *priv = dev->priv; </li></ul><ul><li>struct ftgmac100_rxdes *curr_des; </li></ul><ul><li>unsigned short rxlen; </li></ul><ul><li>... </li></ul><ul><li>}; </li></ul>Use structure to maintain address offsets. Use simple format to represent bit fields in registers Private data maintained by driver. Register functions to middleware and API
  22. 22. Device driver related parts <ul><li>drivers/mmc </li></ul><ul><li>`-- ftsdc010_esdhc.c </li></ul><ul><li>include/faraday </li></ul><ul><li>`-- ftsdc010.h </li></ul><ul><li>ftsdc010.h: </li></ul><ul><li>struct ftsdc010_mmc { </li></ul><ul><li>unsigned int cmd; /* 0x00 */ </li></ul><ul><li>... </li></ul><ul><li>} </li></ul><ul><li>struct mmc_host { </li></ul><ul><li>struct ftsdc010_mmc *reg; </li></ul><ul><li>unsigned int version; </li></ul><ul><li>... </li></ul><ul><li>}; </li></ul><ul><li>/* functions */ </li></ul><ul><li>int ftsdc010_mmc_init (int dev_index); </li></ul><ul><li>ftsdc010.c: </li></ul><ul><li>static struct mmc ftsdc010_dev[CONFIG_FTSDC010_NUMBER]; </li></ul><ul><li>static struct mmc_host ftsdc010_host[CONFIG_FTSDC010_NUMBER]; </li></ul><ul><li>static struct ftsdc010_mmc * ftsdc010_get_base_mmc (int dev_index) </li></ul><ul><li>{ </li></ul><ul><li>return (struct ftsdc010_mmc *)CONFIG_FTSDC010_BASE + dev_index; </li></ul><ul><li>} </li></ul><ul><li>int ftsdc010_mmc_init(int dev_index) </li></ul><ul><li>{ </li></ul><ul><li>... </li></ul><ul><li>mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; </li></ul><ul><li>mmc->f_min = CONFIG_SYS_CLK_FREQ / 2 / (2*128); </li></ul><ul><li>mmc->f_max = CONFIG_SYS_CLK_FREQ / 2 / 2; </li></ul><ul><li>ftsdc010_host[dev_index].reg = ftsdc010_get_base_mmc (dev_index); </li></ul><ul><li>... </li></ul><ul><li>} </li></ul>Use function to get hardware base address. DO NOT USE “volatile” to maintain address. Exported function called by other files. ex: adp-ag101.c Use structure to maintain address offsets.
  23. 23. Documents and miscs. <ul><li>doc/ </li></ul><ul><li>|-- README.ARM-SoC </li></ul><ul><li>|-- README.ARM-memory-map </li></ul><ul><li>|-- README.AVR32 </li></ul><ul><li>|-- README.AVR32-port-muxing </li></ul><ul><li>|-- README.JFFS2 </li></ul><ul><li>|-- README.JFFS2_NAND </li></ul><ul><li>|-- README.NDS32 </li></ul><ul><li>|-- README.N1213 </li></ul><ul><li>|-- README.ag101 </li></ul><ul><li>`-- README.ag102 </li></ul><ul><li>README.ag101: </li></ul><ul><li>Andes Technology SoC AG101 </li></ul><ul><li>========================== </li></ul><ul><li>AG101 is the first SoC produced by Andes Technology using N1213 </li></ul><ul><li>… </li></ul><ul><li>Configurations </li></ul><ul><li>============== </li></ul><ul><li>CONFIG_MEM_REMAP: </li></ul><ul><li>Doing memory remap is essential for preparing some non-OS or RTOS applications. </li></ul><ul><li>… </li></ul><ul><li>CONFIG_SKIP_LOWLEVEL_INIT: </li></ul><ul><li>If you want to boot this system from FLASH and bypass e-bios (the other boot loader on ROM). You should undefine CONFIG_SKIP_LOWLEVEL_INIT in &quot;include/configs/adp-ag101.h&quot;. </li></ul><ul><li>… </li></ul><ul><li>Build and boot steps </li></ul><ul><li>==================== </li></ul><ul><li>build: </li></ul><ul><li>1. Prepare the toolchains and make sure the $PATH to toolchains is correct. </li></ul><ul><li>2. Use `make adp-ag101` in u-boot root to build the image. </li></ul><ul><li>burn u-boot to flash: </li></ul><ul><li>1. Make sure the MA17 (J16) is Lo. </li></ul><ul><li>2. Make sure the dip switch SW5 is set to &quot;0101&quot;. </li></ul><ul><li>… </li></ul>
  24. 24. Documents and miscs. <ul><li>boards.cfg </li></ul><ul><li>MAKEALL </li></ul><ul><li>MAINTAINERS </li></ul><ul><li>MAKEALL </li></ul><ul><ul><li>Automatically build all boards belongs to one architecture, CPU core, Vendor, etc. </li></ul></ul><ul><li>Boards.cfg: </li></ul><ul><li># Target ARCH CPU Board name Vendor SoC Options </li></ul><ul><li>########################################################################################################### </li></ul><ul><li>incaip_150MHz mips mips32 incaip - incaip incaip:CPU_CLOCK_RATE=150000000 </li></ul><ul><li>qi_lb60 mips xburst qi_lb60 qi </li></ul><ul><li>adp-ag101 nds32 n1213 adp-ag101 AndesTech ag101 </li></ul><ul><li>adp-ag101p nds32 n1213 adp-ag101p AndesTech ag101 </li></ul><ul><li>nios2-generic nios2 nios2 nios2-generic altera </li></ul><ul><li>... </li></ul><ul><li>MAINTAINERS: </li></ul><ul><li>######################################################################### </li></ul><ul><li># NDS32 Systems: # </li></ul><ul><li># Maintainer Name, Email Address # </li></ul><ul><li># Board CPU # </li></ul><ul><li>######################################################################### </li></ul><ul><li>Macpaul Lin <macpaul@andestech.com> </li></ul><ul><li>ADP-AG101 N1213 (AG101 SoC) </li></ul><ul><li>ADP-AG101P N1213 (AG101P XC5 FPGA) </li></ul>
  25. 25. Commit techniques. <ul><li>In order to maintain your changes easily (based on patch rules and coding styles) we suggest the following method to maintain your branch. </li></ul><ul><ul><li>Create local branch to track upstream. </li></ul></ul><ul><ul><li>Use “git rebase” to maintain your changes, do not use “git merge”. </li></ul></ul><ul><li>Keep in sync with the upstream repository by pulling it. $ git fetch git://git.denx.de/${upstream}.git </li></ul><ul><li>Rebase the master, testing and any &quot;work in progress&quot; branches to the ${upstream}/master remote branch (which always reflect the One Repo to Rule Them All). $ git checkout master $ git rebase ${upstream}/master $ git checkout next $ git rebase master </li></ul><ul><li>References: </li></ul><ul><li>-------------------------------------------------- </li></ul><ul><li>Patch rules: </li></ul><ul><li>http://www.denx.de/wiki/U-Boot/Patches </li></ul><ul><li>U-Boot Design Principles: </li></ul><ul><li>http://www.denx.de/wiki/U-Boot/DesignPrinciples </li></ul><ul><li>Workflow for Custodian git Repositories </li></ul><ul><li>http://www.denx.de/wiki/U-Boot/CustodianGitTrees </li></ul><ul><li>Example: </li></ul><ul><li>$ git clone git://git.denx.de/u-boot.git u-boot.git </li></ul><ul><li>$ cd u-boot.git </li></ul><ul><li>$ git branch working_branch </li></ul><ul><li>$ git checkout working_branch </li></ul><ul><li>... </li></ul><ul><li>$ git commit –s </li></ul><ul><li>... </li></ul><ul><li>(new updates from upstream) </li></ul><ul><li>$ git checkout master </li></ul><ul><li>$ git pull </li></ul><ul><li>$ git checkout working_branch </li></ul><ul><li>$ git rebase master </li></ul><ul><li>(re-apply your changes on the top of upstream) </li></ul>
  26. 26. Commit techniques. <ul><li>General Patch Submission Rules </li></ul><ul><ul><li>Patches should always contain exactly one complete logical change, i. e. </li></ul></ul><ul><ul><ul><li>Changes that contain different, unrelated modifications shall be submitted as separate patches, one patch per changeset. </li></ul></ul></ul><ul><ul><ul><li>If one logical set of modifications affects or creates several files, all these changes shall be submitted in a single patch. </li></ul></ul></ul><ul><ul><ul><li>Commits should be able to do bisect. </li></ul></ul></ul><ul><ul><ul><li>Header files goes with (or before) C files with related functions. </li></ul></ul></ul>master master working_branch working_branch master working_branch master git rebase
  27. 27. Commit techniques. master master working working master working master git rebase master master working master working master working git merge Changes will become difficult to manage on master master working git merge local master
  28. 28. Commit techniques. <ul><li>Patches and commit usually need to be reviewed and revised back and forth. </li></ul><ul><ul><li>Hence using “git merge” to track upstream is not a good idea and leading update problems. </li></ul></ul>working branch merged local master Pull new update usually cause problem. Old patches cannot be applied to new upstream update.
  29. 29. Debug techniques. <ul><li>Because the linking address will be adjusted in general relocation, the compiled elf file cannot be used directly for helping debug work. </li></ul><ul><ul><li>The debug trick is different if u-boot did lowlevel_init or not. </li></ul></ul><ul><ul><li>The following example is for the case we have lowlevel_init and which should be most people will encountered. </li></ul></ul>
  30. 30. Debug techniques. <ul><li>Build tips: </li></ul><ul><li>Remove old objects ---------------------> </li></ul><ul><li>Cleanup dependencies (header includes) -> </li></ul><ul><li>Build target and redirect output -------> </li></ul><ul><li>Rename output to avoid debugging problem on multiple boards. -------------> </li></ul><ul><li>make clean && </li></ul><ul><li>find ./ | grep depend | xargs rm && </li></ul><ul><li>make adp-ag101p 2>&1 > make.log && </li></ul><ul><li>mv u-boot.bin ubag101p.bin </li></ul><ul><li>Debug tips: </li></ul><ul><li>Add DEBUG to configuration file to inspect stack and relocation address. </li></ul><ul><li>include/configs/adp-ag101p.h: </li></ul><ul><li>#define DEBUG </li></ul><ul><li>monitor len: 00059958 </li></ul><ul><li>ramsize: 04000000 </li></ul><ul><li>TLB table at: 03ff0000 </li></ul><ul><li>Top of RAM usable for U-Boot at: 03ff0000 </li></ul><ul><li>Reserving 358k for U-Boot at: 03f96000 </li></ul><ul><li>Reserving 520k for malloc() at: 03f14000 </li></ul><ul><li>Reserving 64 Bytes for Board Info at: 03f13fc0 </li></ul><ul><li>Reserving 96 Bytes for Global Data at: 03f13f60 </li></ul><ul><li>New Stack Pointer is: 03f13f50 </li></ul><ul><li>RAM Configuration: </li></ul><ul><li>Bank #0: 00000000 64 MiB </li></ul><ul><li>relocation Offset is: 00d96000 </li></ul><ul><li>monitor flash len: 0000956D </li></ul><ul><li>Now running in RAM - U-Boot at: 03f96000 </li></ul>
  31. 31. Debug techniques. <ul><li>Debug early board setup after general relocation. </li></ul><ul><ul><li>You must set a break point after the general relocation has been finished. </li></ul></ul><ul><ul><li>Then re-align the symbol-file “u-boot” to the destination address which binary will be relocated to. </li></ul></ul><ul><ul><li>Use gdb script to help you complete the redundant binary transmission work. </li></ul></ul><ul><li>gdb_script.sh: </li></ul><ul><li>#!/bin/sh </li></ul><ul><li>nds32le-linux-gdb u-boot --command=gdb_script.txt </li></ul><ul><li>gdb_script.txt: </li></ul><ul><li>target remote ${ip}:${port} </li></ul><ul><li>load </li></ul><ul><li>set symbol-reloading </li></ul><ul><li># break before board_init_r </li></ul><ul><li>b start.S:269 </li></ul><ul><li>c </li></ul><ul><li>... </li></ul><ul><li>Manual operation command after the 1st breakpoint: </li></ul><ul><li>symbol-file </li></ul><ul><li># align the symbol-file to the address after relocation </li></ul><ul><li>add-symbol-file u-boot ${addr} </li></ul><ul><li># set break at board_init_r(), you can do single step, too. </li></ul><ul><li>b board.c:302 </li></ul>DRAM FLASH/ROM U-boot U-boot relo U-boot lowlevel_init with remap U-boot elf U-boot elf add-symbol-file
  32. 32. Summary <ul><li>The following principle is important for porting u-boot and Linux. </li></ul><ul><ul><li>Understand the configuration usage and use generic function to avoid incorrect integration. </li></ul></ul><ul><ul><li>Understand the generic software API first and co-design the hardware behavior in earlier stage to avoid breaking the design of the software framework. </li></ul></ul><ul><li>Maintain your patches into different parts, like drivers, SoC, and configurations to make the patches could be easily fixed. </li></ul><ul><ul><li>Maintain your patches into orders and reasonable. </li></ul></ul>

×