= Beagleboard = {{Infobox BSP |BSP_name = BeagleBoard |Manufacturer = Texas Instruments |image = Beagle Board big.jpg |caption = BeagleBoard rev.B |Board_URL = http:/beagleboard.org |Architecture = ARM |CPU_model = Cortex-A8 |Monitor = uBoot |Simulator = Yes. [wiki:TBR/UserManual/QEMU QEMU] |Aliases = None |RAM = 256 MB LPDDR RAM |NVMEM = 256 MB NAND Flash memory |Serial = TBD |Video = S-Video, DVI |NICs = TBD |Other = TBD }} = Overview = This page documents the currently un-mainline support for the original Beagleboard. For an overview of it and related targets, see: http://en.wikipedia.org/wiki/BeagleBoard = Board Setup = None = Downloading and Executing = = 1. Clone and build qemu-maemo: = $ git clone git://gitorious.org/qemu-maemo/qemu.git $ cd qemu $ ./configure --target-list="arm-softmmu" $ make [http://meego.gitorious.org/qemu-maemo] = 2. Clone and build rtems from my fork: = $ git clone git://github.com/claas/rtems.git (ben's fork contains a branch that is uptodate w.r.t rtems mainline, has working clock and timers, and has beaglebone support, but is in flux - https://github.com/bengras/rtems.git , beaglebone-wip branch) $ mkdir rtems-b $ cd rtems $ ./bootstrap $ cd ../rtems-b $ ../rtems/configure --target=arm-rtems4.11 --enable-rtemsbsp=beagle $ make $ make install (these instructions previously mentioned the now-obsolete arm-rtemseabi4.11 target: --target=arm-rtemseabi4.11. these instructions also previously mentioned to disable posix, networking, cxx, and enable rtems debug, and specify a prefix, but the default also builds.) = 3. Clone my tools repository: = $ git clone git://github.com/claas/tools.git find the test.c file in the cloned repository and copy it to the examples hello/hello_world_c folder = 5. Download the x-loader and uboot images = $ wget http://qemu-omap3.googlecode.com/files/image-v0.01.tar.bz2 = 6. Build the nand flash image = The original beagleboard has 256MB builtin flash NAND. We make a full image for that flash and feed it to the emulator to boot from. The script to do that is in the tools repo, the name is: build-nand.sh For this, you will also need: * bb_nandflash.sh and bb_nandflash_ecc from e.g. http://beagleboard.lohray.com/vm-larix/setting-up-an-emulator/qemu-emulation * uboot mkimage, from e.g. uboot-mkimage package (apt-get install uboot-mkimage on ubuntu) * some minor modifications to the build-nand.sh script, like setting the path to the tools and files properly Invocation: $ build-nand.sh e.g. with my layout: $ sh tools/build-nand.sh rtems-b/arm-rtems4.11/c/beagle/testsuites/samples/hello/hello nand Then to invoke qemu: $ qemu-system-arm -M beagle -mtdblock nand -serial stdio Once you are in the boot prompt, load and run the program: OMAP3 beagleboard.org # nand read 0x80800000 0x280000 0x400000 NAND read: device 0 offset 0x280000, size 0x400000 4194304 bytes read: OK OMAP3 beagleboard.org # bootm 0x80800000 ## Booting kernel from Legacy Image at 80800000 ... Image Name: RTEMS Image Type: ARM RTEMS Kernel Image (gzip compressed) Data Size: 56484 Bytes = 55.2 kB Load Address: 80000000 Entry Point: 80000000 Verifying Checksum ... OK Uncompressing Kernel Image ... OK ## Transferring control to RTEMS (at address 80000000) ... bsp_interrupt_facility_initializebeagle_set_exception_handler *** BEGIN OF TEST HELLO WORLD *** Hello World *** END OF TEST HELLO WORLD *** = Debugging = How do you debug code on this board? What gdb setup? BDM, stub, etc? = Beagleboard XM, Linaro qemu = Using a different emulator (fork), and running a different u-boot, emulating a beagleboard xm, this hello world also works on the bbxm. The bbxm has no internal NAND so booting is a bit different, the mmc card is needed. the image referenced contains a FAT partition that contains hello.img: $ qemu-system-arm -M beaglexm -drive if=sd,cache=writeback,file=rtems_arm_sd.img -clock unix -serial stdio booting then looks like: OMAP3 beagleboard.org # fatload mmc 0:1 0x80800000 hello.img reading hello.img 56548 bytes read in 12 ms (4.5 MiB/s) OMAP3 beagleboard.org # bootm 0x80800000 ## Booting kernel from Legacy Image at 80800000 ... Image Name: RTEMS Image Type: ARM RTEMS Kernel Image (gzip compressed) Data Size: 56484 Bytes = 55.2 KiB Load Address: 80000000 Entry Point: 80000000 Verifying Checksum ... OK Uncompressing Kernel Image ... OK ## Transferring control to RTEMS (at address 80000000) ... bsp_interrupt_facility_initializebeagle_set_exception_handler *** BEGIN OF TEST HELLO WORLD *** Hello World *** END OF TEST HELLO WORLD *** This means that bbxm support should not be too far off. = References = * TBD = Ben and Chris's Big Beagleboard Adventure = The following are some notes about Ben and Chris's project to get full support for Beagleboards into the RTEMS kernel source. The plan is support all Beagleboards from the xM to the Black and White with JTAG debugging if possible. = GIT Repo = Ben has a WIP git repo. Use at your own risk. https://github.com/bengras/rtems/tree/beaglebone-wip If you want to track the RTEMS master repo and Ben's WIP branch try the following: $ git clone git://git.rtems.org/data/rtems.git Cloning into 'rtems'... remote: Counting objects: 449200, done. remote: Compressing objects: 100% (82131/82131), done. remote: Total 449200 (delta 364296), reused 442014 (delta 357735) Receiving objects: 100% (449200/449200), 61.24 MiB | 490.00 KiB/s, done. Resolving deltas: 100% (364296/364296), done. Checking connectivity... done. Checking out files: 100% (9947/9947), done. $ cd rtems $ git remote add ben https://github.com/bengras/rtems.git $ git fetch ben remote: Counting objects: 434, done. remote: Compressing objects: 100% (201/201), done. remote: Total 434 (delta 259), reused 334 (delta 210) Receiving objects: 100% (434/434), 125.08 KiB | 137.00 KiB/s, done. Resolving deltas: 100% (259/259), done. From https://github.com/bengras/rtems * [new branch] beaglebone-wip -> ben/beaglebone-wip * [new branch] master -> ben/master $ git branch --track beaglebone-wip ben/beaglebone-wip Branch beaglebone-wip set up to track remote branch beaglebone-wip from ben. $ git checkout beaglebone-wip Switched to branch 'beaglebone-wip' To update the branch to the current master fetch the origin then: $ git checkout beaglebone-wip Switched to branch 'beaglebone-wip' $ git rebase master First, rewinding head to replay your work on top of it... Applying: Added BeagleBoard BSP Applying: Basic BSP for BeagleBoard and Beaglebones Applying: testing Applying: nothing .... = Debugging = Using the xM and JTAG I cannot get Ben's build to work. The problem is no UART set up because it is not set up by the time JTAG is given control. From reading the TRM and by playing around it seems some code is being loaded off the SD card and that is setting up DRAM plus other things however the UART is not setup. If the SD card is removed the code sits in the ROM code. As a result we need a boot monitor of some form to get things working until supporting initialisation code is added to RTEMS we decide to settle on U-Boot as the initialisation code. = JTAG = I use a Flyswatter2 from Rusty at Tincan Tools (http://www.tincantools.com/JTAG/Flyswatter2.html). You can also buy an adaptor board for the xM that makes connecting simple. The software is OpenOCD (http://openocd.sourceforge.net/). I build from git with a range of unrelated patches for SMP support on the Zynq. The git repo is http://sourceforge.net/p/openocd/code/ci/master/tree/. I use a special prefix by configuring with the --prefix option to configure. To run OpenOCD: $ curl http://www.rtems.org/ftp/pub/rtems/people/chrisj/beagle/bbxm.cfg > bbxm.cfg $ ~/development/openocd/git/bin/openocd -f bbxm.cfg -c "reset" Open On-Chip Debugger 0.8.0-dev-00014-gd3d0bf2-dirty (2013-07-21-15:32) Licensed under GNU GPL v2 For bug reports, read http://openocd.sourceforge.net/doc/doxygen/bugs.html Info : only one transport option; autoselect 'jtag' adapter speed: 10 kHz Warn : dm37x.dsp: huge IR length 38 trst_only separate trst_push_pull Info : clock speed 10 kHz Info : TAP dm37x.jrc does not have IDCODE Warn : JTAG tap: dm37x.jrc UNEXPECTED: 0x00000000 (mfg: 0x000, part: 0x0000, ver: 0x0) Error: JTAG tap: dm37x.jrc expected 1 of 3: 0x2b89102f (mfg: 0x017, part: 0xb891, ver: 0x2) Error: JTAG tap: dm37x.jrc expected 2 of 3: 0x1b89102f (mfg: 0x017, part: 0xb891, ver: 0x1) Error: JTAG tap: dm37x.jrc expected 3 of 3: 0x0b89102f (mfg: 0x017, part: 0xb891, ver: 0x0) Error: Trying to use configured scan chain anyway... Warn : Bypassing JTAG setup events due to errors adapter speed: 1000 kHz Warn : dm37x.cpu: ran after reset and before halt ... dm37x.cpu: target state: halted dm37x.cpu: target halted in Thumb state due to debug-request, current mode: Supervisor dm37x.cpu: cpsr: 0x000001f3 pc: 0x00015dec dm37x.cpu: MMU: disabled, D-Cache: disabled, I-Cache: enabled The file http://www.rtems.org/ftp/pub/rtems/people/chrisj/beagle/bbxm.cfg contains initialisation sequence needed to get the board set up so code can be downloaded into RAM. The sequence is from the cunnig capture Ben did with qemu. = Building U-Boot = To build U-Boot: $ git clone git://git.denx.de/u-boot.git $ cd u-boot $ git checkout --track -b omap3 origin/master $ export PATH=$HOME/development/rtems/4.11/bin:$PATH $ gmake CROSS_COMPILE=arm-rtems4.11- mrproper $ gmake CROSS_COMPILE=arm-rtems4.11- omap3_beagle_config $ gmake CROSS_COMPILE=arm-rtems4.11- Note: I use FreeBSD so gmake is required. U-Boot can be run via JTAG. Start OpenOCD and then run: $ arm-rtems4.11-gdb u-boot GNU gdb (GDB) 7.6.2 Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=x86_64-freebsd10.0 --target=arm-rtems4.11". For bug reporting instructions, please see: ... Reading symbols from /usr/home/chris/development/rtems/bb/uboot/u-boot/u-boot...done. (gdb) target remote :3333 Remote debugging using :3333 0x00018354 in ?? () (gdb) mon reset halt adapter speed: 10 kHz JTAG tap: dm37x.jrc tap/device found: 0x2b89102f (mfg: 0x017, part: 0xb891, ver: 0x2) JTAG tap: dm37x.dap enabled adapter speed: 1000 kHz dm37x.cpu: ran after reset and before halt ... dm37x.cpu: target state: halted dm37x.cpu: target halted in Thumb state due to debug-request, current mode: Supervisor dm37x.cpu: cpsr: 0x000001f3 pc: 0x00015dec dm37x.cpu: MMU: disabled, D-Cache: disabled, I-Cache: enabled (gdb) mon beagleboard_xm_init (gdb) load Loading section .text, size 0x3af04 lma 0x80100000 Loading section .rodata, size 0xd534 lma 0x8013af08 Loading section .hash, size 0x2c lma 0x8014843c Loading section .data, size 0x5462 lma 0x80148468 Loading section .got.plt, size 0xc lma 0x8014d8cc Loading section .u_boot_list, size 0x840 lma 0x8014d8d8 Loading section .rel.dyn, size 0x7cf8 lma 0x8014e118 Loading section .dynsym, size 0x60 lma 0x80155e10 Loading section .dynstr, size 0x2a lma 0x80155e70 Loading section .dynamic, size 0x80 lma 0x80155e9c Loading section .interp, size 0x11 lma 0x80155f1c Start address 0x80100000, load size 352037 Transfer rate: 16 KB/sec, 11734 bytes/write. (gdb) display /i $pc 1: x/i $pc => 0x80100000 <_start>: b 0x80100044 (gdb) si stepi ignored. GDB will now fetch the register state from the target. Program received signal SIGINT, Interrupt. _start () at arch/arm/cpu/armv7/start.S:23 23 _start: b reset 1: x/i $pc => 0x80100000 <_start>: b 0x80100044 (gdb) reset () at arch/arm/cpu/armv7/start.S:95 95 bl save_boot_params 1: x/i $pc => 0x80100044 : bl 0x8010009c (gdb) c On the console serial port with a baudrate of 115200 I see: U-Boot 2014.04 (Apr 16 2014 - 13:16:21) OMAP36XX/37XX-GP ES1.2, CPU-OPP2, L3-200MHz, Max CPU Clock 1 Ghz OMAP3 Beagle board + LPDDR/NAND I2C: ready DRAM: 512 MiB NAND: 0 MiB MMC: OMAP SD/MMC: 0 *** Warning - readenv() failed, using default environment In: serial Out: serial Err: serial Beagle xM Rev C No EEPROM on expansion board Die ID #402c00029ff8000001683b050a01c00e Net: usb_ether Hit any key to stop autoboot: 0 OMAP3 beagleboard.org # = Initializing the SOC without bootcode = Booting is quite touchy, as there are quite some dependencies on even just getting the RAM and UART to work. In other words everything has to line up right before *anything* happens (easily) so it'll be tricky to bootstrap. The on-SOC ROM code does basic initialization, and searches for MLO code to get this initialization done. It can come from an SD card if it has an MBR and has a fat-formatted first partition (or other sources like UART). It is loaded into 128k of on-SOC RAM that is usable to do further initialization. One possible source of such MLO code is the so-called SPL build of U-Boot. It is just meant to be a small U-Boot that does initialization of the hardware, limited to 128kb, and then load the bigger U-Boot from MMC. The question is how to load RTEMS binaries without the help of an SD card. A very convenient and powerful setup is jtag, openocd and gdb, as Chris mentions above. However we want the target to be in a completely 'neutral' state, i.e. not be dependent on a particular loaded SD card with MLO on it. To accomplish this, one way is to initialize the SOC from JTAG (using openocd or gdb) so that after that the RAM is available, the uart clock is on, etc., and we can load and run RTEMS binaries. A clean solution would be, as happens for some other targets in openocd, to have an initialization sequence in the target config. I thought an 'easy' way to get started on finding a nice clean list of a minimal initialization sequence would be to record what U-Boot MLO does. Then perhaps decode all the addresses and find which ones are and aren't important to minimize the list. This is quite hard to do from within U-Boot itself because it takes quite along time, in short, before data works as you'd expect in a C program. However booting an SD-card with MLO and U-Boot on it from a qemu does let me record the i/o operations it does. I added this code to qemu: index aab4a31..2c357d1 100644 --- a/memory.c +++ b/memory.c @@ -900,6 +900,18 @@ static uint64_t memory_region_dispatch_read(MemoryRegion *mr, unsigned size) { uint64_t ret; + uint32_t addroffset = addr, addrbase = mr->addr; + + if(size == 4) { + fprintf(stderr, "mdw 0x%08lx ;# %s\n", + addroffset + addrbase, mr->name); + } else if(size == 2) { + fprintf(stderr, "mdh 0x%08lx ;# %s\n", + addroffset + addrbase, mr->name); + } else if(size == 1) { + fprintf(stderr, "mdb 0x%08lx ;# %s\n", + addroffset + addrbase, mr->name); + } else fprintf(stderr, "size %d??\n", size); ret = memory_region_dispatch_read1(mr, addr, size); adjust_endianness(mr, &ret, size); @@ -911,10 +923,23 @@ static void memory_region_dispatch_write(MemoryRegion *mr, uint64_t data, unsigned size) { + uint32_t addroffset = addr, addrbase = mr->addr; + if (!memory_region_access_valid(mr, addr, size, true)) { return; /* FIXME: better signalling */ } + if(size == 4) { + fprintf(stderr, "mww 0x%08lx 0x%08lx ;# %s\n", + addroffset + addrbase, (uint32_t) data, mr->name); + } else if(size == 2) { + fprintf(stderr, "mwh 0x%08lx 0x%08lx ;# %s\n", + addroffset + addrbase, (uint32_t) data, mr->name); + } else if(size == 1) { + fprintf(stderr, "mwb 0x%08lx 0x%08lx ;# %s\n", + addroffset + addrbase, (uint32_t) data, mr->name); + } else fprintf(stderr, "size %d??\n", size); + adjust_endianness(mr, &data, size); if (!mr->ops->write) { and put the resulting commands in the reset-init hook of the openocd target config. I included the reads just in case the HW behaviour is affected by it. The list is unnecessarily long but I haven't bothered trimming it yet before I see it actually working. This gets very far in initializing the device. I can load an .exe now from gdb and the disassembly looks okay so I assume the RAM writing is working. But it has an exception on the first instruction. I haven't figured out why. I have seen hello.exe execute properly once so I'm sure it's close. Don't be confused by the u-boot banner being printed! This is a result of the u-boot spl (mlo) trace being executed very faithfully. After minimizing it should be a very small list if the other openocd configs are any indication. = RTEMS Tester = I've added a config file for the bbxm to the RTEMS Tester that interfaces with gdb and openocd to load and run test executables. The repo is here: https://github.com/bengras/rtems-tools/tree/bbxm-wip Currently the tests work 'most of the time' but not most of the time enough, see test reports. = Test Reports = These are done with the RTEMS tester, with the bbxm.cfg from the RTEMS tree (commit indicated) and the gdbinit file from the RTEMS tester tree (commit indicated). {{Test Report |Version = RTEMS 3057e8b, Tester 19b8d4cd |Date = 23 apr 2014 |User = [wiki:User:Beng User:Beng] |Report = Passed: 422 Failed: 20 Timeouts: 36 Invalid: 14; 1 spurious interrupt; the Timeouts are due to the JTAG load & run failing; no noise on reset, no nothing. }} {{Test Report |Version = RTEMS 3057e8b but with original bbxm.cfg, Tester 19b8d4cd |Date = 23 apr 2014 |User = [wiki:User:Beng User:Beng] |Report = Passed: 390 Failed: 20 Timeouts: 68 Invalid: 14; more spurious interrupts }} {{Test Report |Version = RTEMS f7b72ac, Tester 19b8d4cd |Date = 24 apr 2014 |User = [wiki:User:Beng User:Beng] |Report = Passed: 447 Failed: 23 Timeouts: 8 Invalid: 14 Total: 492; code always runs! }} (rebase) {{Test Report |Version = RTEMS b74176050, Tester e48631889 |Date = 26 apr 2014 |User = [wiki:User:Beng User:Beng] |Report = Passed: 475 Failed: 7 Timeouts: 10 Invalid: 0 }} {{Navbox_BSPs}}