Archive for linux

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

 

“adb devices” shows “??????? no permissions”

Posted in Android with tags , , , , , , , on February 24, 2011 by UnixmanLinuxboy

Environment: Ubuntu 10.04
adb 1.0.26

Problem:
$adb devices
??????????? no permissions

This is because the udev is unable to determine the permissions for this USB device.
The udev is the program that the OS uses to dynamically control the devices. As soon as a device is plugged into, udev detects it and creates device files on-the-fly.

The android debug bridge (adb) is a the daemon program that allows you to talk to device. It uses network sockets.

The “no permissions” error is because the daemon is unable to determine the right permissions to access the device as the user that it is running as. Unless the phone device appears in the udev infrastructure with correct permissions to be accessed as the user you are logged in as, it won’t work.

The solution:

1. Plug your android phone to your system.
2. Verify that you can see your phone by using “lsusb”
e.g
===================================
$ lsusb
lsusb
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 003: ID 0461:4d22 Primax Electronics, Ltd
Bus 006 Device 002: ID 413c:2106 Dell Computer Corp.
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 010: ID XXXX:YYYY Samsung Electronics Co., Ltd
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

The line
Bus 002 Device 010: ID XXXX:YYYY Samsung Electronics Co., Ltd
is our phone, rest of the lines can be ignored…

3. The ID XXXX is the Vendor ID of my phone and YYYY is its Device ID. 002 is the BUS number and 010 is the Device number.
Note: These numbers may be different for your phone. So do not panic.

4. Now, type the following command in terminal
$ udevadm info –attribute-walk –name=/dev/bus/usb/002/010

Note: This will provide a lot of output as this command walks up the usb bus. If you have not connected any other device after you connected your phone, it is likely that the first entry would be of your device.
Typical output will be like thilooking at device ‘/devices/pci0000:00/0000:00:1d.7/usb2/2-5’:
KERNEL==”2-5″
SUBSYSTEM==”usb”
DRIVER==”usb”
|
|
|
|
|
|
|
|
ATTR{manufacturer}==”<Your_Phone’s_Manufacturer”
ATTR{product}==”Your_Phone’s_Product_Name”
ATTR{serial}==”Serial_Number”

The serial number here will appear when this all works.

5. Now, lets set udev rules.
Go to /etc/udev/rules.d/ directory and create a new file with name 99-android.rules

Note: In order to perform this activity, you need to be root or use sudo.

6. edit the file you created in step 5 with the following content:

SUBSYSTEM==”usb”, SYSFS{idVendor}==”XXXX”, OWNER=”yourUserName” GROUP=”yourGroupName”, MODE=”666″

7: Save and close it.

8: Reconnect the device and check the permissions…

$ ls -l /dev/bus/usb/bus-number/device-number

Enjoy

Feel free to comment if you find anything that is not working. I will try to help you