Archive for June, 2012

Problem running U-Boot on QEMU for versatilepb (ARM729EJ-S) ?

Posted in Arm stuffs with tags , , , , , , , , on June 18, 2012 by UnixmanLinuxboy

Qemu is a good emulator to try out and understand system programming without a real hardware.
Versatilepb (arm926ej-s) is supported quite well by Qemu and this article describes to overcome a nasty U-Boot error which I encountered when compiling u-boot for versatilepb.

U-boot version used: u-boot-2012.04.tar.bz2

Compiled using:

make versatilepb_config ARCH=arm CROSS_COMPILE=arm-none-eabi-
make all ARM=arm CROSS_COMPILE=arm-none-eabi-

Running u-boot with QEMU:
qemu-system-arm -M versatilepb -m 128M -nographic -kernel ./u-boot.bin

And I am greeted with this:


qemu: fatal: Trying to execute code outside RAM or ROM at 0xffff07bc

R00=fffcbf64 R01=ffff0000 R02=00000000 R03=0101c08c
R04=ffff0000 R05=fffcbf64 R06=ffff0000 R07=00000000
R08=008fff78 R09=feff0000 R10=0101c08c R11=00000000
R12=fffcbfdc R13=fffcbf58 R14=ffff07bc R15=ffff07bc
PSR=600001d3 -ZC- A svc32
Aborted

Or

U-Boot 2012.04 (Jun 18 2012 - 17:54:11)

DRAM: 128 MiB
WARNING: Caches not enabled
Flash: ## Unknown flash on Bank 1 - Size = 0x00000000 = 0 MB
*** failed ***
### ERROR ### Please RESET the board ###
QEMU: Terminated

How to avoid this nasty error you ask?

Answer: Patch include/configs/versatile.h
Add this line

#define CONFIG_ARCH_VERSATILE_QEMU

just below

#ifndef __CONFIG_H
#define __CONFIG_H

Recompile and voila!!

Here is the output


U-Boot 2012.04 (Jun 18 2012 - 18:14:08)

DRAM: 128 MiB
WARNING: Caches not enabled
Using default environment

In: serial
Out: serial
Err: serial
Net: SMC91111-0
VersatilePB # help
? - alias for 'help'
base - print or set address offset
bdinfo - print Board Info structure
bootm - boot application image from memory
bootp - boot image via network using BOOTP/TFTP protocol
cmp - memory compare
cp - memory copy
crc32 - checksum calculation
dhcp - boot image via network using DHCP/TFTP protocol
env - environment handling commands
erase - erase FLASH memory
flinfo - print FLASH memory information
go - start application at address 'addr'
help - print command description/usage
iminfo - print header information for application image
loop - infinite loop on address range
md - memory display
mm - memory modify (auto-incrementing address)
mtest - simple RAM read/write test
mw - memory write (fill)
nm - memory modify (constant address)
ping - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
protect - enable or disable FLASH write protection
reset - Perform RESET of the CPU
setenv - set environment variables
tftpboot- boot image via network using TFTP protocol
version - print monitor, compiler and linker version
VersatilePB #

Advertisements

A simple “bare-metal” program (ARM)

Posted in Arm stuffs with tags , , , , , , , , , , , , , , on June 16, 2012 by UnixmanLinuxboy

Caution: Here be dragons!
For those who feel like writing C code with nice and fancy algorithm, this is not for you. This is for them who wants to dig deeper at the core to see how things run and work.
A “bare-metal” program is simplest of all which does not need special services from underlying OS. It is capable enough to run on its own.

Without much ado, lets get it on, shall we?

This tutorial can be used on both real hardware and an emulator. I have used QEMU for this purpose.

Architecture to emulate: ARM926EJ-S
This is well supported by QEMU and has four UART
serial ports. The first serial port (UART0) works
as a terminal when we will use '-nographic' or
'-serial stdio' option in QMEU

Goal: This program will run inside QEMU emulator and will pass few characters to the UART0 which will, then be redirected by QEMU to the standard console.
Note: On real board (ARM926EJ-S) you have to connect to serial port (Minicom).

Required:
QEMU, ARM toolchain, little patience and willingness to learn.

Install QEMU on ubuntu:
sudo apt-get install qemu qemu-kvm-extras

Get ARM toolchain from:
ARM toolchain download link

Note: Do not download the installer (it sucks!)
Instead, get the .tar.gz archieve and unpack it your working directory
and set your PATH accordingly.
If you’re using login shell, modify the .bash_profile,
else modify .bashrc.
————————————————————————–

No interrupt handling and other fancy stuffs.

The code is well-explained and do contact me if you need more information.

The command to run the final binary in QEMU is:
qemu-system-arm -M versatilepb -m 128M -nographic -kernel output.bin

"-M versatilepb" specifies the machine type: Here we are using ARM9 versatile board.
"-nographic" mode tells to redirect UART0 messages to console.

Note: Without the option "-m 128M" QEMU crashes badly. A bug has been already filed regarding this.

Here we go!!!

File: simple-startup.s


/* ===========================================
Start up routines for bare-metal program
===========================================
*/

.global _Reset
_Reset:
B Reset_Handler /* Reset handler */
B Undefined /* Undefined mode handler */
B SWI /* Software interrupt */
B Prfetch_Abort /* Prefetch abort handler */
B Data_Abort /* Data abort handler */
B IRQ_Handler /* IRQ handler */
B FIQ_Handler /* FIQ handler */

Reset_Handler:
LDR sp, =stack_top /*set up env for C function */
BL simple_init
B .
Undefined: /* do nothing */
B .
SWI: /* do nothing */
B .
Prfetch_Abort: /* do nothing */
B .
Data_Abort: /* do nothing */
B .
IRQ_Handler: /* do nothing */
B .
FIQ_Handler: /* do nothing */
B .

File: simple-init.c


/*******************************************/
/* Simple Bare metal program init */
/*******************************************/

/* Note: QEMU model of PL011 serial port ignores the transmit
FIFO capabilities. When writing on a real SOC, the
"Transmit FIFO Full" flag must be checked in UARTFR register
before writing on the UART register*/

volatile unsigned int* const UART0 = (unsigned int*)0x0101F1000;

static void uart_print(const char *s)
{
while(*s != '') {
*UART0 = (unsigned int)(*s); /* send to UART */
s++;
}
}

/* Main entry point */
void simple_init()
{
uart_print("Welcome to Simple bare-metal program\n");
uart_print("If you're running in QEMU, press Ctrl+a\n");
uart_print("and then x to stop me...\n");
}

File: simple-linker.ld


/* Simple Bare metal program - linker script
*
* Note: This is written for QEMU
* QEMU loads the kernel address at 0x00010000
* The emulator starts at 0x00000000 and peripheral interrupts
* are disabled at startup.
*
* The code must be compiled and linked to be placed at
* 0x00010000
* IRQ handling can be ignored.
*
*/

ENTRY(_Reset)
SECTIONS
{
. = 0x10000;
.startup . : { simple-startup.o(.text) }
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss) }
. = . + 0x1000; /* move by 4kbyte (our stack memory) */
stack_top = .;
}

Build commands:


arm-none-eabi-as -mcpu=arm926ej-s -g simple-startup.s -o simple-startup.o
arm-none-eabi-gcc -c -mcpu=arm926ej-s -g simple-init.c -o simple-init.o
arm-none-eabi-ld -T simple-linker.ld simple-init.o simple-startup.o -o output.elf
arm-none-eabi-objcopy -O binary output.elf output.bin

And here is the output:

sarbojit@Phrozen:~/timepass/assembly-fun$ qemu-system-arm -M versatilepb -m 128M -nographic -kernel output.bin
Welcome to Simple bare-metal program
If you’re running in QEMU, press Ctrl+a
and then x to stop me…
QEMU: Terminated
sarbojit@Phrozen:~/timepass/assembly-fun$

Inspired by:
http://balau82.wordpress.com/2010/02/28/hello-world-for-bare-metal-arm-using-qemu/

A RALink (rt2x00 / rt2800pci) Wifi chipset and does not seem to work? Read on

Posted in Unix/Linux with tags , , , , , , , , , on June 10, 2012 by UnixmanLinuxboy

There can a lot of reason why the wi-fi card don’t seem to work.

In my Lubuntu 12.04 (kernel 3.2.0-24-generic-pae) it never worked with Network Manager. I chucked nm and installed wicd, after some time, it too, refused to connect me to encrypted network.

So I fired up good ol’ (# cat /proc/kmsg) and lo! What do I see ?

phy0 -> rt2x00queue_write_tx_frame: Error – Dropping frame due to full tx queue 0.
phy0 -> rt2x00queue_write_tx_frame: Error – Dropping frame due to full tx queue 0.
phy0 -> rt2x00queue_write_tx_frame: Error – Dropping frame due to full tx queue 1.
phy0 -> rt2x00queue_write_tx_frame: Error – Dropping frame due to full tx queue 1.
phy0 -> rt2x00queue_write_tx_frame: Error – Dropping frame due to full tx queue 1.
phy0 -> rt2x00queue_write_tx_frame: Error – Dropping frame due to full tx queue 1.
phy0 -> rt2x00queue_write_tx_frame: Error – Dropping frame due to full tx queue 1.
phy0 -> rt2x00queue_write_tx_frame: Error – Dropping frame due to full tx queue 1.

Dear friend, if you face similar logs in your kernel, it is time we get into some bug-banging 😉

Let check against the daily builds of compat-wireless drivers. You can get ’em here

http://wireless.kernel.org/download/compat-wireless-2.6/ 

As of today it is compat-wireless-2012-05-10.tar.bz2 updated 2012-Jun-09 22:38:35

Download this in your box and run the following:

./scripts/driver-select rt2x00
make
sudo make install

 

— Now you can reboot your box, or unload your modules and modprobe them.
sudo make unload
sudo modprobe -v rt2800pci

 

Official instructions are here: http://wireless.kernel.org/en/users/Download#Selecting_your_driver