EmbLogic's Blog

Precision Time Protocol

The Precision Time Protocol (PTP) is a protocol used to synchronize clocks throughout a computer network. On a local area network, it achieves clock accuracy in the sub-microsecond range, making it suitable for measurement and control systems.[1]

PTP was originally defined in the IEEE 1588-2002 standard, officially entitled “Standard for a Precision Clock Synchronization Protocol for Networked Measurement and Control Systems” and published in 2002. In 2008, IEEE 1588-2008 was released as a revised standard; also known as PTP Version 2, it improves accuracy, precision and robustness but is not backward compatible with the original 2002 version.[2]

“IEEE 1588 is designed to fill a niche not well served by either of the two dominant protocols, NTP and GPS. IEEE 1588 is designed for local systems requiring accuracies beyond those attainable using NTP. It is also designed for applications that cannot bear the cost of a GPS receiver at each node, or for which GPS signals are inaccessible

Posted in Uncategorized | Leave a comment

gcc- tool chain

GCC is a popular tool chain that can generate executables for wide range of architectures including x86, ARM v4/v5/v6/v7, and many others. In personal computers GNU GCC is a compiler that compiles an application written for LINUX X86 PC. When the host and target architectures are different, the tool chain is called ” cross compiler “.
You may come across different tool chains to cross compile your application for ARM like arm-none-linux-gnueabi, arm-none-eabi, arm-eabi, arm-fsl-linux-gnueabi-gcc etc.

Tool chains have a loose name convention like arch [-vendor] [-os] – eabi
arch – refers to target architecture (which in our case is ARM)
vendor – refers to toolchain supplier
os – refers to the target operating system
eabi – refers to Embedded Application Binary Interface

some illustrations as follows :

arm-none-eabi – This tool chain targets for ARM architecture, has no vendor, does not target an operating system and complies with the ARM EABI.
arm-none-linux-gnueabi – This toolchain targets the ARM architecture, has no vendor, creates binaries that run on the Linux operating system, and uses the GNU EABI. It is used to target ARM-based Linux systems.

So, If you built your application “helloworld.c” with arm-none-linux-gnueabi-gcc (or) arm-fsl-linux-gnueabi-gcc, executable will work on your ARM target board as the tool chain has only difference in vendor.

Posted in Uncategorized | Leave a comment

Remote Access to Linux

Our office network contains several Windows computers and one Linux desktop. I recently switched from Windows to Linux for most of my work, and have enjoyed its many advantages. But as I became more dependent on the information and applications stored in that computer, I wondered how I could use that system from other locations. This article describes how I solved that problem and shows how you can set up remote access to Linux computers.

My Linux distribution is SUSE Linux 10.1. Our network consists of a Linksys WRT54GS wireless router, a Linksys WMP54G wireless access card in the Linux computer, a Linksys WRE54G repeater to boost the signal quality, and a Maxtor Shared Storage drive, so all the computers have shared storage. My goals were to access the files on both Linux disks (local hard drive and shared storage) and to run applications on the Linux system from any other computer on the Internet. I accomplished these tasks in three largely independent ways, which you can mix and match to suit your needs:
· Secure Shell (SSH)
· File Transfer Protocol (FTP)
· SUSE Linux VNC-based remote administration feature
As a starting point, I assume that your Linux installation and network are already set up, using components similar to mine. The shared file server is not required, but if you have one, see the sidebar (editor: insert link here) for instructions about mounting this resource.

SSH

SSH is the Secure SHell service. It is similar to telnet, but with more features, and every transaction is encrypted. Using SSH, you are provided a shell nearly identical to one available locally. This provides all of the command line functionality of Linux. Also, curses applications (like YaST) work through SSH. Keep in mind that because the shell is identical to one available locally, you cannot move files between your SSH client’s system and the SSH server system. For file transfer, FTP is required.

To set up SSH, open up the YaST Control Center and use the Software Management module to make sure you have the package openssh installed. Next, enable the SSH server on your system by selecting YaST’s System tab, opening System Services, and ensuring that the service ssh is enabled.

When you want to access this SSH server from a remote computer, use the ssh command in Linux and Mac OS X. Type the following at the remote computer:

ssh

The IP address you use here is either: your company’s static IP address, or the address assigned to your router by your Internet service provider (ISP). If you do not know the IP address of your router, you can find it by visiting www.whatismyipaddress.com.

For Windows, the application PuTTY is the preferred SSH client.

FTP

FTP is the File Transfer Protocol. It can be used to move files between where you are (the remote client) and the computer you’re connecting to (your office Linux system).

To set up your Linux computer as an FTP server, use YaST’s Software Management module to make sure you have the vsftpd package installed. Then, check the System Services module to verify that vsftpd is enabled.

Before you can begin to use the FTP server properly, it needs to be configured. The default configuration is for a read-only anonymous server, without permission to see the directory tree. This is fairly useless. You probably want to modify FTP access to allow login with the normal accounts of the system and with write permissions. The general configuration file that vsftpd uses is /etc/vsftpd.conf, which is only writable by root. Make the following changes to this file, which appear below in the same order as in the file.
· Uncomment the line that says “#write_enable=YES”. This permits actions which modify files on your system.
· Uncomment and change the line “#ftpd_banner=”Welcome to FOOBAR FTP service.”” if you want to. This is a message sent to the client when they log in.
· Uncomment the line “#local_enable=YES”. This allows login with the user accounts of the system. These are listed in /etc/passwd.
· Change the line “anonymous_enable=YES” to say “anonymous_enable=NO”. There is no need to allow random passersby to access your system.
· Uncomment the lines “#log_ftp_protocol=YES” and “#xferlog_enable=YES”, which will enable logging of all actions.
To access the FTP service from a remote computer, you can use a command line FTP client. Many are available for Windows, Mac OS X, and Linux. At the FTP command line, just type

ftp

Also, most web browsers support the FTP protocol directly, so you can type ftp:// into the browser bar. Personally, I recommend a GUI FTP tool rather than command line or browser-based utility. I like Filezilla on Windows.

Linux Remote Desktop

Remote desktops create an “almost like you are there” experience for remote users. With a high-speed connection, this is a very nice way to work on your Linux system from another location. SUSE’s remote desktop is based on VNC. To begin, make sure that the VNC-related packages (tightvnc, xorg-x11-Xvnc, kdenetwork3-vnc) are installed on your Linux computer. Next, start the Remote Administration module on the YaST System tab, choose “Allow Remote Administration” and click “Finish”.

To access your Linux system from a remote computer, use a VNC client (RealVNC, TightVNC, UltraVNC, Krdc or KVPnc) and connect to port 5901 of your router’s IP address. If you are somewhere that a VNC client is not available (and installing one is not desirable) the SUSE VNC server allows another connection method. Type :5801 into a standard web browser, and a Java applet will start that remotely mimics your Linux desktop.

Setting up the Router with Port Mapping

There is one last crucial step before any of this can work. Your router must be modified to allow incoming connections to the services you just established. Using a web browser on your office network, enter the IP address of your router’s control panel. (This is usually something like 192.168.1.1.) You want to configure port forwarding, also called port mapping. On the Linksys WRT54GS router, this is the first tab under Applications and Gaming. Set your router to forward ports 20, 21, 22, 5801, and 5901 for TCP and UDP traffic, for any application, to the IP address assigned to the Linux computer inside your network. (This address is probably something like 192.168.1.6.) Ports 20 and 21 are for FTP, port 22 is for SSH, and ports 5801 and 5901 are for the VNC remote desktop. To find the internal IP address of your Linux system, type ifconfig in a Linux root shell.

Posted in Uncategorized | Leave a comment

Installing and setting TFTPD in Ubuntu

Installing and setting TFTPD in Ubuntu

1. Install tftpd and related packages.
$ sudo apt-get install xinetd tftpd tftp
2. Create /etc/xinetd.d/tftp and put this entry:

service tftp
{
protocol = udp
port = 69
socket_type = dgram
wait = yes
user = nobody
server = /usr/sbin/in.tftpd
server_args = /tftpboot
disable = no
}

3. Make /tftpboot directory

$ sudo mkdir /tftpboot
$ sudo chmod -R 777 /tftpboot
$ sudo chown -R nobody /tftpboot

4. Start tftpd through xinetd

$ sudo /etc/init.d/xinetd start

Posted in Uncategorized | Leave a comment

GPIO Device driver

GPIO Device driver

Device node creation without using “mknod”
In my last post, where i showed how to write a character gpio driver, i had used mknod for device node creation. Without mknod the device files would not have been created under /dev. So, we had to manually create the device node under /dev using mknod. Now, cannot this manual work be done away with? Of course, it can be done!!.
The automatic creation of device files can be handled with udev. One has to ensure that the major and minor numbers assigned to a device controlled by the driver are exported to user space through the sysfs interface. To know more about this, read “The Linux Device Module” chapter from the Linux Device Drivers book.
Below i am posting the source code for the driver module, the user space application and the Makefile. The user space application and Makefile remain the same. I have only changed the name of the device node under /dev from gpio to gpio_drv. So, the user space application code accordingly reflects this.
The Driver Module:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
 
#define GPIO_NUMBER    149     //any valid gpio number
 
static dev_t first;         // Global variable for the first device number
static struct cdev c_dev;     // Global variable for the character device structure
static struct class *cl;     // Global variable for the device class
 
static int init_result;
 
static ssize_t gpio_read( struct file* F, char *buf, size_t count, loff_t *f_pos )
{
    char buffer[10];
 
    int temp = gpio_get_value(GPIO_NUMBER);
 
    sprintf( buffer, “%1d” , temp );
 
    count = sizeof( buffer );
 
    if( copy_to_user( buf, buffer, count ) )
    {
        return -EFAULT;
    }
 
    if( *f_pos == 0 )
    {
        *f_pos += 1;
        return 1;
    }
    else
    {
        return 0;
    }
}
 
static ssize_t gpio_write( struct file* F, const char *buf, size_t count, loff_t *f_pos )
{
 
    printk(KERN_INFO “Executing WRITE.\n”);
 
    switch( buf[0] )
    {
        case ’0′:
        gpio_set_value(GPIO_NUMBER, 0);
        break;
 
        case ’1′:
        gpio_set_value(GPIO_NUMBER, 1);
        break;
 
        default:
        printk(“Wrong option.\n”);
        break;
    }
    return count;
}
 
static int gpio_open( struct inode *inode, struct file *file )
{
    return 0;
}
 
static int gpio_close( struct inode *inode, struct file *file )
{
    return 0;
}
 
static struct file_operations FileOps =
{
    .owner        = THIS_MODULE,
    .open         = gpio_open,
    .read         = gpio_read,
    .write        = gpio_write,
    .release      = gpio_close,
};
 
static int init_gpio(void)
{
    //init_result = register_chrdev( 0, “gpio”, &FileOps );
 
    init_result = alloc_chrdev_region( &first, 0, 1, “gpio_drv” );
 
    if( 0 > init_result )
    {
        printk( KERN_ALERT “Device Registration failed\n” );
        return -1;
    }
    //else
    //{
    //    printk( KERN_ALERT “Major number is: %d\n”,init_result );
    //    return 0;
    //}
 
    if ( (cl = class_create( THIS_MODULE, “chardev” ) ) == NULL )
    {
        printk( KERN_ALERT “Class creation failed\n” );
        unregister_chrdev_region( first, 1 );
        return -1;
    }
 
    if( device_create( cl, NULL, first, NULL, “gpio_drv” ) == NULL )
    {
        printk( KERN_ALERT “Device creation failed\n” );
        class_destroy(cl);
        unregister_chrdev_region( first, 1 );
        return -1;
    }
 
    cdev_init( &c_dev, &FileOps );
 
    if( cdev_add( &c_dev, first, 1 ) == -1)
    {
        printk( KERN_ALERT “Device addition failed\n” );
        device_destroy( cl, first );
        class_destroy( cl );
        unregister_chrdev_region( first, 1 );
        return -1;
    }
 
    return 0;
}
 
void cleanup_gpio(void)
{
    //unregister_chrdev( init_result, “gpio” );
 
    cdev_del( &c_dev );
    device_destroy( cl, first );
    class_destroy( cl );
    unregister_chrdev_region( first, 1 );
 
    printk(KERN_ALERT “Device unregistered\n”);
}
 
module_init(init_gpio);
module_exit(cleanup_gpio);
 
MODULE_AUTHOR(“Sanchayan”);
MODULE_LICENSE(“GPL”);
MODULE_DESCRIPTION(“Beagleboard-xM GPIO Driver”);
The User Space Application:
#include
#include
 
int main(void)
{
    int fd;
    char gpio_buffer[10];
    char choice[10];
 
    fd = open( “/dev/gpio_drv”, O_RDWR );
 
    printf( “Value of fd is: %d”, fd );
 
    if( fd trigger” in their respective directories.
Now, run the user space application by typing ./gpio_app on the command line prompt. You will be prompted to enter the value “0? or “1? to turn off or turn on the led. You can observe the state of the led pin on your board after this.

Posted in Uncategorized | Leave a comment

Basic board bring up of Olinuxino board & solved libncurses issue.

Built the U-boot successfully through the host and built the kernel and wrote the files in sd card.
There was an issue while configuring menu in linux-sunki folder, the issue was libncurses problem in fedora.
Then I installed libncurses by yum install ncurses-* .
After installing the libncurses i was able to access the menuconfig.

Posted in ARM Embedded Processors, Embedded Linux | Leave a comment

How to Write Your Own Linux Kernel Module with a Simple Example

What are kernel modules?

Kernel modules are piece of code, that can be loaded and unloaded from kernel on demand.

Kernel modules offers an easy way to extend the functionality of the base kernel without having to rebuild or recompile the kernel again. Most of the drivers are implemented as a Linux kernel modules. When those drivers are not needed, we can unload only that specific driver, which will reduce the kernel image size.

The kernel modules will have a .ko extension. On a normal linux system, the kernel modules will reside inside /lib/modules//kernel/ directory.

Earlier we discussed how to compile a kernel from the source.

This tutorial explains how to write a Kernel module using a simple Hello World example.
I. Utilities to Manipulate Kernel Modules
1. lsmod – List Modules that Loaded Already

lsmod command will list modules that are already loaded in the kernel as shown beblow.

# lsmod
Module Size Used by
ppp_deflate 12806 0
zlib_deflate 26445 1 ppp_deflate
bsd_comp 12785 0
..

2. insmod – Insert Module into Kernel

insmod command will insert a new module into the kernel as shown below.

# insmod /lib/modules/3.5.0-19-generic/kernel/fs/squashfs/squashfs.ko

# lsmod | grep “squash”
squashfs 35834 0

3. modinfo – Display Module Info

modinfo command will display information about a kernel module as shown below.

# modinfo /lib/modules/3.5.0-19-generic/kernel/fs/squashfs/squashfs.ko

filename: /lib/modules/3.5.0-19-generic/kernel/fs/squashfs/squashfs.ko
license: GPL
author: Phillip Lougher
description: squashfs 4.0, a compressed read-only filesystem
srcversion: 89B46A0667BD5F2494C4C72
depends:
intree: Y
vermagic: 3.5.0-19-generic SMP mod_unload modversions 686

4. rmmod – Remove Module from Kernel

rmmod command will remove a module from the kernel. You cannot remove a module which is already used by any program.

# rmmod squashfs.ko

5. modprobe – Add or Remove modules from the kernel

modprobe is an intelligent command which will load/unload modules based on the dependency between modules. Refer to modprobe commands for more detailed examples.

II. Write a Simple Hello World Kernel Module

1. Installing the linux headers

You need to install the linux-headers-.. first as shown below. Depending on your distro, use apt-get or yum.

# apt-get install build-essential linux-headers-$(uname -r)

2. Hello World Module Source Code

Next, create the following hello.c module in C programming language.

#include // included for all kernel modules
#include // included for KERN_INFO
#include // included for __init and __exit macros

MODULE_LICENSE(“GPL”);
MODULE_AUTHOR(“Lakshmanan”);
MODULE_DESCRIPTION(“A Simple Hello World module”);

static int __init hello_init(void)
{
printk(KERN_INFO “Hello world!\n”);
return 0; // Non-zero return means that the module couldn’t be loaded.
}

static void __exit hello_cleanup(void)
{
printk(KERN_INFO “Cleaning up module.\n”);
}

module_init(hello_init);
module_exit(hello_cleanup);

Warning: All kernel modules will operate on kernel space, a highly privileged mode. So be careful with what you write in a kernel module.

3. Create Makefile to Compile Kernel Module

The following makefile can be used to compile the above basic hello world kernel module.

obj-m += hello.o

all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

Use the make command to compile hello world kernel module as shown below.

# make

make -C /lib/modules/3.5.0-19-generic/build M=/home/lakshmanan/a modules
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-19-generic’
CC [M] /home/lakshmanan/a/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/lakshmanan/a/hello.mod.o
LD [M] /home/lakshmanan/a/hello.ko
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-19-generic’

The above will create hello.ko file, which is our sample Kernel module.
4. Insert or Remove the Sample Kernel Module

Now that we have our hello.ko file, we can insert this module to the kernel by using insmod command as shown below.

# insmod hello.ko

# dmesg | tail -1
[ 8394.731865] Hello world!

# rmmod hello.ko

# dmesg | tail -1
[ 8707.989819] Cleaning up module.

When a module is inserted into the kernel, the module_init macro will be invoked, which will call the function hello_init. Similarly, when the module is removed with rmmod, module_exit macro will be invoked, which will call the hello_exit. Using dmesg command, we can see the output from the sample Kernel module.

Please note that printk is a function which is defined in kernel, and it behaves similar to the printf in the IO library. Remember that you cannot use any of the library functions from the kernel module.

Posted in Uncategorized | Leave a comment

U-Boot environment

The U-Boot environment is a block of memory that is kept on persistent storage and copied to RAM when U-Boot starts. It is used to store environment variables which can be used to configure the system. The environment is protected by a CRC32 checksum.

This section lists the most important environment variables, some of which have a special meaning to U-Boot. You can use these variables to configure the behaviour of U-Boot to your liking.

autoload: if set to “no” (or any string beginning with ‘n’), the rarpb, bootp or dhcp commands will perform only a configuration lookup from the BOOTP / DHCP server, but not try to load any image using TFTP.
autostart: if set to “yes”, an image loaded using the rarpb, bootp, dhcp, tftp, disk, or docb commands will be automatically started (by internally calling the bootm command).
baudrate: a decimal number that selects the console baudrate (in bps). Only a predefined list of baudrate settings is available.
When you change the baudrate (using the “setenv baudrate …” command), U-Boot will switch the baudrate of the console terminal and wait for a newline which must be entered with the new speed setting. This is to make sure you can actually type at the new speed. If this fails, you have to reset the board (which will operate at the old speed since you were not able to saveenv the new settings.)
If no “baudrate” variable is defined, the default baudrate of 115200 is used.
bootargs: The contents of this variable are passed to the Linux kernel as boot arguments (aka “command line”).
bootcmd: This variable defines a command string that is automatically executed when the initial countdown is not interrupted.
This command is only executed when the variable bootdelay is also defined!
bootdelay: After reset, U-Boot will wait this number of seconds before it executes the contents of the bootcmd variable. During this time a countdown is printed, which can be interrupted by pressing any key.
Set this variable to 0 boot without delay. Be careful: depending on the contents of your bootcmd variable, this can prevent you from entering interactive commands again forever!
Set this variable to -1 to disable autoboot.
bootfile: name of the default image to load with TFTP
cpuclk: (Only with MPC859 / MPC866 / MPC885 processors) On some processors, the CPU clock frequency can be adjusted by the user (for example to optimize performance versus power dissipation). On such systems the cpuclk variable can be set to the desired CPU clock value, in MHz. If the cpuclk variable exists and its value is within the compile-time defined limits (CONFIG_SYS_8xx_CPUCLK_MIN and CONFIG_SYS_8xx_CPUCLK_MAX = minimum resp. maximum allowed CPU clock), then the specified value is used. Otherwise, the default CPU clock value of CONFIG_8xx_CPUCLK_DEFAULT is used.
ethaddr: Ethernet MAC address for first/only ethernet interface (= eth0 in Linux).
This variable can be set only once (usually during manufacturing of the board). U-Boot refuses to delete or overwrite this variable once it has been set.
eth1addr: Ethernet MAC address for second ethernet interface (= eth1 in Linux).
eth2addr: Ethernet MAC address for third ethernet interface (= eth2 in Linux).

initrd_high: used to restrict positioning of initrd ramdisk images:
If this variable is not set, initrd images will be copied to the highest possible address in RAM; this is usually what you want since it allows for maximum initrd size. If for some reason you want to make sure that the initrd image is loaded below the CFG_BOOTMAPSZ limit, you can set this environment variable to a value of “no” or “off” or “0″. Alternatively, you can set it to a maximum upper address to use (U-Boot will still check that it does not overwrite the U-Boot stack and data).
For instance, when you have a system with 16 MB RAM, and want to reserve 4 MB from use by Linux, you can do this by adding “mem=12M” to the value of the “bootargs” variable. However, now you must make sure that the initrd image is placed in the first 12 MB as well – this can be done with
=> setenv initrd_high 00c00000

Setting initrd_high to the highest possible address in your system (0xFFFFFFFF) prevents U-Boot from copying the image to RAM at all. This allows for faster boot times, but requires a Linux kernel with zero-copy ramdisk support.
ipaddr: IP address; needed for tftp command
loadaddr: Default load address for commands like tftp or loads.
loads_echo: If set to 1, all characters received during a serial download (using the loads command) are echoed back. This might be needed by some terminal emulations (like cu), but may as well just take time on others.
mtdparts: This variable (usually defined using the mtdparts command) allows to share a common MTD partition scheme between U-Boot and the Linux kernel.
pram: If the “Protected RAM” feature is enabled in your board’s configuration, this variable can be defined to enable the reservation of such “protected RAM”, i. e. RAM which is not overwritten by U-Boot. Define this variable to hold the number of kB you want to reserve for pRAM. Note that the board info structure will still show the full amount of RAM. If pRAM is reserved, a new environment variable “mem” will automatically be defined to hold the amount of remaining RAM in a form that can be passed as boot argument to Linux, for instance like that:
=> setenv bootargs ${bootargs} mem=\${mem}
=> saveenv

This way you can tell Linux not to use this memory, either, which results in a memory region that will not be affected by reboots.
serverip: TFTP server IP address; needed for tftp command.
serial#: contains hardware identification information such as type string and/or serial number.
This variable can be set only once (usually during manufacturing of the board). U-Boot refuses to delete or overwrite this variable once it hass been set.
silent: If the configuration option CONFIG_SILENT_CONSOLE has been enabled for your board, setting this variable to any value will suppress all console messages. Please see doc/README.silent for details.
verify: If set to n or no disables the checksum calculation over the complete image in the bootm command to trade speed for safety in the boot process. Note that the header checksum is still verified.
The following environment variables may be used and automatically updated by the network boot commands (bootp, dhcp, or tftp), depending the information provided by your boot server:

bootfile: see above
dnsip: IP address of your Domain Name Server
gatewayip: IP address of the Gateway (Router) to use
hostname: Target hostname
ipaddr: see above
netmask: Subnet Mask
rootpath: Pathname of the root filesystem on the NFS server
serverip: see above
filesize: Size (as hex number in bytes) of the file downloaded using the last bootp, dhcp, or tftp command.

Posted in Uncategorized | Leave a comment

U-Boot: Quick reference

Information commands

bdinfo – print Board Info structure
coninfo – print console devices and information
flinfo – print FLASH memory information
help – print online help
Memory commands

base – print or set address offset
crc32 – checksum calculation
cmp – memory compare
cp – memory copy
md – memory display
mm – memory modify (auto incrementing)
mtest – simple RAM test
mw – memory write (fill)
nm – memory modify (constant address)
loop – infinite loop on address range
Flash memory commands

cp – memory copy
flinfo – print FLASH memory information
erase – erase FLASH memory
protect – enable or disable FLASH write protection
Image commands

iminfo – print header information for application image
imxtract – extract a part of a multi-image
Execution control commands

autoscr – run script from memory
source – run script from memory
bootm – boot application image from memory
go – start application at address ‘addr’
loop – infinite loop on address range
exit – exit script
Download commands

bootp – boot image via network using BOOTP/TFTP protocol
dhcp – invoke DHCP client to obtain IP/boot params
loadb – load binary file over serial line (kermit mode)
loady – load binary file over serial line (ymodem mode)
loads – load S?Record file over serial line
rarpboot – boot image via network using RARP/TFTP protocol
tftpboot – boot image via network using TFTP protocol
nfs – boot image via network using NFS protocol
ping – send ICMP ECHO REQUEST to network host
Environment variables commands

env – environment handling commands
editenv – edit environment variable
printenv – print environment variables
saveenv – save environment variables to persistent storage
setenv – set environment variables
run – run commands in an environment variable
bootd – boot default, i.e., run ‘bootcmd’
boot – boot default, i.e., run ‘bootcmd’
File system support commands

fatinfo – print information about a FAT file system
fatload – load binary file from a FAT file system
fatls – list files in a FAT file system directory (default /)
ext2load – load binary file from a Ext2 filesystem
ext2ls – list files in a directory (default /)
fsinfo – print information about JFFS2 file system
fsload – load binary file from a JFFS2 file system image
ls – list files in a JFFS2 file system directory (default /)
NAND flash support

nand – NAND sub-system control
nandecc – switch OMAP3 NAND ECC calculation algorithm
nboot – boot from NAND device
Partition commands

mtdparts – define flash/nand partitions
chpart – change active partition
FDT support

fdt – flattened device tree utility commands
MMC support

mmc – MMC sub system
mmcinfo – display MMC information
I2C support

i2c – I2C sub-system control
USB support

usb – USB sub-system control
usbboot – boot from USB device
Cache support

icache – enable or disable instruction cache
dcache – enable or disable data cache
Bitmap support

bmp – manipulate BMP image data
GPIO support

gpio – manipulate gpios
Miscellaneous commands

echo – echo arguments to console
reset – Perform RESET of the CPU
sleep – delay execution for some time
version – print monitor version
test – minimal test, like /bin/bash
? – alias for help
showvar – print local hushshell variables
true – do nothing, successfully
false – do nothing, unsuccessfully
cls – clear screen
itest – return true/false on integer compare

Posted in Uncategorized | Leave a comment

The Linux Kernel Sources

How The Kernel Sources Are Arranged

At the very top level of the source tree /usr/src/linux you will see a number of directories:
arch
The arch subdirectory contains all of the architecture specific kernel code. It has further subdirectories, one per supported architecture, for example i386 and alpha.
include
The include subdirectory contains most of the include files needed to build the kernel code. It too has further subdirectories including one for every architecture supported. The include/asm subdirectory is a soft link to the real include directory needed for this architecture, for example include/asm-i386. To change architectures you need to edit the kernel makefile and rerun the Linux kernel configuration program.
init
This directory contains the initialization code for the kernel and it is a very good place to start looking at how the kernel works.
mm
This directory contains all of the memory management code. The architecture specific memory management code lives down in arch/*/mm/, for example arch/i386/mm/fault.c.
drivers
All of the system’s device drivers live in this directory. They are further sub-divided into classes of device driver, for example block.
ipc
This directory contains the kernels inter-process communications code.
modules
This is simply a directory used to hold built modules.
fs
All of the file system code. This is further sub-divided into directories, one per supported file system, for example vfat and ext2.
kernel
The main kernel code. Again, the architecture specific kernel code is in arch/*/kernel.
net
The kernel’s networking code.
lib
This directory contains the kernel’s library code. The architecture specific library code can be found in arch/*/lib/.
scripts
This directory contains the scripts (for example awk and tk scripts) that are used when the kernel is configured.
Where to Start Looking

A large complex program like the Linux kernel can be rather daunting to look at. It is rather like a large ball of string with no end showing. Looking at one part of the kernel often leads to looking at several other related files and before long you have forgotten what you were looking for. The next subsections give you a hint as to where in the source tree the best place to look is for a given subject.
System Startup and Initialization

On an Intel based system, the kernel starts when either loadlin.exe or LILO has loaded the kernel into memory and passed control to it. Look in arch/i386/kernel/head.S for this part. Head.S does some architecture specific setup and then jumps to the main() routine in init/main.c.
Memory Management

This code is mostly in mm but the architecture specific code is in arch/*/mm. The page fault handling code is in mm/memory.c and the memory mapping and page cache code is in mm/filemap.c. The buffer cache is implemented in mm/buffer.c and the swap cache in mm/swap_state.c and mm/swapfile.c.
Kernel

Most of the relevent generic code is in kernel with the architecture specific code in arch/*/kernel. The scheduler is in kernel/sched.c and the fork code is in kernel/fork.c. The bottom half handling code is in include/linux/interrupt.h. The task_struct data structure can be found in include/linux/sched.h.
PCI

The PCI pseudo driver is in drivers/pci/pci.c with the system wide definitions in include/linux/pci.h. Each architecture has some specific PCI BIOS code, Alpha AXP’s is in arch/alpha/kernel/bios32.c.
Interprocess Communication

This is all in ipc. All System V IPC objects include an ipc_perm data structure and this can be found in include/linux/ipc.h. System V messages are implemented in ipc/msg.c, shared memory in ipc/shm.c and semaphores in ipc/sem.c. Pipes are implemented in ipc/pipe.c.
Interrupt Handling

The kernel’s interrupt handling code is almost all microprocessor (and often platform) specific. The Intel interrupt handling code is in arch/i386/kernel/irq.c and its definitions in include/asm-i386/irq.h.
Device Drivers

Most of the lines of the Linux kernel’s source code are in its device drivers. All of Linux’s device driver sources are held in drivers but these are further broken out by type:
/block
block device drivers such as ide (in ide.c). If you want to look at how all of the devices that could possibly contain file systems are initialized then you should look at device_setup() in drivers/block/genhd.c. It not only initializes the hard disks but also the network as you need a network to mount nfs file systems. Block devices include both IDE and SCSI based devices.
/char
This the place to look for character based devices such as ttys, serial ports and mice.
/cdrom
All of the CDROM code for Linux. It is here that the special CDROM devices (such as Soundblaster CDROM) can be found. Note that the ide CD driver is ide-cd.c in drivers/block and that the SCSI CD driver is in scsi.c in drivers/scsi.
/pci
This are the sources for the PCI pseudo-driver. A good place to look at how the PCI subsystem is mapped and initialized. The Alpha AXP PCI fixup code is also worth looking at in arch/alpha/kernel/bios32.c.
/scsi
This is where to find all of the SCSI code as well as all of the drivers for the scsi devices supported by Linux.
/net
This is where to look to find the network device drivers such as the DECChip 21040 PCI ethernet driver which is in tulip.c.
/sound
This is where all of the sound card drivers are.
File Systems

The sources for the EXT2 file system are all in the fs/ext2/ directory with data structure definitions in include/linux/ext2_fs.h, ext2_fs_i.h and ext2_fs_sb.h. The Virtual File System data structures are described in include/linux/fs.h and the code is in fs/*. The buffer cache is implemented in fs/buffer.c along with the update kernel daemon.
Network

The networking code is kept in net with most of the include files in include/net. The BSD socket code is in net/socket.c and the IP version 4 INET socket code is in net/ipv4/af_inet.c. The generic protocol support code (including the sk_buff handling routines) is in net/core with the TCP/IP networking code in net/ipv4. The network device drivers are in drivers/net.
Modules

The kernel module code is partially in the kernel and partially in the modules package. The kernel code is all in kernel/modules.c with the data structures and kernel demon kerneld messages in include/linux/module.h and include/linux/kerneld.h respectively. You may want to look at the structure of an ELF object file in include/linux/elf.h.

Posted in Uncategorized | Leave a comment

Linux Data Structures

block_dev_struct

block_dev_struct data structures are used to register block devices as available for use by the buffer cache. They are held together in the blk_dev vector.
struct blk_dev_struct {
void (*request_fn)(void);
struct request * current_request;
struct request plug;
struct tq_struct plug_tq;
};
buffer_head

The buffer_head data structure holds information about a block buffer in the buffer cache.
/* bh state bits */
#define BH_Uptodate 0 /* 1 if the buffer contains valid data */
#define BH_Dirty 1 /* 1 if the buffer is dirty */
#define BH_Lock 2 /* 1 if the buffer is locked */
#define BH_Req 3 /* 0 if the buffer has been invalidated */
#define BH_Touched 4 /* 1 if the buffer has been touched (aging) */
#define BH_Has_aged 5 /* 1 if the buffer has been aged (aging) */
#define BH_Protected 6 /* 1 if the buffer is protected */
#define BH_FreeOnIO 7 /* 1 to discard the buffer_head after IO */

struct buffer_head {
/* First cache line: */
unsigned long b_blocknr; /* block number */
kdev_t b_dev; /* device (B_FREE = free) */
kdev_t b_rdev; /* Real device */
unsigned long b_rsector; /* Real buffer location on disk */
struct buffer_head *b_next; /* Hash queue list */
struct buffer_head *b_this_page; /* circular list of buffers in one
page */

/* Second cache line: */
unsigned long b_state; /* buffer state bitmap (above) */
struct buffer_head *b_next_free;
unsigned int b_count; /* users using this block */
unsigned long b_size; /* block size */

/* Non-performance-critical data follows. */
char *b_data; /* pointer to data block */
unsigned int b_list; /* List that this buffer appears */
unsigned long b_flushtime; /* Time when this (dirty) buffer
* should be written */
unsigned long b_lru_time; /* Time when this buffer was
* last used. */
struct wait_queue *b_wait;
struct buffer_head *b_prev; /* doubly linked hash list */
struct buffer_head *b_prev_free; /* doubly linked list of buffers */
struct buffer_head *b_reqnext; /* request queue */
};
device

Every network device in the system is represented by a device data structure.
struct device
{

/*
* This is the first field of the “visible” part of this structure
* (i.e. as seen by users in the “Space.c” file). It is the name
* the interface.
*/
char *name;

/* I/O specific fields */
unsigned long rmem_end; /* shmem “recv” end */
unsigned long rmem_start; /* shmem “recv” start */
unsigned long mem_end; /* shared mem end */
unsigned long mem_start; /* shared mem start */
unsigned long base_addr; /* device I/O address */
unsigned char irq; /* device IRQ number */

/* Low-level status flags. */
volatile unsigned char start, /* start an operation */
interrupt; /* interrupt arrived */
unsigned long tbusy; /* transmitter busy */
struct device *next;

/* The device initialization function. Called only once. */
int (*init)(struct device *dev);

/* Some hardware also needs these fields, but they are not part of
the usual set specified in Space.c. */
unsigned char if_port; /* Selectable AUI,TP, */
unsigned char dma; /* DMA channel */

struct enet_statistics* (*get_stats)(struct device *dev);

/*
* This marks the end of the “visible” part of the structure. All
* fields hereafter are internal to the system, and may change at
* will (read: may be cleaned up at will).
*/

/* These may be needed for future network-power-down code. */
unsigned long trans_start; /* Time (jiffies) of
last transmit */
unsigned long last_rx; /* Time of last Rx */
unsigned short flags; /* interface flags (BSD)*/
unsigned short family; /* address family ID */
unsigned short metric; /* routing metric */
unsigned short mtu; /* MTU value */
unsigned short type; /* hardware type */
unsigned short hard_header_len; /* hardware hdr len */
void *priv; /* private data */

/* Interface address info. */
unsigned char broadcast[MAX_ADDR_LEN];
unsigned char pad;
unsigned char dev_addr[MAX_ADDR_LEN];
unsigned char addr_len; /* hardware addr len */
unsigned long pa_addr; /* protocol address */
unsigned long pa_brdaddr; /* protocol broadcast addr*/
unsigned long pa_dstaddr; /* protocol P-P other addr*/
unsigned long pa_mask; /* protocol netmask */
unsigned short pa_alen; /* protocol address len */

struct dev_mc_list *mc_list; /* M’cast mac addrs */
int mc_count; /* No installed mcasts */

struct ip_mc_list *ip_mc_list; /* IP m’cast filter chain */
__u32 tx_queue_len; /* Max frames per queue */

/* For load balancing driver pair support */
unsigned long pkt_queue; /* Packets queued */
struct device *slave; /* Slave device */
struct net_alias_info *alias_info; /* main dev alias info */
struct net_alias *my_alias; /* alias devs */

/* Pointer to the interface buffers. */
struct sk_buff_head buffs[DEV_NUMBUFFS];

/* Pointers to interface service routines. */
int (*open)(struct device *dev);
int (*stop)(struct device *dev);
int (*hard_start_xmit) (struct sk_buff *skb,
struct device *dev);
int (*hard_header) (struct sk_buff *skb,
struct device *dev,
unsigned short type,
void *daddr,
void *saddr,
unsigned len);
int (*rebuild_header)(void *eth,
struct device *dev,
unsigned long raddr,
struct sk_buff *skb);
void (*set_multicast_list)(struct device *dev);
int (*set_mac_address)(struct device *dev,
void *addr);
int (*do_ioctl)(struct device *dev,
struct ifreq *ifr,
int cmd);
int (*set_config)(struct device *dev,
struct ifmap *map);
void (*header_cache_bind)(struct hh_cache **hhp,
struct device *dev,
unsigned short htype,
__u32 daddr);
void (*header_cache_update)(struct hh_cache *hh,
struct device *dev,
unsigned char * haddr);
int (*change_mtu)(struct device *dev,
int new_mtu);
struct iw_statistics* (*get_wireless_stats)(struct device *dev);
};
device_struct

device_struct data structures are used to register character and block devices (they hold its name and the set of file operations that can be used for this device). Each valid member of the chrdevs and blkdevs vectors represents a character or block device respectively.
struct device_struct {
const char * name;
struct file_operations * fops;
};
file

Each open file, socket etcetera is represented by a file data structure.
struct file {
mode_t f_mode;
loff_t f_pos;
unsigned short f_flags;
unsigned short f_count;
unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin;
struct file *f_next, *f_prev;
int f_owner; /* pid or -pgrp where SIGIO should be sent */
struct inode * f_inode;
struct file_operations * f_op;
unsigned long f_version;
void *private_data; /* needed for tty driver, and maybe others */
};
files_struct

The files_struct data structure describes the files that a process has open.
struct files_struct {
int count;
fd_set close_on_exec;
fd_set open_fds;
struct file * fd[NR_OPEN];
};
fs_struct

struct fs_struct {
int count;
unsigned short umask;
struct inode * root, * pwd;
};
gendisk

The gendisk data structure holds information about a hard disk. They are used during initialization when the disks are found and then probed for partitions.
struct hd_struct {
long start_sect;
long nr_sects;
};

struct gendisk {
int major; /* major number of driver */
const char *major_name; /* name of major driver */
int minor_shift; /* number of times minor is shifted to
get real minor */
int max_p; /* maximum partitions per device */
int max_nr; /* maximum number of real devices */

void (*init)(struct gendisk *);
/* Initialization called before we
do our thing */
struct hd_struct *part; /* partition table */
int *sizes; /* device size in blocks, copied to
blk_size[] */
int nr_real; /* number of real devices */

void *real_devices; /* internal use */
struct gendisk *next;
};
inode

The VFS inode data structure holds information about a file or directory on disk.
struct inode {
kdev_t i_dev;
unsigned long i_ino;
umode_t i_mode;
nlink_t i_nlink;
uid_t i_uid;
gid_t i_gid;
kdev_t i_rdev;
off_t i_size;
time_t i_atime;
time_t i_mtime;
time_t i_ctime;
unsigned long i_blksize;
unsigned long i_blocks;
unsigned long i_version;
unsigned long i_nrpages;
struct semaphore i_sem;
struct inode_operations *i_op;
struct super_block *i_sb;
struct wait_queue *i_wait;
struct file_lock *i_flock;
struct vm_area_struct *i_mmap;
struct page *i_pages;
struct dquot *i_dquot[MAXQUOTAS];
struct inode *i_next, *i_prev;
struct inode *i_hash_next, *i_hash_prev;
struct inode *i_bound_to, *i_bound_by;
struct inode *i_mount;
unsigned short i_count;
unsigned short i_flags;
unsigned char i_lock;
unsigned char i_dirt;
unsigned char i_pipe;
unsigned char i_sock;
unsigned char i_seek;
unsigned char i_update;
unsigned short i_writecount;
union {
struct pipe_inode_info pipe_i;
struct minix_inode_info minix_i;
struct ext_inode_info ext_i;
struct ext2_inode_info ext2_i;
struct hpfs_inode_info hpfs_i;
struct msdos_inode_info msdos_i;
struct umsdos_inode_info umsdos_i;
struct iso_inode_info isofs_i;
struct nfs_inode_info nfs_i;
struct xiafs_inode_info xiafs_i;
struct sysv_inode_info sysv_i;
struct affs_inode_info affs_i;
struct ufs_inode_info ufs_i;
struct socket socket_i;
void *generic_ip;
} u;
};
ipc_perm

The ipc_perm data structure describes the access permissions of a System V IPC object .
struct ipc_perm
{
key_t key;
ushort uid; /* owner euid and egid */
ushort gid;
ushort cuid; /* creator euid and egid */
ushort cgid;
ushort mode; /* access modes see mode flags below */
ushort seq; /* sequence number */
};
irqaction

The irqaction data structure is used to describe the system’s interrupt handlers.
struct irqaction {
void (*handler)(int, void *, struct pt_regs *);
unsigned long flags;
unsigned long mask;
const char *name;
void *dev_id;
struct irqaction *next;
};
linux_binfmt

Each binary file format that Linux understands is represented by a linux_binfmt data structure.
struct linux_binfmt {
struct linux_binfmt * next;
long *use_count;
int (*load_binary)(struct linux_binprm *, struct pt_regs * regs);
int (*load_shlib)(int fd);
int (*core_dump)(long signr, struct pt_regs * regs);
};
mem_map_t

The mem_map_t data structure (also known as page) is used to hold information about each page of physical memory.
typedef struct page {
/* these must be first (free area handling) */
struct page *next;
struct page *prev;
struct inode *inode;
unsigned long offset;
struct page *next_hash;
atomic_t count;
unsigned flags; /* atomic flags, some possibly
updated asynchronously */
unsigned dirty:16,
age:8;
struct wait_queue *wait;
struct page *prev_hash;
struct buffer_head *buffers;
unsigned long swap_unlock_entry;
unsigned long map_nr; /* page->map_nr == page – mem_map */
} mem_map_t;
mm_struct

The mm_struct data structure is used to describe the virtual memory of a task or process.
struct mm_struct {
int count;
pgd_t * pgd;
unsigned long context;
unsigned long start_code, end_code, start_data, end_data;
unsigned long start_brk, brk, start_stack, start_mmap;
unsigned long arg_start, arg_end, env_start, env_end;
unsigned long rss, total_vm, locked_vm;
unsigned long def_flags;
struct vm_area_struct * mmap;
struct vm_area_struct * mmap_avl;
struct semaphore mmap_sem;
};
pci_bus

Every PCI bus in the system is represented by a pci_bus data structure.
struct pci_bus {
struct pci_bus *parent; /* parent bus this bridge is on */
struct pci_bus *children; /* chain of P2P bridges on this bus */
struct pci_bus *next; /* chain of all PCI buses */

struct pci_dev *self; /* bridge device as seen by parent */
struct pci_dev *devices; /* devices behind this bridge */

void *sysdata; /* hook for sys-specific extension */

unsigned char number; /* bus number */
unsigned char primary; /* number of primary bridge */
unsigned char secondary; /* number of secondary bridge */
unsigned char subordinate; /* max number of subordinate buses */
};
pci_dev

Every PCI device in the system, including PCI-PCI and PCI-ISA bridge devices is represented by a pci_dev data structure.
/*
* There is one pci_dev structure for each slot-number/function-number
* combination:
*/
struct pci_dev {
struct pci_bus *bus; /* bus this device is on */
struct pci_dev *sibling; /* next device on this bus */
struct pci_dev *next; /* chain of all devices */

void *sysdata; /* hook for sys-specific extension */

unsigned int devfn; /* encoded device & function index */
unsigned short vendor;
unsigned short device;
unsigned int class; /* 3 bytes: (base,sub,prog-if) */
unsigned int master : 1; /* set if device is master capable */
/*
* In theory, the irq level can be read from configuration
* space and all would be fine. However, old PCI chips don’t
* support these registers and return 0 instead. For example,
* the Vision864-P rev 0 chip can uses INTA, but returns 0 in
* the interrupt line and pin registers. pci_init()
* initializes this field with the value at PCI_INTERRUPT_LINE
* and it is the job of pcibios_fixup() to change it if
* necessary. The field must not be 0 unless the device
* cannot generate interrupts at all.
*/
unsigned char irq; /* irq generated by this device */
};
request

request data structures are used to make requests to the block devices in the system. The requests are always to read or write blocks of data to or from the buffer cache.
struct request {
volatile int rq_status;
#define RQ_INACTIVE (-1)
#define RQ_ACTIVE 1
#define RQ_SCSI_BUSY 0xffff
#define RQ_SCSI_DONE 0xfffe
#define RQ_SCSI_DISCONNECTING 0xffe0

kdev_t rq_dev;
int cmd; /* READ or WRITE */
int errors;
unsigned long sector;
unsigned long nr_sectors;
unsigned long current_nr_sectors;
char * buffer;
struct semaphore * sem;
struct buffer_head * bh;
struct buffer_head * bhtail;
struct request * next;
};
rtable

Each rtable data structure holds information about the route to take in order to send packets to an IP host. rtable data structures are used within the IP route cache.
struct rtable
{
struct rtable *rt_next;
__u32 rt_dst;
__u32 rt_src;
__u32 rt_gateway;
atomic_t rt_refcnt;
atomic_t rt_use;
unsigned long rt_window;
atomic_t rt_lastuse;
struct hh_cache *rt_hh;
struct device *rt_dev;
unsigned short rt_flags;
unsigned short rt_mtu;
unsigned short rt_irtt;
unsigned char rt_tos;
};
semaphore

Semaphores are used to protect critical data structures and regions of code. y
struct semaphore {
int count;
int waking;
int lock ; /* to make waking testing atomic */
struct wait_queue *wait;
};
sk_buff

The sk_buff data structure is used to describe network data as it moves between the layers of protocol.
struct sk_buff
{
struct sk_buff *next; /* Next buffer in list */
struct sk_buff *prev; /* Previous buffer in list */
struct sk_buff_head *list; /* List we are on */
int magic_debug_cookie;
struct sk_buff *link3; /* Link for IP protocol level buffer chains */
struct sock *sk; /* Socket we are owned by */
unsigned long when; /* used to compute rtt’s */
struct timeval stamp; /* Time we arrived */
struct device *dev; /* Device we arrived on/are leaving by */
union
{
struct tcphdr *th;
struct ethhdr *eth;
struct iphdr *iph;
struct udphdr *uh;
unsigned char *raw;
/* for passing file handles in a unix domain socket */
void *filp;
} h;

union
{
/* As yet incomplete physical layer views */
unsigned char *raw;
struct ethhdr *ethernet;
} mac;

struct iphdr *ip_hdr; /* For IPPROTO_RAW */
unsigned long len; /* Length of actual data */
unsigned long csum; /* Checksum */
__u32 saddr; /* IP source address */
__u32 daddr; /* IP target address */
__u32 raddr; /* IP next hop address */
__u32 seq; /* TCP sequence number */
__u32 end_seq; /* seq [+ fin] [+ syn] + datalen */
__u32 ack_seq; /* TCP ack sequence number */
unsigned char proto_priv[16];
volatile char acked, /* Are we acked ? */
used, /* Are we in use ? */
free, /* How to free this buffer */
arp; /* Has IP/ARP resolution finished */
unsigned char tries, /* Times tried */
lock, /* Are we locked ? */
localroute, /* Local routing asserted for this frame */
pkt_type, /* Packet class */
pkt_bridged, /* Tracker for bridging */
ip_summed; /* Driver fed us an IP checksum */
#define PACKET_HOST 0 /* To us */
#define PACKET_BROADCAST 1 /* To all */
#define PACKET_MULTICAST 2 /* To group */
#define PACKET_OTHERHOST 3 /* To someone else */
unsigned short users; /* User count – see datagram.c,tcp.c */
unsigned short protocol; /* Packet protocol from driver. */
unsigned int truesize; /* Buffer size */
atomic_t count; /* reference count */
struct sk_buff *data_skb; /* Link to the actual data skb */
unsigned char *head; /* Head of buffer */
unsigned char *data; /* Data head pointer */
unsigned char *tail; /* Tail pointer */
unsigned char *end; /* End pointer */
void (*destructor)(struct sk_buff *); /* Destruct function */
__u16 redirport; /* Redirect port */
};
sock

Each sock data structure holds protocol specific information about a BSD socket. For example, for an INET (Internet Address Domain) socket this data structure would hold all of the TCP/IP and UDP/IP specific information.
struct sock
{
/* This must be first. */
struct sock *sklist_next;
struct sock *sklist_prev;

struct options *opt;
atomic_t wmem_alloc;
atomic_t rmem_alloc;
unsigned long allocation; /* Allocation mode */
__u32 write_seq;
__u32 sent_seq;
__u32 acked_seq;
__u32 copied_seq;
__u32 rcv_ack_seq;
unsigned short rcv_ack_cnt; /* count of same ack */
__u32 window_seq;
__u32 fin_seq;
__u32 urg_seq;
__u32 urg_data;
__u32 syn_seq;
int users; /* user count */
/*
* Not all are volatile, but some are, so we
* might as well say they all are.
*/
volatile char dead,
urginline,
intr,
blog,
done,
reuse,
keepopen,
linger,
delay_acks,
destroy,
ack_timed,
no_check,
zapped,
broadcast,
nonagle,
bsdism;
unsigned long lingertime;
int proc;

struct sock *next;
struct sock **pprev;
struct sock *bind_next;
struct sock **bind_pprev;
struct sock *pair;
int hashent;
struct sock *prev;
struct sk_buff *volatile send_head;
struct sk_buff *volatile send_next;
struct sk_buff *volatile send_tail;
struct sk_buff_head back_log;
struct sk_buff *partial;
struct timer_list partial_timer;
long retransmits;
struct sk_buff_head write_queue,
receive_queue;
struct proto *prot;
struct wait_queue **sleep;
__u32 daddr;
__u32 saddr; /* Sending source */
__u32 rcv_saddr; /* Bound address */
unsigned short max_unacked;
unsigned short window;
__u32 lastwin_seq; /* sequence number when we last
updated the window we offer */
__u32 high_seq; /* sequence number when we did
current fast retransmit */
volatile unsigned long ato; /* ack timeout */
volatile unsigned long lrcvtime; /* jiffies at last data rcv */
volatile unsigned long idletime; /* jiffies at last rcv */
unsigned int bytes_rcv;
/*
* mss is min(mtu, max_window)
*/
unsigned short mtu; /* mss negotiated in the syn’s */
volatile unsigned short mss; /* current eff. mss – can change */
volatile unsigned short user_mss; /* mss requested by user in ioctl */
volatile unsigned short max_window;
unsigned long window_clamp;
unsigned int ssthresh;
unsigned short num;
volatile unsigned short cong_window;
volatile unsigned short cong_count;
volatile unsigned short packets_out;
volatile unsigned short shutdown;
volatile unsigned long rtt;
volatile unsigned long mdev;
volatile unsigned long rto;

volatile unsigned short backoff;
int err, err_soft; /* Soft holds errors that don’t
cause failure but are the cause
of a persistent failure not
just ‘timed out’ */
unsigned char protocol;
volatile unsigned char state;
unsigned char ack_backlog;
unsigned char max_ack_backlog;
unsigned char priority;
unsigned char debug;
int rcvbuf;
int sndbuf;
unsigned short type;
unsigned char localroute; /* Route locally only */
/*
* This is where all the private (optional) areas that don’t
* overlap will eventually live.
*/
union
{
struct unix_opt af_unix;
#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
struct atalk_sock af_at;
#endif
#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)
struct ipx_opt af_ipx;
#endif
#ifdef CONFIG_INET
struct inet_packet_opt af_packet;
#ifdef CONFIG_NUTCP
struct tcp_opt af_tcp;
#endif
#endif
} protinfo;
/*
* IP ‘private area’
*/
int ip_ttl; /* TTL setting */
int ip_tos; /* TOS */
struct tcphdr dummy_th;
struct timer_list keepalive_timer; /* TCP keepalive hack */
struct timer_list retransmit_timer; /* TCP retransmit timer */
struct timer_list delack_timer; /* TCP delayed ack timer */
int ip_xmit_timeout; /* Why the timeout is running */
struct rtable *ip_route_cache; /* Cached output route */
unsigned char ip_hdrincl; /* Include headers ? */
#ifdef CONFIG_IP_MULTICAST
int ip_mc_ttl; /* Multicasting TTL */
int ip_mc_loop; /* Loopback */
char ip_mc_name[MAX_ADDR_LEN]; /* Multicast device name */
struct ip_mc_socklist *ip_mc_list; /* Group array */
#endif

/*
* This part is used for the timeout functions (timer.c).
*/
int timeout; /* What are we waiting for? */
struct timer_list timer; /* This is the TIME_WAIT/receive
* timer when we are doing IP
*/
struct timeval stamp;
/*
* Identd
*/
struct socket *socket;
/*
* Callbacks
*/
void (*state_change)(struct sock *sk);
void (*data_ready)(struct sock *sk,int bytes);
void (*write_space)(struct sock *sk);
void (*error_report)(struct sock *sk);

};
socket

Each socket data structure holds information about a BSD socket. It does not exist independently; it is, instead, part of the VFS inode data structure.
struct socket {
short type; /* SOCK_STREAM, … */
socket_state state;
long flags;
struct proto_ops *ops; /* protocols do most everything */
void *data; /* protocol data */
struct socket *conn; /* server socket connected to */
struct socket *iconn; /* incomplete client conn.s */
struct socket *next;
struct wait_queue **wait; /* ptr to place to wait on */
struct inode *inode;
struct fasync_struct *fasync_list; /* Asynchronous wake up list */
struct file *file; /* File back pointer for gc */
};
task_struct

Each task_struct data structure describes a process or task in the system.
struct task_struct {
/* these are hardcoded – don’t touch */
volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
long counter;
long priority;
unsigned long signal;
unsigned long blocked; /* bitmap of masked signals */
unsigned long flags; /* per process flags, defined below */
int errno;
long debugreg[8]; /* Hardware debugging registers */
struct exec_domain *exec_domain;
/* various fields */
struct linux_binfmt *binfmt;
struct task_struct *next_task, *prev_task;
struct task_struct *next_run, *prev_run;
unsigned long saved_kernel_stack;
unsigned long kernel_stack_page;
int exit_code, exit_signal;
/* ??? */
unsigned long personality;
int dumpable:1;
int did_exec:1;
int pid;
int pgrp;
int tty_old_pgrp;
int session;
/* boolean value for session group leader */
int leader;
int groups[NGROUPS];
/*
* pointers to (original) parent process, youngest child, younger sibling,
* older sibling, respectively. (p->father can be replaced with
* p->p_pptr->pid)
*/
struct task_struct *p_opptr, *p_pptr, *p_cptr,
*p_ysptr, *p_osptr;
struct wait_queue *wait_chldexit;
unsigned short uid,euid,suid,fsuid;
unsigned short gid,egid,sgid,fsgid;
unsigned long timeout, policy, rt_priority;
unsigned long it_real_value, it_prof_value, it_virt_value;
unsigned long it_real_incr, it_prof_incr, it_virt_incr;
struct timer_list real_timer;
long utime, stime, cutime, cstime, start_time;
/* mm fault and swap info: this can arguably be seen as either
mm-specific or thread-specific */
unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
int swappable:1;
unsigned long swap_address;
unsigned long old_maj_flt; /* old value of maj_flt */
unsigned long dec_flt; /* page fault count of the last time */
unsigned long swap_cnt; /* number of pages to swap on next pass */
/* limits */
struct rlimit rlim[RLIM_NLIMITS];
unsigned short used_math;
char comm[16];
/* file system info */
int link_count;
struct tty_struct *tty; /* NULL if no tty */
/* ipc stuff */
struct sem_undo *semundo;
struct sem_queue *semsleeping;
/* ldt for this task – used by Wine. If NULL, default_ldt is used */
struct desc_struct *ldt;
/* tss for this task */
struct thread_struct tss;
/* filesystem information */
struct fs_struct *fs;
/* open file information */
struct files_struct *files;
/* memory management info */
struct mm_struct *mm;
/* signal handlers */
struct signal_struct *sig;
#ifdef __SMP__
int processor;
int last_processor;
int lock_depth; /* Lock depth.
We can context switch in and out
of holding a syscall kernel lock… */
#endif
};
timer_list

timer_list data structure’s are used to implement real time timers for processes.
struct timer_list {
struct timer_list *next;
struct timer_list *prev;
unsigned long expires;
unsigned long data;
void (*function)(unsigned long);
};
tq_struct

Each task queue (tq_struct) data structure holds information about work that has been queued. This is usually a task needed by a device driver but which does not have to be done immediately.
struct tq_struct {
struct tq_struct *next; /* linked list of active bh’s */
int sync; /* must be initialized to zero */
void (*routine)(void *); /* function to call */
void *data; /* argument to function */
};
vm_area_struct

Each vm_area_struct data structure describes an area of virtual memory for a process.
struct vm_area_struct {
struct mm_struct * vm_mm; /* VM area parameters */
unsigned long vm_start;
unsigned long vm_end;
pgprot_t vm_page_prot;
unsigned short vm_flags;
/* AVL tree of VM areas per task, sorted by address */
short vm_avl_height;
struct vm_area_struct * vm_avl_left;
struct vm_area_struct * vm_avl_right;
/* linked list of VM areas per task, sorted by address */
struct vm_area_struct * vm_next;
/* for areas with inode, the circular list inode->i_mmap */
/* for shm areas, the circular list of attaches */
/* otherwise unused */
struct vm_area_struct * vm_next_share;
struct vm_area_struct * vm_prev_share;
/* more */
struct vm_operations_struct * vm_ops;
unsigned long vm_offset;
struct inode * vm_inode;
unsigned long vm_pte; /* shared mem */
};

Posted in Uncategorized | Leave a comment

How the Command Line Parsing Works

How the Command Line Parsing Works
There are two different command line parsers available with U-Boot: the old “simple” one, and the much more powerful “hush” shell:

Old, simple command line parser
supports environment variables (through setenv / saveenv commands)
several commands on one line, separated by ‘;’

variable substitution using “… ${_variablename_} …” syntax
ALERT! NOTE: Older versions of U-Boot used “$(…)” for variable substitution. Support for this syntax is still present in current versions, but will be removed soon. Please use “${…}” instead, which has the additional benefit that your environment definitions are compatible with the Hush shell, too.
special characters (‘$’, ‘;’) can be escaped by prefixing with ‘\’, for example:
setenv bootcmd bootm \${address}
You can also escape text by enclosing in single apostrophes, for example:
setenv addip ‘setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off’

Hush shell

similar to Bourne shell, with control structures like if…then…else…fi, for…do…done, while…do…done, until…do…done, …
supports environment (“global”) variables (through setenv / saveenv commands) and local shell variables (through standard shell syntax name=value ); only environment variables can be used with the run command, especially as the variable to run (i. e. the first argument).
In the current implementation, the local variables space and global environment variables space are separated. Local variables are those you define by simply typing like name=value. To access a local variable later on, you have to write ‘$name’ or ‘${name}’; to execute the contents of a variable directly you can type ‘$name’ at the command prompt. Note that local variables can only be used for simple commands, not for compound commands etc.
Global environment variables are those you can set and print using setenv and printenv. To run a command stored in such a variable, you need to use the run command, and you must not use the ‘$’ sign to access them.
To store commands and special characters in a variable, use single quotation marks surrounding the whole text of the variable, instead of the backslashes before semicolons and special symbols.
Be careful when using the hash (‘#’) character – like with a “real” Bourne shell it is the comment character, so you have to escape it when you use it in the value of a variable.
Examples:

setenv bootcmd bootm \$address
setenv addip ‘setenv bootargs $bootargs ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off’

Hush shell scripts
Here are a few examples for the use of the advanced capabilities of the hush shell in U-Boot environment variables or scripts:

Example:

=> setenv check ‘if imi $addr; then echo Image OK; else echo Image corrupted!!; fi’
=> print check
check=if imi $addr; then echo Image OK; else echo Image corrupted!!; fi
=> addr=0 ; run check

## Checking Image at 00000000 …
Bad Magic Number
Image corrupted!!
=> addr=40000 ;run check

## Checking Image at 00040000 …
Image Name: ARM Linux-2.4.18
Created: 2003-06-02 14:10:54 UTC
Image Type: ARM Linux Kernel Image (gzip compressed)
Data Size: 801609 Bytes = 782.8 kB
Load Address: 0c008000
Entry Point: 0c008000
Verifying Checksum … OK
Image OK
Instead of “echo Image OK” there could be a command (sequence) to boot or otherwise deal with the correct image; instead of the “echo Image corrupted!!” there could be a command (sequence) to (load and) boot an alternative image, etc.

Example:

=> addr1=0
=> addr2=10
=> bootm $addr1 || bootm $addr2 || tftpboot $loadaddr $loadfile && bootm
## Booting image at 00000000 …
Bad Magic Number
## Booting image at 00000010 …
Bad Magic Number
TFTP from server 192.168.3.1; our IP address is 192.168.3.68
Filename ‘/tftpboot/TRAB/uImage’.
Load address: 0xc400000
Loading: #################################################################
#################################################################
###########################
done
Bytes transferred = 801673 (c3b89 hex)
## Booting image at 0c400000 …
Image Name: ARM Linux-2.4.18
This will check if the image at (flash?) address “addr1″ is ok and boot it; if the image is not ok, the alternative image at address “addr2″ will be checked and booted if it is found to be OK. If both images are missing or corrupted, a new image will be loaded over TFTP and booted.
14.2.17.4. General rules
If a command line (or an environment variable executed by a run command) contains several commands separated by semicolons, and one of these commands fails, the remaining commands will still be executed.
If you execute several variables with one call to run (i. e. calling run with a list of variables as arguments), any failing command will cause run to terminate, i. e. the remaining variables are not executed.

Posted in Uncategorized | Leave a comment

U-Boot Standalone Applications

U-Boot Standalone Applications
U-Boot supports “standalone” applications, which are loaded dynamically; these applications can have access to the U-Boot console I/O functions, memory allocation and interrupt services.

A couple of simple examples are included with the U-Boot source code:

5.12.1. “Hello World” Demo
examples/hello_world.c contains a small “Hello World” Demo application; it is automatically compiled when you build U-Boot. It’s configured to run at address 0×00040000, so you can play with it like that:

TIP Note that the entry point of the program is at 0×40000 for the PowerPC architecture. It may be different for other architectures. See the CONFIG_STANDALONE_LOAD_ADDR define in your U-Boot tree if problems are encountered.

=> loads
## Ready for S-Record download …
~>examples/hello_world.srec
1 2 3 4 5 6 7 8 9 10 11 …
[file transfer complete]
[connected]
## Start Addr = 0×00040000

=> go 40000 Hello World! This is a test.
## Starting application at 0×00040000 …
Hello World
argc = 7
argv[0] = “40000″
argv[1] = “Hello”
argv[2] = “World!”
argv[3] = “This”
argv[4] = “is”
argv[5] = “a”
argv[6] = “test.”
argv[7] = “”
Hit any key to exit …

## Application terminated, rc = 0×0
Alternatively, you can of course use TFTP to download the image over the network. In this case the binary image (hello_world.bin) is used.

=> tftp 40000 /tftpboot/hello_world.bin

=> go 40000 This is another test.
## Starting application at 0×00040000 …
Hello World
argc = 5
argv[0] = “40000″
argv[1] = “This”
argv[2] = “is”
argv[3] = “another”
argv[4] = “test.”
argv[5] = “”
Hit any key to exit …

## Application terminated, rc = 0×0
5.12.2. Timer Demo
ALERT! This example is only available on MPC8xx CPUs.

TIP This example, which demonstrates how to register a CPM interrupt handler with the U-Boot code, can be found in examples/timer.c. Here, a CPM timer is set up to generate an interrupt every second. The interrupt service routine is trivial, just printing a ‘.’ character, but this is just a demo program. The application can be controlled by the following keys:

? – print current values of the CPM Timer registers
b – enable interrupts and start timer
e – stop timer and disable interrupts
q – quit application

=> loads
## Ready for S-Record download …
~>examples/timer.srec
1 2 3 4 5 6 7 8 9 10 11 …
[file transfer complete]
[connected]
## Start Addr = 0×00040000

=> go 40000
## Starting application at 0×00040000 …
TIMERS=0xfff00980
Using timer 1
tgcr @ 0xfff00980, tmr @ 0xfff00990, trr @ 0xfff00994, tcr @ 0xfff00998, tcn @ 0xfff0099c, ter @ 0xfff009b0

Hit ‘b’:
[q, b, e, ?] Set interval 1000000 us
Enabling timer
Hit ‘?’:
[q, b, e, ?] ……..
tgcr=0×1, tmr=0xff1c, trr=0x3d09, tcr=0×0, tcn=0xef6, ter=0×0
Hit ‘?’:
[q, b, e, ?] .
tgcr=0×1, tmr=0xff1c, trr=0x3d09, tcr=0×0, tcn=0x2ad4, ter=0×0
Hit ‘?’:
[q, b, e, ?] .
tgcr=0×1, tmr=0xff1c, trr=0x3d09, tcr=0×0, tcn=0x1efc, ter=0×0
Hit ‘?’:
[q, b, e, ?] .
tgcr=0×1, tmr=0xff1c, trr=0x3d09, tcr=0×0, tcn=0x169d, ter=0×0
Hit ‘e’:
[q, b, e, ?] …Stopping timer
Hit ‘q’:
[q, b, e, ?] ## Application terminated, rc = 0×0
5.12.3. Processor cache considerations
Some processors have data and/or instruction caches. For some of these processors (e.g. MPC85xx), the operation of the cache(s) must be considered whenever data transferred to RAM is later executed as instructions. For these processors, data transferred to RAM might not be be represented correctly in the instruction cache without special treatment. This could result in incorrect execution of that data when it is considered an instruction stream. Multi core and multi processor systems with caches can also show this erroneous behaviour. To avoid this extremely difficult to debug type of problem, any instruction stream transferred to RAM as data should be flushed from any enabled data cache and the corresponding part of any enabled instruction cache should be invalidated.

In the “Hello World” example previously shown, the example program might be transferred to RAM by TFTP and then executed with the go command. While this procedure may work in most situations, it makes no provisions for cache behaviour as was just discussed. That is, obviously, there is no explicit cache management, nor does the go command do any cache management. This leaves open the possibility of malfunction.

The bootm command, which is normally used to start Linux, does implement the required cache flushes and invalidations, in ways that are appropriate for the particular processor.

To prepare an image of the “Hello World” example that is appropriate for the bootm command, the IMG target in the Makefile will wrap the executable in the appropriate U-Boot image header. An example addition to the Makefile might look like

IMG = $(BOARD)_standalone.img
IMG := $(addprefix $(obj),$(IMG))
$(IMG):
$(obj)%.img: $(BIN)
$(MKIMAGE) -n “Hello stand alone” -A ppc -O u-boot -T standalone -C none -a $(LOAD_ADDR) -d $(BIN) -v $@
With this preparatory step added to the Makefile, the previously given “Hello World” console output example becomes

=> tftp 600000 helloworld.img

=> bootm 600000 Hello World! This is a test.
WARNING: adjusting available memory to 30000000
## Booting kernel from Legacy Image at 600000 …
Image Name: Hello stand alone
Image Type: PowerPC U-Boot Standalone Program (uncompressed)
Data Size: 25391 Bytes = 24.8 KiB
Load Address: 00040000
Entry Point: 00040000
Verifying Checksum … OK
Hello World
argc = 7
argv[0] = “600000″
argv[1] = “Hello”
argv[2] = “World!”
argv[3] = “This”
argv[4] = “is”
argv[5] = “a”
argv[6] = “test.”
argv[7] = “”
Hit any key to exit …

=>
Of course, more is done by bootm in this example than is done by go in the original example. This additional work requires additional time, which may, or may not, be significant in any particular situation.

5.12.4. Running on core other than core 0
For Freescale PowerPC-based multi-core system, the following can be said.

U-Boot facilities are not available to stand alone applications, since U-Boot runs only on core 0

From Scott Wood ():

If you have true standalone code, you can release it on other CPUs using the
“cpu release” command. That code will not have access to any U-Boot
functionality. Its entry state will be as described for secondary CPUs in [the]
ePAPR [specification]. It will be the same as if an OS were spinning up its
secondary cores by writing directly to the spin table.
The ePAPR specification can be found at https://www.power.org/documentation/epapr-version-1-1/.

This implies that use of the normal stand alone stubs (e.g. stdio, I2C) will not work for stand alone applications running on any core other than core 0.

Posted in Uncategorized | Leave a comment

The Universal Boot Loader (“Das U-Boot”)

The Universal Boot Loader (“Das U-Boot”)
Table of contents:
1. Abstract
? 1.1. Introduction
? 1.2. History
? 1.3. Supported Hardware
? 1.4. Design Principles
? 1.5. User Interface
? 1.6. Basic Command Set
1.7. Advanced Commands
? 1.7.1. Logbuffer Manipulation Commands
? 1.7.2. Bedbug Embedded Debugger Commands
? 1.7.3. POST – Hardware Diagnose Commands
?
? 1.8. Environment Variables
? 1.9. Boot Options
? 1.10. Command Interpreters
? 1.11. Standalone Programs
1.12. Special Features
? 1.12.1. Bitmap and Splash Screen Support
? 1.12.2. Boot Count Limit
? 1.12.3. Keyboard Support
? 1.12.4. Automatic Updates

1.1. Introduction
• The “Universal Bootloader” (“Das U-Boot”) is a monitor program.
• Free Software: full source code under GPL
• hosted on SourceForge: http://sourceforge.net/projects/u-boot
• production quality: used as default boot loader by several board vendors
• portable and easy to port and to debug
• many supported architectures: PPC, ARM, MIPS, x86, m68k, NIOS, Microblaze
• more than 216 boards supported by public source tree
• many, many features
1.1. Introduction 1
1.2. History
• Oct 22, 1999: fadsrom – Dan Malek => PPCBoot rev. 1.1
• Dec 18, 1999: 8xxrom-0.3.0 – Magnus Damm, Raphael Bossek => PPCBoot rev. 1.2
• Jul 07, 2000: Wolfgang Denk => PPCBoot rev. 1.3
Jul 19, 2000: Wolfgang Denk => PPCBoot-0.4.1
first public version of PPCBoot

Siemens PSE, Vienna: Development of a Bluetooth LAN Access Point with a MPC850 Processor that
needed to be able to boot over Ethernet => first commercial sponsor

Aug 08, 2000: PPCBoot rev. 1.4 = PPCBoot-0.4.2
(only PPC, only MPC8xx, 4 boards)

• Oct 01, 2000: added network support => PPCBoot-0.4.4
• Oct 01, 2000: Stefan Roese: add support for IBM PPC401/403/405GP processors => PPCBoot-0.5.1
• Nov 16, 2000: Murray Jensen: add support for MPC8260 => PPCBoot-0.6.2
• Nov 20, 2000: Rob Taylor: add support for MPC8240 => PPCBoot-0.6.3
• End 2000: PPCBoot-0.7.1 (MPC8xx, MPC8240, MPC8260, PPC401/403/405GP; 27 boards)
• End 2001: PPCBoot-1.1.3 (MPC8xx, MPC8240, MPC8260, 7xx, 74xx, IBM 4xx, 63 boards)
• Mar 2002: SYSGO: split ARMBoot project, separate (incompatible) source tree
• Jul 2002: begin merging with ARMBoot tree
Nov 2002: PPCBoot-2.0.0 (last release of PPCBoot)
(PPC: 8xx, 824x, 826x, 7xx, 74xx, 4xx; ARM: StrongARM, ARM7, ARM9, XScale; >106 boards)
=> Start U-Boot project: PPCBoot-2.0.0 = U-Boot-0.1.0

• Nov 2002: x86 support
• Mar 2003: MIPS32
• Apr 2003: MIPS64
• Oct 2003: Altera NIOS-32
• Dec 2003: Coldfire
• Apr 2004: Microblaze
today (31 May 2004): U-Boot-1.1.2
(PPC: 5xx, 5xxx, 8xx, 824x, 826x, 85xx, 7xx, 74xx, 4xx;
ARM: StrongARM, ARM720T, ARM92xT, S3C44B0, AT91RM9200, XScale;
x86: SC520; m68k: Coldfire; MIPS32: 4Kc, Au1x00; MIPS64: 5Kc; NIOS32; Microblaze;
>216 boards in public tree; many more not submitted back

• several board manufacturers use U-Boot as default firmware on some or all of their boards
1.3. Supported Hardware
Architecture Processor Number of Boards
PPC 5xx 2
5xxx 6
8xx 71
824x 15
826x 26
85xx 3
1.3. Supported Hardware 2
7xx/74xx 11
4xx 38
ARM StrongARM 5
ARM720T 3
ARM92xT 11
S3C44B0 1
AT91RM9200 1
XScale 8
x86 SC520 2
m68k Coldfire 2
MIPS32 4Kc 2
Au1x00 3
MIPS64 5Kc 1
NIOS32 3
Microblaze 1
Blackfin BF5xx 18
1.4. Design Principles
• easy to port to new architectures, new processors, and new boards
• easy to debug: serial console output as soon as possible
• features and commands configurable
• as small as possible
• as reliable as possible
1.5. User Interface
U-Boot uses a simple command line interface (CLI), usually over a serial console port.
Two different command interpreters are available:
• simple CLI
• Bourne compatible shell (HUSH shell from Busybox)
Configuration parameters and commands / command sequences (scripts !) can be stored in “environment
variables” which can be saved to non-volatile storage (flash, EEPROM, NVRAM, etc.)
1.5. User Interface 3
1.6. Basic Command Set
Information Commands
? bdinfo – print Board Info structure
? coninfo – print console devices and informations
? flinfo – print FLASH memory information
? iminfo – print header information for application image
? imls – list all images found in flash
? help – print online help

Memory Commands
? base – print or set address offset
? crc32 – checksum calculation
? cmp – memory compare
? cp – memory copy
? md – memory display
? mm – memory modify (auto-incrementing)
? mtest – simple RAM test
? mw – memory write (fill)
? nm – memory modify (constant address)
? loop – infinite loop on address range

Flash Memory Commands
? cp – memory copy (program flash)
? flinfo – print FLASH memory information
? erase – erase FLASH memory
? protect – enable or disable FLASH write protection

Execution Control Commands
? autoscr – run script from memory
? bootm – boot application image from memory
? bootelf – Boot from an ELF image in memory
? bootvx – Boot vxWorks from an ELF image
? go – start application at address ‘addr’

Network Commands
? bootp – boot image via network using BOOTP/TFTP protocol
? cdp – Perform Cisco Discovery Protocol network configuration
? dhcp – invoke DHCP client to obtain IP/boot params
? loadb – load binary file over serial line (kermit mode)
? loads – load S-Record file over serial line
? nfs – boot image via network using NFS protocol
? ping – send ICMP ECHO_REQUEST to network host
? rarpboot- boot image via network using RARP/TFTP protocol
? tftpboot- boot image via network using TFTP protocol

Environment Variables Commands
? printenv- print environment variables
? saveenv – save environment variables to persistent storage
? askenv – get environment variables from stdin
? setenv – set environment variables
? run – run commands in an environment variable
? bootd – boot default, i.e., run ‘bootcmd’

Filesystem Support (FAT, cramfs, JFFS2, Reiser)
? chpart – change active partition

1.6. Basic Command Set 4
? fsinfo – print information about filesystems
? fsload – load binary file from a filesystem image
? ls – list files in a directory (default /)
? fatinfo – print information about filesystem
? fatls – list files in a directory (default /)
? fatload – load binary file from a dos filesystem
? nand – NAND flash sub-system
? reiserls- list files in a directory (default /)
? reiserload- load binary file from a Reiser filesystem
Special Commands
? i2c – I2C sub-system
? doc – Disk-On-Chip sub-system
? dtt – Digital Thermometer and Themostat
? eeprom – EEPROM sub-syste
? fpga – FPGA sub-system
? ide – IDE sub-system
? kgdb – enter gdb remote debug mode
? diskboot- boot from IDE device
? icache – enable or disable instruction cache
? dcache – enable or disable data cache
? diag – perform board diagnostics (POST code)
? log – manipulate logbuffer
? pci – list and access PCI Configuraton Space
? regdump – register dump commands
? usb – USB sub-system
? sspi – SPI utility commands

Miscellaneous Commands
? bmp – manipulate BMP image data
? date – get/set/reset date & time
? echo – echo args to console
? exit – exit script
? kbd – read keyboard status
? in – read data from an IO port
? out – write datum to IO port
? reset – Perform RESET of the CPU
? sleep – delay execution for some time
? test – minimal test like /bin/sh
? version – print monitor version
? wd – check and set watchdog
? ? – alias for ‘help’

1.7. Advanced Commands
Some of the following commands depend on certain hardware features and may not be available on all boards.
1.7. Advanced Commands 5
1.7.1. Logbuffer Manipulation Commands
Use a reserved area of system memory as log buffer;
can be re-used by syslogd in Linux;
content will survive reset / warm boot
• log info – show pointer details
• log log reset – clear contents
• log log show – show contents
• log log append – append to the logbuffer
• setenv stdout log – redirect standard output to log buffer
Used for example to pass POST results to Linux application code or for post-mortem checking of the Linux
system logs.
1.7.2. Bedbug Embedded Debugger Commands
• ds – disassemble memory
• as – assemble memory
• break – set or clear a breakpoint
• continue – continue from a breakpoint
• step – single step execution.
• next – single step execution, stepping over subroutines.
• where – Print the running stack.
• rdump – Show registers.
1.7.3. POST – Hardware Diagnose Commands
• cache – Cache test
• watchdog – Watchdog timer test
• i2c – I2C test
• rtc – RTC test
• memory – Memory test
• cpu – CPU test
• uart – UART test
• ethernet – ETHERNET test
• spi – SPI test
• usb – USB test
• spr – Special register test
• sysmon – SYSMON test
• dsp – DSP test
1.8. Environment Variables
Environment Variables (EV) can be used to configure the system and to store parameters for commands, and
1.8. Environment Variables 6
even commands and sequences of commands (simple scripts).
Board Configuration
baudrate, ethaddr, serial#, cpuclk

Startup Behaviour
bootdelay, bootcmd

Network Parameters
ipaddr, serverip, gatewayip, dnsip, netmask, hostname, rootpath, bootfile

Misc
autoload (network lookup without download); autostart (start downloaded image); pram
(reserve “protected RAM” area); silent (supress console messages); verify (disable CRC32
checks); …

User Defined
=> setenv name word1 word2 word3
=> saveenv

The real power of EVs results from the fact that Unix shell like variable expansion is available. For example:
=> setenv ipaddr 192.168.3.71
=> setenv serverip 192.168.3.1
=> setenv netdev eth0
=> setenv hostname testbox
=> setenv rootpath /opt/eldk/ppc_8xx
=> setenv ramargs setenv bootargs root=/dev/ram rw
=> setenv nfsargs ‘setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath}’
=> setenv addip ‘setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off’
=> setenv kernel_addr 40040000
=> setenv ramdisk_addr 40100000
=> setenv flash_ram ‘run ramargs addip;bootm ${kernel_addr} ${ramdisk_addr}’
=> setenv flash_nfs ‘run nfsargs addip;bootm ${kernel_addr}’
=> setenv net_nfs ‘tftp 200000 ${bootfile};run nfsargs addip;bootm’
=> setenv net_ram ‘tftp 200000 ${bootfile};run ramargs addip;bootm 200000 ${ramdisk_addr}’
Boot Kernel Image in flash with ramdisk in flash:
=> run flash_ram
Boot Kernel Image in flash with root filesystem over NFS:
=> run flash_nfs
Download Kernel Image over network and use root filesystem over NFS:
=> run net_nfs
Download Kernel Image over network with ramdisk in flash:
=> run net_ram
Step by step:
=> run flash_nfs
1.8. Environment Variables 7
Step Action Result in bootargs
run
nfsargs
setenv bootargs root=/dev/nfs rw
nfsroot=${serverip}:${rootpath}
root=/dev/nfs rw
nfsroot=192.168.3.1:/opt/eldk/ppc_8xx
run addip
setenv bootargs ${bootargs}
ip=${ipaddr}:${serverip}:\
${gatewayip}:${netmask}:\
${hostname:${netdev}:off
root=/dev/nfs rw
nfsroot=192.168.3.1:/opt/eldk/ppc_8xx
ip=192.168.3.71:192.168.3.1:::\
testbox:eth0:off
bootm
40040000 boot Linux kernel
Example: simple recovery strategy:
=> setenv bootcmd ‘run flash_ram; setenv kernel_addr ${alt_kernel}; run flash_ram; run net_ram’
1.9. Boot Options
U-Boot supports many different ways to load and boot an image.
Basic command:
“bootm” – Boot Image in memory (RAM, flash)
Image:
Header + Payload
Header:
? Creation Timestamp
? Data Load Address
? Entry Point Address
? Data CRC Checksum
? Operating System
? CPU architecture
? Image Type
? Compression Type
? Image Name
Actions:
? test CPU architecture and OS
? test checksum (optional)
? if compressed, uncompress
? copy to load address
? prepare boot arguments
? start at entry point
Load image in memory:
? Serial Port: “loads” (S-Record), “loadb” (Kermit binary protocol)
1.9. Boot Options 8
? Ethernet: “tftp”, “bootp”, “dhcp”, “nfs”, …
? Harddisk, CDROM: “ide read”
? CompactFlash card etc.: “ide read”
? USB Mass Storage Device: “usb read”
? SCSI Disk and CDROM: “scsi read”
? NAND flash with JFFS2 filesystem: “nboot”
? Disk on Chip: “doc read”
? PCI Bus: copy
? …
Supported Filesystems (read-only):
? FAT
? Reiser
? JFFS2
1.10. Command Interpreters
Two command line interfaces:
Simple (old) command interpreter:
? sequential statements
? statements separated by newline or ‘;’
no conditional execution except simple builtin rules:
“run cmd1; run cmd2; run cmd3″
will always run all three commands
?
“run cmd1 cmd2 cmd3″
will stop when a command fails
?
?
? “scripts” (canned sequences of commands) avaialble using “autoscr” command

Hush Shell (from Busybox, see http://www.busybox.net/):
? Bourne Shell compatible
(local) shell variables (“name=val”), (global) environment variables (“setenv name
val”)
?
? Conditionals: “if … then … else … fi”
Control loops: “for … do … done”, “while … do done”, “until …
do … done”
?
? Control operators: && and || (AND and OR lists: “command1 && command2″)
? real shell scripts
? no functions
? no command substitution
? no backquotes

1.11. Standalone Programs
1.11. Standalone Programs 9
U-Boot can dynamically load independent software modules, called “standalone programs”. Standalone
programs have a standard C calling environment, and can use standard services like printf(), malloc(),
install_hdlr().
Used for:
• special test software that is used in bring-up but shall not be included with customer release
• software that is needed only occasionally
• code that performs special actions that were not foreseen (software updates)
• code that shall not be made available under GPL
Example:
#include
#include
int hello_world (int argc, char *argv[])
{
int i;
app_startup(argv);
printf (“Example expects ABI version %d\n”, XF_VERSION);
printf (“Actual U-Boot ABI version %d\n”, (int)get_version());
printf (“Hello World\n”);
printf (“argc = %d\n”, argc);
for (i=0; i<=argc; ++i) {
printf ("argv[%d] = \"%s\"\n",
i,
argv[i] ? argv[i] : "”);
}
return (0);
}
Run:
=> tftp 40000 /tftpboot/hello_world.bin

=> go 40004 Hello World! This is a test.
## Starting application at 0×00040004 …
Hello World
argc = 7
argv[0] = “40004″
argv[1] = “Hello”
argv[2] = “World!”
argv[3] = “This”
argv[4] = “is”
argv[5] = “a”
argv[6] = “test.”
argv[7] = “”
## Application terminated, rc = 0×0
1.12. Special Features
• Bitmap and Splash Screen Support
• Boot Count Limit
• Keyboard Support
1.12. Special Features 10
• Automatic Updates
1.12.1. Bitmap and Splash Screen Support
Problem: booting Linux and starting a GUI takes a couple of seconds, but the user expects to see something
“immediately” after power-on.
Solution: display a static splash screen as soon as possible; available commands:
• bmp info – print Bitmap info
• bmp display – display bitmap image on screen
• setenv splashimage addr – display spash screen image at address addr
1.12.2. Boot Count Limit
The Open Source Development Labs Carrier Grade Linux Requirements Definition says:
CGL shall provide support for detecting a repeating reboot cycle due to recurring failures and will go to an
offline state if this occurs.
U-Boot allows to run an arbitrary command in such a case:
• bootcount (EV) – number of reboots since power-on
• bootlimit (EV) – maximum number of reboot cycles
• altbootcmd (EV) – alternate boot action
1.12.3. Keyboard Support
Problem: make system behaviour dependent on keys pressed at power-on
Solution: in U-Boot you can define one or more keys or key combinations and commands which are executed
when these keys are pressed at power-on:
“magic_keys” (EV) – List of characters for keys; for example:
=> setenv magic_keys 0123CB*

“key_magic_?_” (EV) – Key code or list of key codes for this action; scanned in the order as
listed in magic_keys; for example:
=> setenv key_magic0 3a+3b
=> setenv key_magic1 3c
=> setenv key_magic2 4a
=> setenv key_magic3 4c+51
=> setenv key_magicC 3a+4a+5a
=> setenv key_magicB 52+53
=> setenv key_magic* 55+56

• “key_cmd?” (EV) – Action to be performed when corresponding key(s) are pressed; for example:
1.12.3. Keyboard Support 11
=> setenv key_cmd0 setenv bootdelay 10
=> setenv key_cmd1 setenv addcons ‘console=ttyS0,${baudrate}’
=> setenv key_cmd2 setenv memtest on
=> setenv key_cmd3 setenv bootcmd run old_version
=> setenv key_cmdC setenv bootcmd run recovery
=> setenv key_cmdB setenv bootcmd run usb_update
=> setenv key_cmd* setenv bootcmd run demo_mode
Example: after a software update, the user can select to boot the old software version (“run old_version”) by
holding the keys with keycodes “4c” and “51″ at power-on.
1.12.4. Automatic Updates
Problem:
Distribute Software Updates to customers
Solution:
use cheap standard media like USB memory sticks
Implementation:
• Keep BOM (Versions, Timestamps etc.) in persistent memory (EEPROM etc.)
• When booting, check whether a USB memory stick is plugged in.
If one is found:
If prepare.img is found load it into memory.
If it is valid then run it (always).
1.
If preinst.img is found load it into memory.
If it is valid then run it. Update the EEPROM.
2.
If firmware.img is found load it into memory.
If it is valid, burn it into FLASH and update the EEPROM.
3.
If kernel.img is found load it into memory.
If it is valid, burn it into FLASH and update the EEPROM.
4.
If app.img is found load it into memory.
If it is valid, burn it into FLASH and update the EEPROM.
5.
If disk.img is found load it into memory.
If it is valid, burn it into FLASH and update the EEPROM.
6.
If postinst.img is found load it into memory.
If it is valid then run it. Update the EEPROM.
7.

1.13. Resources, Summary
Resources:
• The U-Boot project is hosted at Sourceforge: http://sourceforge.net/projects/u-boot
• Tarballs can be found either at sourceforge.net or at the DENX ftp server.
• There is a pretty active u-boot-users mailing list.
The Mailing list archive can be viewed at sourceforge.net (if it works – it is regularly broken, so don’t
get discouraged and try again later).

The DENX U-Boot and Linux Guide is a Wiki based documentation documenting U-Boot and its
interaction with Linux. It can be viewed (and improved) at www.denx.de. The whole DULG web

1.13. Resources, Summary 12
packed into a single HTML page or a PDF file is also available (TQM8xxL version, i.e. PowerPC
based).
• The current README file can be viewed through viewcvs at sourceforge.net
Sample configuration files for the Abatron BDI2000 debugger are available at the FTP Server at
DENX.

• Even more useful links can be found in the DENX Training wiki documentation at www.denx.de.
Summary:
• U-Boot is a very active community project.
It lives from the spritit of Free Software. It would be impossible without the numberless contributions
of other developers.

1.13. Resources, Summary 13

Posted in Uncategorized | Leave a comment

Tricky C interview questions

1.Give a fastest way to multiply any number by 9.
Answer:
#include
#include
void main()
{
int n;
printf(“Enter a number:”);
scanf(“%d”,&n);
printf(“%d”, (n<<3)+n);
getch();
}
2. How to measure the size of any variable without “sizeof” operator?
Answer:
#define size_of(x) ((char *)(&x+1) – (char *)&x)
void main()
{
Short int x;
Printf(“%d”,size_of(x));
}

Explanation:
By using the &x, we get the base address of the variable x and by adding 1 to it we get the base address of next short int type. Hence the resulting address of (&x+1) will be 2 bytes more than the base address of the variable x. But if we just display the difference between the base address of x and the incremented address, then the difference will be ‘1’, means “1 block of short int type has been added” but we need the result of size of variable in terms of bytes not in terms of blocks. This can be achieved if we typecast the address into char *, because the address of char data type will always be in block of one byte, hence if the difference between the base address of x and the incremented address is displayed in terms of char type, then the difference will be displayed as 2, because the difference is actually 2 blocks or 2 bytes in terms of char type representation.

3. How to measure the size of any variable without using “sizeof” operator?
Answer:
#define SIZE_OF(T) (((T *)0)+1)
void main()
{
clrscr();
printf(“%d”,SIZE_OF(long int));
}

Explanation:

Whenever we typecast any constant, it converts the constants into a base address of specified data type and as we know (address+1) will always return the next address of its type or we can say the address of next block of memory of that type, so accordingly if 1 will be added with the address ‘0’, then it will return the size of any data type in bytes. For example 1 for char, 2 for short int, 4 for long int or float and so on.

4. Write code snippets to swap two variables in five different ways.
Answer:
a. /* swapping using three variables*/ (Takes extra memory space)
Int a=5, b=10, c;
c=a;
a=b;
b=c;

b. /* using arithmetic operators */
a=a+b;
b=a-b;
a=a-b;

c. /* using bit-wise operators */
a=a^b;
b=b^a;
a=a^b;

Line
Operation
Value of a
Value of b

1
-
5
10
Initial values
2
a=a^b
15
10

3
b=a^a
15
5

4
a=a^b
10
5
values after swapping

d. /* one line statement using bit-wise operators */ (most efficient)
a^=b^=a^=b;

The order of evaluation is from right to left. This is same as in approach (c) but the three statements are compounded into one statement.

e. /* one line statement using arithmetic & assignment operators */
a=(a+b) – (b=a);
In the above axample, parenthesis operator enjoys the highest priority & the order of evaluation is from left to right. Hence (a+b) is evaluated first and replaced with 15. Then (b=a) is evaluated and the value of a is assigned to b, which is 5. Finally a is replaced with 15-5, i.e. 10. Now the two numbers are swapped.

5. How to swap between first & 2nd byte of an integer in one line statement?
Answer:
int x=0×1234;
x = x<>8;

Explanation:
Let x = 0×1234

x = 00010010 00110100
x<>8 = 00000000 00010010
x<>8 = 00110100 00010010 i.e. value of ‘x’ after swap is 0×3412

6. What is the efficient way to divide a no. by 4?
Answer:
x = x>>2;

7. Suggest an efficient method to count the no. of 1’s in a 32 bit no. Remember without using loop & testing each bit.
Answer:
(i) int count_set_bits (long n)
{
int count = 0;
while (n)
{
count ++;
n & = n-1;
}
return (count);
}
(ii) int count_set_bits (long n)
{
return (n ? 1+ count_set_bits (n&n-1) : 0);
}

Explanation:

The logic is that the while loop continues as long as there are set bits (1) in the no. If all the bits became 0, that means no. is ‘0’ & the loop terminates. The logic needs conversion of every 1 to 0, which can be achieved by making a bitwise ‘&’ operation between the no. (n) and its previous no. (n-1) and assigning the resulting value back to n. If this is done, then with every run of the loop each set bit (1) will be reset. ( i.e. converted to 0).
Let n= 30
30 = 00011110
29 = 00011101
(30 & 29) = 00011100

We can see that the 2nd bit of 30 is reset to 0 which gives the no 28 which is now assigned to n (n &=n-1). This step is repeated until n becomes ‘0’.

8. Test whether a no. is power of 2 or not.
Answer:
void main ()
{
int n;
printf (“\n Enter any no:”);
scanf (“%d”, & n);
if (n & & ((n & n-1) = = 0))
printf (“It is power of 2”);
else
printf (“It is not power of 2”);
}
Test:
Enter any no: 32
It is power of 2

Enter any no: 56
It is not power of 2

Explanation:

The logic says that if a no. is power of 2, then in the binary representation, only one bit of the no. can be ‘1’ & rest are must be ‘0’.
For example the number 32 has a binary representation of 00100000.

9. How to check endianness of the computer.

Answer:
Logic-1
void main ()
{
int x = 300;
if ((* ((unsigned char *) & x) == 1)
&& (*(unsigned char*) & x+1) == 44))
printf (“BIG ENDIAN”);
else
printf (“LITTLE ENDIAN”);
}

Logic-2
void main ()
{
union xxx
{
unsigned int x;
unsigned char ch[2];
};
union xxx p = {300};
if ((p.ch [0] = = 1) && (p. ch [1] == 44))
printf (“BIG ENDIAN”);
else
printf (“LITTLE ENDIAN”);
}

Explanation:
00000001
00101100
1
44
Big Endian:

00101100
00000001
44
1
Little Endian:

Address are always created in memory in the form of ABCD format, but the data can be stored in memory either in DCBA format, which is little endian system or in the ABCD format in case of big-endian system.
Lets store 300 in the memory location of an integer. Now if we visit the memory location byte by byte we will find that the contents at first byte will be 1 & the content of the other will be 44. In a Big-endian system the 1st byte will contain 1, and the 2nd byte will be 44 according to the ABCD data storage format where as the little-endian system the 1st will contain 44 & the 2nd byte will be 1 according to the DCBA data storage format.
Logic-1:
First we have to extract the base address of x by type casting it i.e. (unsigned char *). Then by using de-referencing operator ‘*’, we can get the value of the low or 1st byte. If that is found to be equal to 1 & the value of the high / 2nd byte obtained in the same method by adding 1 to the base address of x is equal to 44, then the system is “Big-endian” or else it is “Little-endian”.
Logic-2:
In this logic, we have taken the union called xxx with 2 members – one is an integer x and the other is an array of 2 unsigned characters i.e. ch [2]. As in a union all data members share the same memory location, as the largest data member of the union, hence in this case, ch[0] will be accessing the 1st/low byte of x and ch[1] will be accessing the 2nd/high byte of x. So we can compare p.ch[0] with 1 & p.ch[1] with 44. If it matches, its “Big-endian”, else “little endian”.

10. Write a C-program which does the addition of two integers without using ‘+’ operator.

Answer:
Logic-1:
c = a – (-b);
as a+b is equivalent to a – (-b), binary ‘+’ operator is replaced by one unary ‘-‘ & one binary ‘-‘ operator.

Logic-2:
void main ()
{
int a,b,c;
printf (“\n Enter any two numbers”);
scan f (“%d %d”, &a, &b);
asm mov ax, a;
asm mov bx, b;
asm aad ax, bx;
asm mov c, ax;
printf ( “%d”, c);
}

11. Write a C-program to find the smallest of three integers without using any of the comparision operators.

Answer:
void main ()
{
int a,b,c;
printf (“\n Enter three numbers”);
scan f (“%d %d %d”, &a, &b, &c);
if ((a-b) & 32768)
{
if ((a-c) & 32768)
printf (“ %d”, a);
else
printf (“ %d”, c);
}
else
if ((b-c) & 32768)
printf (“ %d”, b);
else
printf (“ %d”, c);
}

Explanation:

When we substract a number from another number we can find out which one is greater than other. If the result is positive then the first number is greater else the second one is greater. This is known by doing a bitwise & operator with the sign bit (i.e. 32768 or 15th bit).

12. Find the maximum & minimum of two numbers in a single line without using any condition & loop.

Answer:
void main ()
{
int a=15, b=10;
printf (“ max = %d, min = %d”, ((a+b) + abs(a-b)) /2, ((a+b) – abs (a-b)) /2);
}

13. What “condition” expression can be used so that the following code snippet will print Hello world.

Answer:
if “condition”
printf (“ Hello”);
else
printf (“ world !”);

Answer:
void main ()
{
if ( ! printf (“Hello”));
printf (“Hello”);
else
printf (“world !”);
}

Explanation:
As we know the printf function displays the string & returns an integer. So here printf (“Hello”) will print Hello as well as return 5. Then !5 is evaluated which is false. As the condition is false world is printed on the screen. By this we can get Hello world on the screen.

14. How to print number from 1 to 100 without using conditional operators.

Answer:
void main ()
{
int i=0;
while (100 – i++)
printf (“ %d”, i);
}

15. WAP to print 100 times “Hello” without using loop & goto statement.

Answer:
void main()
{
show (1, 100);
}
show (int x, int y)
{
if (x>=y)
return;
printf (“\n Hello”);
show (x+1, y);
}
i.e. Recursive function

16. Write the equivalent expression for x%8.

Answer:
x & 7;

Explanation:
x = 21 = 00010101
7 = 00000111
x & 7 = 00000101 (which is 5)

Posted in Uncategorized | Leave a comment