<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>EmbLogic &#187; Shubham Gupta</title>
	<atom:link href="https://www.emblogic.com/blog/author/shubham16ece/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.emblogic.com/blog</link>
	<description>Embedded System and ARM Training</description>
	<lastBuildDate>Tue, 03 Mar 2020 13:00:06 +0000</lastBuildDate>
	<language>en-US</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.9.1</generator>
	<item>
		<title>Precision Time Protocol</title>
		<link>https://www.emblogic.com/blog/02/precision-time-protocol/</link>
		<comments>https://www.emblogic.com/blog/02/precision-time-protocol/#comments</comments>
		<pubDate>Fri, 03 Feb 2017 04:09:07 +0000</pubDate>
		<dc:creator><![CDATA[Shubham Gupta]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.emblogic.com/blog/?p=13879</guid>
		<description><![CDATA[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 &#8230; <a href="https://www.emblogic.com/blog/02/precision-time-protocol/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>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]</p>
<p>PTP was originally defined in the IEEE 1588-2002 standard, officially entitled &#8220;Standard for a Precision Clock Synchronization Protocol for Networked Measurement and Control Systems&#8221; 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]</p>
<p>&#8220;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</p>
]]></content:encoded>
			<wfw:commentRss>https://www.emblogic.com/blog/02/precision-time-protocol/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>gcc- tool chain</title>
		<link>https://www.emblogic.com/blog/02/gcc-tool-chain/</link>
		<comments>https://www.emblogic.com/blog/02/gcc-tool-chain/#comments</comments>
		<pubDate>Thu, 02 Feb 2017 11:24:44 +0000</pubDate>
		<dc:creator><![CDATA[Shubham Gupta]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.emblogic.com/blog/?p=13875</guid>
		<description><![CDATA[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 &#8230; <a href="https://www.emblogic.com/blog/02/gcc-tool-chain/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>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 &#8221; cross compiler &#8220;.<br />
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.</p>
<p>Tool chains have  a loose name convention like arch [-vendor] [-os] &#8211; eabi<br />
arch &#8211;      refers to target architecture (which in our case is ARM)<br />
vendor &#8211;  refers to toolchain supplier<br />
os &#8211;         refers to the target operating system<br />
eabi &#8211;      refers to Embedded Application Binary Interface</p>
<p>some illustrations as follows :</p>
<p>arm-none-eabi &#8211; This tool chain targets for ARM architecture, has no vendor, does not target an operating system and complies with the ARM EABI.<br />
arm-none-linux-gnueabi &#8211; 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.</p>
<p>So, If you built your application &#8220;helloworld.c&#8221; 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.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.emblogic.com/blog/02/gcc-tool-chain/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remote Access to Linux</title>
		<link>https://www.emblogic.com/blog/02/remote-access-to-linux/</link>
		<comments>https://www.emblogic.com/blog/02/remote-access-to-linux/#comments</comments>
		<pubDate>Wed, 01 Feb 2017 12:26:34 +0000</pubDate>
		<dc:creator><![CDATA[Shubham Gupta]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.emblogic.com/blog/?p=13872</guid>
		<description><![CDATA[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 &#8230; <a href="https://www.emblogic.com/blog/02/remote-access-to-linux/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>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.</p>
<p>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:<br />
·          Secure Shell (SSH)<br />
·          File Transfer Protocol (FTP)<br />
·          SUSE Linux VNC-based remote administration feature<br />
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.</p>
<p>SSH</p>
<p>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&#8217;s system and the SSH server system. For file transfer, FTP is required.</p>
<p>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&#8217;s System tab, opening System Services, and ensuring that the service ssh is enabled.</p>
<p>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:</p>
<p>ssh </p>
<p>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.</p>
<p>For Windows, the application PuTTY is the preferred SSH client.</p>
<p>FTP</p>
<p>FTP is the File Transfer Protocol. It can be used to move files between where you are (the remote client) and the computer you&#8217;re connecting to (your office Linux system).</p>
<p>To set up your Linux computer as an FTP server, use YaST&#8217;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.</p>
<p>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.<br />
·          Uncomment the line that says “#write_enable=YES”. This permits actions which modify files on your system.<br />
·          Uncomment and change the line “#ftpd_banner=&#8221;Welcome to FOOBAR FTP service.&#8221;” if you want to. This is a message sent to the client when they log in.<br />
·          Uncomment the line “#local_enable=YES”. This allows login with the user accounts of the system. These are listed in /etc/passwd.<br />
·          Change the line “anonymous_enable=YES” to say “anonymous_enable=NO”. There is no need to allow random passersby to access your system.<br />
·          Uncomment the lines “#log_ftp_protocol=YES” and “#xferlog_enable=YES”, which will enable logging of all actions.<br />
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</p>
<p>ftp </p>
<p>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.</p>
<p>Linux Remote Desktop</p>
<p>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”.</p>
<p>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.</p>
<p>Setting up the Router with Port Mapping</p>
<p>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.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.emblogic.com/blog/02/remote-access-to-linux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing and setting TFTPD in Ubuntu</title>
		<link>https://www.emblogic.com/blog/02/installing-and-setting-tftpd-in-ubuntu/</link>
		<comments>https://www.emblogic.com/blog/02/installing-and-setting-tftpd-in-ubuntu/#comments</comments>
		<pubDate>Wed, 01 Feb 2017 04:04:22 +0000</pubDate>
		<dc:creator><![CDATA[Shubham Gupta]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.emblogic.com/blog/?p=13870</guid>
		<description><![CDATA[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 = &#8230; <a href="https://www.emblogic.com/blog/02/installing-and-setting-tftpd-in-ubuntu/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Installing and setting TFTPD in Ubuntu</p>
<p>1. Install tftpd and related packages.<br />
$ sudo apt-get install xinetd tftpd tftp<br />
2. Create /etc/xinetd.d/tftp and put this entry:</p>
<p>service tftp<br />
{<br />
protocol        = udp<br />
port            = 69<br />
socket_type     = dgram<br />
wait            = yes<br />
user            = nobody<br />
server          = /usr/sbin/in.tftpd<br />
server_args     = /tftpboot<br />
disable         = no<br />
}</p>
<p>3. Make /tftpboot directory</p>
<p>$ sudo mkdir /tftpboot<br />
$ sudo chmod -R 777 /tftpboot<br />
$ sudo chown -R nobody /tftpboot</p>
<p>4. Start tftpd through xinetd</p>
<p>$ sudo /etc/init.d/xinetd start</p>
]]></content:encoded>
			<wfw:commentRss>https://www.emblogic.com/blog/02/installing-and-setting-tftpd-in-ubuntu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GPIO Device driver</title>
		<link>https://www.emblogic.com/blog/01/gpio-device-driver/</link>
		<comments>https://www.emblogic.com/blog/01/gpio-device-driver/#comments</comments>
		<pubDate>Wed, 25 Jan 2017 12:26:57 +0000</pubDate>
		<dc:creator><![CDATA[Shubham Gupta]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.emblogic.com/blog/?p=13863</guid>
		<description><![CDATA[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 &#8230; <a href="https://www.emblogic.com/blog/01/gpio-device-driver/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>GPIO Device driver</p>
<p>Device node creation without using “mknod”<br />
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!!.<br />
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.<br />
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.<br />
The Driver Module:<br />
#include<br />
#include<br />
#include<br />
#include<br />
#include<br />
#include<br />
#include<br />
#include<br />
#include<br />
#include<br />
#include<br />
#include<br />
#include<br />
 <br />
#define GPIO_NUMBER    149     //any  valid gpio number<br />
 <br />
static dev_t first;         // Global variable for the first device number<br />
static struct cdev c_dev;     // Global variable for the character device structure<br />
static struct class *cl;     // Global variable for the device class<br />
 <br />
static int init_result;<br />
 <br />
static ssize_t gpio_read( struct file* F, char *buf, size_t count, loff_t *f_pos )<br />
{<br />
    char buffer[10];<br />
 <br />
    int temp = gpio_get_value(GPIO_NUMBER);<br />
 <br />
    sprintf( buffer, &#8220;%1d&#8221; , temp );<br />
 <br />
    count = sizeof( buffer );<br />
 <br />
    if( copy_to_user( buf, buffer, count ) )<br />
    {<br />
        return -EFAULT;<br />
    }<br />
 <br />
    if( *f_pos == 0 )<br />
    {<br />
        *f_pos += 1;<br />
        return 1;<br />
    }<br />
    else<br />
    {<br />
        return 0;<br />
    }<br />
}<br />
 <br />
static ssize_t gpio_write( struct file* F, const char *buf, size_t count, loff_t *f_pos )<br />
{<br />
 <br />
    printk(KERN_INFO &#8220;Executing WRITE.\n&#8221;);<br />
 <br />
    switch( buf[0] )<br />
    {<br />
        case &#8217;0&#8242;:<br />
        gpio_set_value(GPIO_NUMBER, 0);<br />
        break;<br />
 <br />
        case &#8217;1&#8242;:<br />
        gpio_set_value(GPIO_NUMBER, 1);<br />
        break;<br />
 <br />
        default:<br />
        printk(&#8220;Wrong option.\n&#8221;);<br />
        break;<br />
    }<br />
    return count;<br />
}<br />
 <br />
static int gpio_open( struct inode *inode, struct file *file )<br />
{<br />
    return 0;<br />
}<br />
 <br />
static int gpio_close( struct inode *inode, struct file *file )<br />
{<br />
    return 0;<br />
}<br />
 <br />
static struct file_operations FileOps =<br />
{<br />
    .owner        = THIS_MODULE,<br />
    .open         = gpio_open,<br />
    .read         = gpio_read,<br />
    .write        = gpio_write,<br />
    .release      = gpio_close,<br />
};<br />
 <br />
static int init_gpio(void)<br />
{<br />
    //init_result = register_chrdev( 0, &#8220;gpio&#8221;, &amp;FileOps );<br />
 <br />
    init_result = alloc_chrdev_region( &amp;first, 0, 1, &#8220;gpio_drv&#8221; );<br />
 <br />
    if( 0 &gt; init_result )<br />
    {<br />
        printk( KERN_ALERT &#8220;Device Registration failed\n&#8221; );<br />
        return -1;<br />
    }<br />
    //else<br />
    //{<br />
    //    printk( KERN_ALERT &#8220;Major number is: %d\n&#8221;,init_result );<br />
    //    return 0;<br />
    //}<br />
 <br />
    if ( (cl = class_create( THIS_MODULE, &#8220;chardev&#8221; ) ) == NULL )<br />
    {<br />
        printk( KERN_ALERT &#8220;Class creation failed\n&#8221; );<br />
        unregister_chrdev_region( first, 1 );<br />
        return -1;<br />
    }<br />
 <br />
    if( device_create( cl, NULL, first, NULL, &#8220;gpio_drv&#8221; ) == NULL )<br />
    {<br />
        printk( KERN_ALERT &#8220;Device creation failed\n&#8221; );<br />
        class_destroy(cl);<br />
        unregister_chrdev_region( first, 1 );<br />
        return -1;<br />
    }<br />
 <br />
    cdev_init( &amp;c_dev, &amp;FileOps );<br />
 <br />
    if( cdev_add( &amp;c_dev, first, 1 ) == -1)<br />
    {<br />
        printk( KERN_ALERT &#8220;Device addition failed\n&#8221; );<br />
        device_destroy( cl, first );<br />
        class_destroy( cl );<br />
        unregister_chrdev_region( first, 1 );<br />
        return -1;<br />
    }<br />
 <br />
    return 0;<br />
}<br />
 <br />
void cleanup_gpio(void)<br />
{<br />
    //unregister_chrdev( init_result, &#8220;gpio&#8221; );<br />
 <br />
    cdev_del( &amp;c_dev );<br />
    device_destroy( cl, first );<br />
    class_destroy( cl );<br />
    unregister_chrdev_region( first, 1 );<br />
 <br />
    printk(KERN_ALERT &#8220;Device unregistered\n&#8221;);<br />
}<br />
 <br />
module_init(init_gpio);<br />
module_exit(cleanup_gpio);<br />
 <br />
MODULE_AUTHOR(&#8220;Sanchayan&#8221;);<br />
MODULE_LICENSE(&#8220;GPL&#8221;);<br />
MODULE_DESCRIPTION(&#8220;Beagleboard-xM GPIO Driver&#8221;);<br />
The User Space Application:<br />
#include<br />
#include<br />
 <br />
int main(void)<br />
{<br />
    int fd;<br />
    char gpio_buffer[10];<br />
    char choice[10];<br />
 <br />
    fd = open( &#8220;/dev/gpio_drv&#8221;, O_RDWR );<br />
 <br />
    printf( &#8220;Value of fd is: %d&#8221;, fd );<br />
 <br />
    if( fd  trigger” in their respective directories.<br />
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.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.emblogic.com/blog/01/gpio-device-driver/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Write Your Own Linux Kernel Module with a Simple Example</title>
		<link>https://www.emblogic.com/blog/01/how-to-write-your-own-linux-kernel-module-with-a-simple-example/</link>
		<comments>https://www.emblogic.com/blog/01/how-to-write-your-own-linux-kernel-module-with-a-simple-example/#comments</comments>
		<pubDate>Tue, 10 Jan 2017 04:13:17 +0000</pubDate>
		<dc:creator><![CDATA[Shubham Gupta]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.emblogic.com/blog/?p=13848</guid>
		<description><![CDATA[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 &#8230; <a href="https://www.emblogic.com/blog/01/how-to-write-your-own-linux-kernel-module-with-a-simple-example/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>What are kernel modules?</p>
<p>Kernel modules are piece of code, that can be loaded and unloaded from kernel on demand.</p>
<p>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.</p>
<p>The kernel modules will have a .ko extension. On a normal linux system, the kernel modules will reside inside /lib/modules//kernel/ directory.</p>
<p>Earlier we discussed how to compile a kernel from the source.</p>
<p>This tutorial explains how to write a Kernel module using a simple Hello World example.<br />
I. Utilities to Manipulate Kernel Modules<br />
1. lsmod – List Modules that Loaded Already</p>
<p>lsmod command will list modules that are already loaded in the kernel as shown beblow.</p>
<p># lsmod<br />
Module                  Size  Used by<br />
ppp_deflate            12806  0<br />
zlib_deflate           26445  1 ppp_deflate<br />
bsd_comp               12785  0<br />
..</p>
<p>2. insmod – Insert Module into Kernel</p>
<p>insmod command will insert a new module into the kernel as shown below.</p>
<p># insmod /lib/modules/3.5.0-19-generic/kernel/fs/squashfs/squashfs.ko</p>
<p># lsmod | grep &#8220;squash&#8221;<br />
squashfs               35834  0</p>
<p>3. modinfo – Display Module Info</p>
<p>modinfo command will display information about a kernel module as shown below.</p>
<p># modinfo /lib/modules/3.5.0-19-generic/kernel/fs/squashfs/squashfs.ko</p>
<p>filename:       /lib/modules/3.5.0-19-generic/kernel/fs/squashfs/squashfs.ko<br />
license:        GPL<br />
author:         Phillip Lougher<br />
description:    squashfs 4.0, a compressed read-only filesystem<br />
srcversion:     89B46A0667BD5F2494C4C72<br />
depends:<br />
intree:         Y<br />
vermagic:       3.5.0-19-generic SMP mod_unload modversions 686</p>
<p>4. rmmod – Remove Module from Kernel</p>
<p>rmmod command will remove a module from the kernel. You cannot remove a module which is already used by any program.</p>
<p># rmmod squashfs.ko</p>
<p>5. modprobe – Add or Remove modules from the kernel</p>
<p>modprobe is an intelligent command which will load/unload modules based on the dependency between modules. Refer to modprobe commands for more detailed examples.</p>
<p>II. Write a Simple Hello World Kernel Module</p>
<p>1. Installing the linux headers</p>
<p>You need to install the linux-headers-.. first as shown below. Depending on your distro, use apt-get or yum.</p>
<p># apt-get install build-essential linux-headers-$(uname -r)</p>
<p>2. Hello World Module Source Code</p>
<p>Next, create the following hello.c module in C programming language.</p>
<p>#include     // included for all kernel modules<br />
#include     // included for KERN_INFO<br />
#include       // included for __init and __exit macros</p>
<p>MODULE_LICENSE(&#8220;GPL&#8221;);<br />
MODULE_AUTHOR(&#8220;Lakshmanan&#8221;);<br />
MODULE_DESCRIPTION(&#8220;A Simple Hello World module&#8221;);</p>
<p>static int __init hello_init(void)<br />
{<br />
    printk(KERN_INFO &#8220;Hello world!\n&#8221;);<br />
    return 0;    // Non-zero return means that the module couldn&#8217;t be loaded.<br />
}</p>
<p>static void __exit hello_cleanup(void)<br />
{<br />
    printk(KERN_INFO &#8220;Cleaning up module.\n&#8221;);<br />
}</p>
<p>module_init(hello_init);<br />
module_exit(hello_cleanup);</p>
<p>Warning: All kernel modules will operate on kernel space, a highly privileged mode. So be careful with what you write in a kernel module.</p>
<p>3. Create Makefile to Compile Kernel Module</p>
<p>The following makefile can be used to compile the above basic hello world kernel module.</p>
<p>obj-m += hello.o</p>
<p>all:<br />
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules</p>
<p>clean:<br />
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean</p>
<p>Use the make command to compile hello world kernel module as shown below.</p>
<p># make</p>
<p>make -C /lib/modules/3.5.0-19-generic/build M=/home/lakshmanan/a modules<br />
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-19-generic&#8217;<br />
  CC [M]  /home/lakshmanan/a/hello.o<br />
  Building modules, stage 2.<br />
  MODPOST 1 modules<br />
  CC      /home/lakshmanan/a/hello.mod.o<br />
  LD [M]  /home/lakshmanan/a/hello.ko<br />
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-19-generic&#8217;</p>
<p>The above will create hello.ko file, which is our sample Kernel module.<br />
4. Insert or Remove the Sample Kernel Module</p>
<p>Now that we have our hello.ko file, we can insert this module to the kernel by using insmod command as shown below.</p>
<p># insmod hello.ko</p>
<p># dmesg | tail -1<br />
[ 8394.731865] Hello world!</p>
<p># rmmod hello.ko</p>
<p># dmesg | tail -1<br />
[ 8707.989819] Cleaning up module.</p>
<p>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.</p>
<p>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.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.emblogic.com/blog/01/how-to-write-your-own-linux-kernel-module-with-a-simple-example/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>U-Boot environment</title>
		<link>https://www.emblogic.com/blog/01/u-boot-environment/</link>
		<comments>https://www.emblogic.com/blog/01/u-boot-environment/#comments</comments>
		<pubDate>Tue, 03 Jan 2017 06:30:40 +0000</pubDate>
		<dc:creator><![CDATA[Shubham Gupta]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.emblogic.com/blog/?p=13845</guid>
		<description><![CDATA[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 &#8230; <a href="https://www.emblogic.com/blog/01/u-boot-environment/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>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.</p>
<p>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.</p>
<p>autoload: if set to &#8220;no&#8221; (or any string beginning with &#8216;n&#8217;), 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.<br />
autostart: if set to &#8220;yes&#8221;, an image loaded using the rarpb, bootp, dhcp, tftp, disk, or docb commands will be automatically started (by internally calling the bootm command).<br />
baudrate: a decimal number that selects the console baudrate (in bps). Only a predefined list of baudrate settings is available.<br />
When you change the baudrate (using the &#8220;setenv baudrate &#8230;&#8221; 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.)<br />
If no &#8220;baudrate&#8221; variable is defined, the default baudrate of 115200 is used.<br />
bootargs: The contents of this variable are passed to the Linux kernel as boot arguments (aka &#8220;command line&#8221;).<br />
bootcmd: This variable defines a command string that is automatically executed when the initial countdown is not interrupted.<br />
This command is only executed when the variable bootdelay is also defined!<br />
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.<br />
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!<br />
Set this variable to -1 to disable autoboot.<br />
bootfile: name of the default image to load with TFTP<br />
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.<br />
ethaddr: Ethernet MAC address for first/only ethernet interface (= eth0 in Linux).<br />
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.<br />
eth1addr: Ethernet MAC address for second ethernet interface (= eth1 in Linux).<br />
eth2addr: Ethernet MAC address for third ethernet interface (= eth2 in Linux).<br />
&#8230;<br />
initrd_high: used to restrict positioning of initrd ramdisk images:<br />
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 &#8220;no&#8221; or &#8220;off&#8221; or &#8220;0&#8243;. 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).<br />
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 &#8220;mem=12M&#8221; to the value of the &#8220;bootargs&#8221; variable. However, now you must make sure that the initrd image is placed in the first 12 MB as well &#8211; this can be done with<br />
=&gt; setenv initrd_high 00c00000</p>
<p>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.<br />
ipaddr: IP address; needed for tftp command<br />
loadaddr: Default load address for commands like tftp or loads.<br />
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.<br />
mtdparts: This variable (usually defined using the mtdparts command) allows to share a common MTD partition scheme between U-Boot and the Linux kernel.<br />
pram: If the &#8220;Protected RAM&#8221; feature is enabled in your board&#8217;s configuration, this variable can be defined to enable the reservation of such &#8220;protected RAM&#8221;, 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 &#8220;mem&#8221; 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:<br />
=&gt; setenv bootargs ${bootargs} mem=\${mem}<br />
=&gt; saveenv</p>
<p>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.<br />
serverip: TFTP server IP address; needed for tftp command.<br />
serial#: contains hardware identification information such as type string and/or serial number.<br />
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.<br />
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.<br />
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.<br />
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:</p>
<p>bootfile: see above<br />
dnsip: IP address of your Domain Name Server<br />
gatewayip: IP address of the Gateway (Router) to use<br />
hostname: Target hostname<br />
ipaddr: see above<br />
netmask: Subnet Mask<br />
rootpath: Pathname of the root filesystem on the NFS server<br />
serverip: see above<br />
filesize: Size (as hex number in bytes) of the file downloaded using the last bootp, dhcp, or tftp command.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.emblogic.com/blog/01/u-boot-environment/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>U-Boot: Quick reference</title>
		<link>https://www.emblogic.com/blog/01/u-boot-quick-reference/</link>
		<comments>https://www.emblogic.com/blog/01/u-boot-quick-reference/#comments</comments>
		<pubDate>Tue, 03 Jan 2017 06:19:34 +0000</pubDate>
		<dc:creator><![CDATA[Shubham Gupta]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.emblogic.com/blog/?p=13843</guid>
		<description><![CDATA[Information commands bdinfo &#8211; print Board Info structure coninfo &#8211; print console devices and information flinfo &#8211; print FLASH memory information help &#8211; print online help Memory commands base &#8211; print or set address offset crc32 &#8211; checksum calculation cmp &#8230; <a href="https://www.emblogic.com/blog/01/u-boot-quick-reference/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Information commands</p>
<p>bdinfo &#8211; print Board Info structure<br />
coninfo &#8211; print console devices and information<br />
flinfo &#8211; print FLASH memory information<br />
help &#8211; print online help<br />
Memory commands</p>
<p>base &#8211; print or set address offset<br />
crc32 &#8211; checksum calculation<br />
cmp &#8211; memory compare<br />
cp &#8211; memory copy<br />
md &#8211; memory display<br />
mm &#8211; memory modify (auto incrementing)<br />
mtest &#8211; simple RAM test<br />
mw &#8211; memory write (fill)<br />
nm &#8211; memory modify (constant address)<br />
loop &#8211; infinite loop on address range<br />
Flash memory commands</p>
<p>cp &#8211; memory copy<br />
flinfo &#8211; print FLASH memory information<br />
erase &#8211; erase FLASH memory<br />
protect &#8211; enable or disable FLASH write protection<br />
Image commands</p>
<p>iminfo &#8211; print header information for application image<br />
imxtract &#8211; extract a part of a multi-image<br />
Execution control commands</p>
<p>autoscr &#8211; run script from memory<br />
source &#8211; run script from memory<br />
bootm &#8211; boot application image from memory<br />
go &#8211; start application at address &#8216;addr&#8217;<br />
loop &#8211; infinite loop on address range<br />
exit &#8211; exit script<br />
Download commands</p>
<p>bootp &#8211; boot image via network using BOOTP/TFTP protocol<br />
dhcp &#8211; invoke DHCP client to obtain IP/boot params<br />
loadb &#8211; load binary file over serial line (kermit mode)<br />
loady &#8211; load binary file over serial line (ymodem mode)<br />
loads &#8211; load S?Record file over serial line<br />
rarpboot &#8211; boot image via network using RARP/TFTP protocol<br />
tftpboot &#8211; boot image via network using TFTP protocol<br />
nfs &#8211; boot image via network using NFS protocol<br />
ping &#8211; send ICMP ECHO REQUEST to network host<br />
Environment variables commands</p>
<p>env &#8211; environment handling commands<br />
editenv &#8211; edit environment variable<br />
printenv &#8211; print environment variables<br />
saveenv &#8211; save environment variables to persistent storage<br />
setenv &#8211; set environment variables<br />
run &#8211; run commands in an environment variable<br />
bootd &#8211; boot default, i.e., run &#8216;bootcmd&#8217;<br />
boot &#8211; boot default, i.e., run &#8216;bootcmd&#8217;<br />
File system support commands</p>
<p>fatinfo &#8211; print information about a FAT file system<br />
fatload &#8211; load binary file from a FAT file system<br />
fatls &#8211; list files in a FAT file system directory (default /)<br />
ext2load &#8211; load binary file from a Ext2 filesystem<br />
ext2ls &#8211; list files in a directory (default /)<br />
fsinfo &#8211; print information about JFFS2 file system<br />
fsload &#8211; load binary file from a JFFS2 file system image<br />
ls &#8211; list files in a JFFS2 file system directory (default /)<br />
NAND flash support</p>
<p>nand &#8211; NAND sub-system control<br />
nandecc &#8211; switch OMAP3 NAND ECC calculation algorithm<br />
nboot &#8211; boot from NAND device<br />
Partition commands</p>
<p>mtdparts &#8211; define flash/nand partitions<br />
chpart &#8211; change active partition<br />
FDT support</p>
<p>fdt &#8211; flattened device tree utility commands<br />
MMC support</p>
<p>mmc &#8211; MMC sub system<br />
mmcinfo &#8211; display MMC information<br />
I2C support</p>
<p>i2c &#8211; I2C sub-system control<br />
USB support</p>
<p>usb &#8211; USB sub-system control<br />
usbboot &#8211; boot from USB device<br />
Cache support</p>
<p>icache &#8211; enable or disable instruction cache<br />
dcache &#8211; enable or disable data cache<br />
Bitmap support</p>
<p>bmp &#8211; manipulate BMP image data<br />
GPIO support</p>
<p>gpio &#8211; manipulate gpios<br />
Miscellaneous commands</p>
<p>echo &#8211; echo arguments to console<br />
reset &#8211; Perform RESET of the CPU<br />
sleep &#8211; delay execution for some time<br />
version &#8211; print monitor version<br />
test &#8211; minimal test, like /bin/bash<br />
? &#8211; alias for help<br />
showvar &#8211; print local hushshell variables<br />
true &#8211; do nothing, successfully<br />
false &#8211; do nothing, unsuccessfully<br />
cls &#8211; clear screen<br />
itest &#8211; return true/false on integer compare</p>
]]></content:encoded>
			<wfw:commentRss>https://www.emblogic.com/blog/01/u-boot-quick-reference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Linux Kernel Sources</title>
		<link>https://www.emblogic.com/blog/01/the-linux-kernel-sources/</link>
		<comments>https://www.emblogic.com/blog/01/the-linux-kernel-sources/#comments</comments>
		<pubDate>Tue, 03 Jan 2017 04:56:34 +0000</pubDate>
		<dc:creator><![CDATA[Shubham Gupta]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.emblogic.com/blog/?p=13841</guid>
		<description><![CDATA[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 &#8230; <a href="https://www.emblogic.com/blog/01/the-linux-kernel-sources/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>How The Kernel Sources Are Arranged</p>
<p>At the very top level of the source tree /usr/src/linux you will see a number of directories:<br />
arch<br />
The arch subdirectory contains all of the architecture specific kernel code. It has further subdirectories, one per supported architecture, for example i386 and alpha.<br />
include<br />
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.<br />
init<br />
This directory contains the initialization code for the kernel and it is a very good place to start looking at how the kernel works.<br />
mm<br />
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.<br />
drivers<br />
All of the system&#8217;s device drivers live in this directory. They are further sub-divided into classes of device driver, for example block.<br />
ipc<br />
This directory contains the kernels inter-process communications code.<br />
modules<br />
This is simply a directory used to hold built modules.<br />
fs<br />
All of the file system code. This is further sub-divided into directories, one per supported file system, for example vfat and ext2.<br />
kernel<br />
The main kernel code. Again, the architecture specific kernel code is in arch/*/kernel.<br />
net<br />
The kernel&#8217;s networking code.<br />
lib<br />
This directory contains the kernel&#8217;s library code. The architecture specific library code can be found in arch/*/lib/.<br />
scripts<br />
This directory contains the scripts (for example awk and tk scripts) that are used when the kernel is configured.<br />
Where to Start Looking</p>
<p>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.<br />
System Startup and Initialization</p>
<p>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.<br />
Memory Management</p>
<p>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.<br />
Kernel</p>
<p>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.<br />
PCI</p>
<p>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&#8217;s is in arch/alpha/kernel/bios32.c.<br />
Interprocess Communication</p>
<p>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.<br />
Interrupt Handling</p>
<p>The kernel&#8217;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.<br />
Device Drivers</p>
<p>Most of the lines of the Linux kernel&#8217;s source code are in its device drivers. All of Linux&#8217;s device driver sources are held in drivers but these are further broken out by type:<br />
/block<br />
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.<br />
/char<br />
This the place to look for character based devices such as ttys, serial ports and mice.<br />
/cdrom<br />
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.<br />
/pci<br />
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.<br />
/scsi<br />
This is where to find all of the SCSI code as well as all of the drivers for the scsi devices supported by Linux.<br />
/net<br />
This is where to look to find the network device drivers such as the DECChip 21040 PCI ethernet driver which is in tulip.c.<br />
/sound<br />
This is where all of the sound card drivers are.<br />
File Systems</p>
<p>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.<br />
Network</p>
<p>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.<br />
Modules</p>
<p>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.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.emblogic.com/blog/01/the-linux-kernel-sources/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux Data Structures</title>
		<link>https://www.emblogic.com/blog/01/linux-data-structures/</link>
		<comments>https://www.emblogic.com/blog/01/linux-data-structures/#comments</comments>
		<pubDate>Tue, 03 Jan 2017 04:45:45 +0000</pubDate>
		<dc:creator><![CDATA[Shubham Gupta]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.emblogic.com/blog/?p=13839</guid>
		<description><![CDATA[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 &#8230; <a href="https://www.emblogic.com/blog/01/linux-data-structures/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>block_dev_struct</p>
<p>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.<br />
struct blk_dev_struct {<br />
    void (*request_fn)(void);<br />
    struct request * current_request;<br />
    struct request   plug;<br />
    struct tq_struct plug_tq;<br />
};<br />
buffer_head</p>
<p>The buffer_head data structure holds information about a block buffer in the buffer cache.<br />
/* bh state bits */<br />
#define BH_Uptodate  0   /* 1 if the buffer contains valid data      */<br />
#define BH_Dirty     1   /* 1 if the buffer is dirty                 */<br />
#define BH_Lock      2   /* 1 if the buffer is locked                */<br />
#define BH_Req       3   /* 0 if the buffer has been invalidated     */<br />
#define BH_Touched   4   /* 1 if the buffer has been touched (aging) */<br />
#define BH_Has_aged  5   /* 1 if the buffer has been aged (aging)    */<br />
#define BH_Protected 6   /* 1 if the buffer is protected             */<br />
#define BH_FreeOnIO  7   /* 1 to discard the buffer_head after IO    */</p>
<p>struct buffer_head {<br />
  /* First cache line: */<br />
  unsigned long      b_blocknr;    /* block number                   */<br />
  kdev_t             b_dev;        /* device (B_FREE = free)         */<br />
  kdev_t             b_rdev;       /* Real device                    */<br />
  unsigned long      b_rsector;    /* Real buffer location on disk   */<br />
  struct buffer_head *b_next;      /* Hash queue list                */<br />
  struct buffer_head *b_this_page; /* circular list of buffers in one<br />
                                      page                           */</p>
<p>  /* Second cache line: */<br />
  unsigned long      b_state;      /* buffer state bitmap (above)    */<br />
  struct buffer_head *b_next_free;<br />
  unsigned int       b_count;      /* users using this block         */<br />
  unsigned long      b_size;       /* block size                     */</p>
<p>  /* Non-performance-critical data follows. */<br />
  char               *b_data;      /* pointer to data block          */<br />
  unsigned int       b_list;       /* List that this buffer appears  */<br />
  unsigned long      b_flushtime;  /* Time when this (dirty) buffer<br />
                                    * should be written              */<br />
  unsigned long      b_lru_time;   /* Time when this buffer was<br />
                                    * last used.                     */<br />
  struct wait_queue  *b_wait;<br />
  struct buffer_head *b_prev;      /* doubly linked hash list        */<br />
  struct buffer_head *b_prev_free; /* doubly linked list of buffers  */<br />
  struct buffer_head *b_reqnext;   /* request queue                  */<br />
};<br />
device</p>
<p>Every network device in the system is represented by a device data structure.<br />
struct device<br />
{</p>
<p>  /*<br />
   * This is the first field of the &#8220;visible&#8221; part of this structure<br />
   * (i.e. as seen by users in the &#8220;Space.c&#8221; file).  It is the name<br />
   * the interface.<br />
   */<br />
  char                    *name;</p>
<p>  /* I/O specific fields                                           */<br />
  unsigned long           rmem_end;        /* shmem &#8220;recv&#8221; end     */<br />
  unsigned long           rmem_start;      /* shmem &#8220;recv&#8221; start   */<br />
  unsigned long           mem_end;         /* shared mem end       */<br />
  unsigned long           mem_start;       /* shared mem start     */<br />
  unsigned long           base_addr;       /* device I/O address   */<br />
  unsigned char           irq;             /* device IRQ number    */</p>
<p>  /* Low-level status flags. */<br />
  volatile unsigned char  start,           /* start an operation   */<br />
                          interrupt;       /* interrupt arrived    */<br />
  unsigned long           tbusy;           /* transmitter busy     */<br />
  struct device           *next;</p>
<p>  /* The device initialization function. Called only once.         */<br />
  int                     (*init)(struct device *dev);</p>
<p>  /* Some hardware also needs these fields, but they are not part of<br />
     the usual set specified in Space.c. */<br />
  unsigned char           if_port;         /* Selectable AUI,TP,   */<br />
  unsigned char           dma;             /* DMA channel          */</p>
<p>  struct enet_statistics* (*get_stats)(struct device *dev);</p>
<p>  /*<br />
   * This marks the end of the &#8220;visible&#8221; part of the structure. All<br />
   * fields hereafter are internal to the system, and may change at<br />
   * will (read: may be cleaned up at will).<br />
   */</p>
<p>  /* These may be needed for future network-power-down code.       */<br />
  unsigned long           trans_start;     /* Time (jiffies) of<br />
                                              last transmit        */<br />
  unsigned long           last_rx;         /* Time of last Rx      */<br />
  unsigned short          flags;           /* interface flags (BSD)*/<br />
  unsigned short          family;          /* address family ID    */<br />
  unsigned short          metric;          /* routing metric       */<br />
  unsigned short          mtu;             /* MTU value            */<br />
  unsigned short          type;            /* hardware type        */<br />
  unsigned short          hard_header_len; /* hardware hdr len     */<br />
  void                    *priv;           /* private data         */</p>
<p>  /* Interface address info. */<br />
  unsigned char           broadcast[MAX_ADDR_LEN];<br />
  unsigned char           pad;<br />
  unsigned char           dev_addr[MAX_ADDR_LEN];<br />
  unsigned char           addr_len;        /* hardware addr len    */<br />
  unsigned long           pa_addr;         /* protocol address     */<br />
  unsigned long           pa_brdaddr;      /* protocol broadcast addr*/<br />
  unsigned long           pa_dstaddr;      /* protocol P-P other addr*/<br />
  unsigned long           pa_mask;         /* protocol netmask     */<br />
  unsigned short          pa_alen;         /* protocol address len */</p>
<p>  struct dev_mc_list      *mc_list;        /* M&#8217;cast mac addrs     */<br />
  int                     mc_count;        /* No installed mcasts  */</p>
<p>  struct ip_mc_list       *ip_mc_list;     /* IP m&#8217;cast filter chain */<br />
  __u32                   tx_queue_len;    /* Max frames per queue   */</p>
<p>  /* For load balancing driver pair support */<br />
  unsigned long           pkt_queue;       /* Packets queued       */<br />
  struct device           *slave;          /* Slave device         */<br />
  struct net_alias_info   *alias_info;     /* main dev alias info  */<br />
  struct net_alias        *my_alias;       /* alias devs           */</p>
<p>  /* Pointer to the interface buffers. */<br />
  struct sk_buff_head     buffs[DEV_NUMBUFFS];</p>
<p>  /* Pointers to interface service routines. */<br />
  int                     (*open)(struct device *dev);<br />
  int                     (*stop)(struct device *dev);<br />
  int                     (*hard_start_xmit) (struct sk_buff *skb,<br />
                                              struct device *dev);<br />
  int                     (*hard_header) (struct sk_buff *skb,<br />
                                          struct device *dev,<br />
                                          unsigned short type,<br />
                                          void *daddr,<br />
                                          void *saddr,<br />
                                          unsigned len);<br />
  int                     (*rebuild_header)(void *eth,<br />
                                          struct device *dev,<br />
                                          unsigned long raddr,<br />
                                          struct sk_buff *skb);<br />
  void                    (*set_multicast_list)(struct device *dev);<br />
  int                     (*set_mac_address)(struct device *dev,<br />
                                          void *addr);<br />
  int                     (*do_ioctl)(struct device *dev,<br />
                                          struct ifreq *ifr,<br />
                                          int cmd);<br />
  int                     (*set_config)(struct device *dev,<br />
                                          struct ifmap *map);<br />
  void                    (*header_cache_bind)(struct hh_cache **hhp,<br />
                                          struct device *dev,<br />
                                          unsigned short htype,<br />
                                          __u32 daddr);<br />
  void                    (*header_cache_update)(struct hh_cache *hh,<br />
                                          struct device *dev,<br />
                                          unsigned char *  haddr);<br />
  int                     (*change_mtu)(struct device *dev,<br />
                                          int new_mtu);<br />
  struct iw_statistics*   (*get_wireless_stats)(struct device *dev);<br />
};<br />
device_struct</p>
<p>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.<br />
struct device_struct {<br />
    const char * name;<br />
    struct file_operations * fops;<br />
};<br />
file</p>
<p>Each open file, socket etcetera is represented by a file data structure.<br />
struct file {<br />
  mode_t f_mode;<br />
  loff_t f_pos;<br />
  unsigned short f_flags;<br />
  unsigned short f_count;<br />
  unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin;<br />
  struct file *f_next, *f_prev;<br />
  int f_owner;         /* pid or -pgrp where SIGIO should be sent */<br />
  struct inode * f_inode;<br />
  struct file_operations * f_op;<br />
  unsigned long f_version;<br />
  void *private_data;  /* needed for tty driver, and maybe others */<br />
};<br />
files_struct</p>
<p>The files_struct data structure describes the files that a process has open.<br />
struct files_struct {<br />
  int count;<br />
  fd_set close_on_exec;<br />
  fd_set open_fds;<br />
  struct file * fd[NR_OPEN];<br />
};<br />
fs_struct</p>
<p>struct fs_struct {<br />
  int count;<br />
  unsigned short umask;<br />
  struct inode * root, * pwd;<br />
};<br />
gendisk</p>
<p>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.<br />
struct hd_struct {<br />
    long start_sect;<br />
    long nr_sects;<br />
};</p>
<p>struct gendisk {<br />
    int major;               /* major number of driver */<br />
    const char *major_name;  /* name of major driver */<br />
    int minor_shift;         /* number of times minor is shifted to<br />
                                get real minor */<br />
    int max_p;               /* maximum partitions per device */<br />
    int max_nr;              /* maximum number of real devices */</p>
<p>    void (*init)(struct gendisk *);<br />
                             /* Initialization called before we<br />
                                do our thing */<br />
    struct hd_struct *part;  /* partition table */<br />
    int *sizes;              /* device size in blocks, copied to<br />
                                blk_size[] */<br />
    int nr_real;             /* number of real devices */</p>
<p>    void *real_devices;      /* internal use */<br />
    struct gendisk *next;<br />
};<br />
inode</p>
<p>The VFS inode data structure holds information about a file or directory on disk.<br />
struct inode {<br />
    kdev_t                       i_dev;<br />
    unsigned long                i_ino;<br />
    umode_t                      i_mode;<br />
    nlink_t                      i_nlink;<br />
    uid_t                        i_uid;<br />
    gid_t                        i_gid;<br />
    kdev_t                       i_rdev;<br />
    off_t                        i_size;<br />
    time_t                       i_atime;<br />
    time_t                       i_mtime;<br />
    time_t                       i_ctime;<br />
    unsigned long                i_blksize;<br />
    unsigned long                i_blocks;<br />
    unsigned long                i_version;<br />
    unsigned long                i_nrpages;<br />
    struct semaphore             i_sem;<br />
    struct inode_operations      *i_op;<br />
    struct super_block           *i_sb;<br />
    struct wait_queue            *i_wait;<br />
    struct file_lock             *i_flock;<br />
    struct vm_area_struct        *i_mmap;<br />
    struct page                  *i_pages;<br />
    struct dquot                 *i_dquot[MAXQUOTAS];<br />
    struct inode                 *i_next, *i_prev;<br />
    struct inode                 *i_hash_next, *i_hash_prev;<br />
    struct inode                 *i_bound_to, *i_bound_by;<br />
    struct inode                 *i_mount;<br />
    unsigned short               i_count;<br />
    unsigned short               i_flags;<br />
    unsigned char                i_lock;<br />
    unsigned char                i_dirt;<br />
    unsigned char                i_pipe;<br />
    unsigned char                i_sock;<br />
    unsigned char                i_seek;<br />
    unsigned char                i_update;<br />
    unsigned short               i_writecount;<br />
    union {<br />
        struct pipe_inode_info   pipe_i;<br />
        struct minix_inode_info  minix_i;<br />
        struct ext_inode_info    ext_i;<br />
        struct ext2_inode_info   ext2_i;<br />
        struct hpfs_inode_info   hpfs_i;<br />
        struct msdos_inode_info  msdos_i;<br />
        struct umsdos_inode_info umsdos_i;<br />
        struct iso_inode_info    isofs_i;<br />
        struct nfs_inode_info    nfs_i;<br />
        struct xiafs_inode_info  xiafs_i;<br />
        struct sysv_inode_info   sysv_i;<br />
        struct affs_inode_info   affs_i;<br />
        struct ufs_inode_info    ufs_i;<br />
        struct socket            socket_i;<br />
        void                     *generic_ip;<br />
    } u;<br />
};<br />
ipc_perm</p>
<p>The ipc_perm data structure describes the access permissions of a System V IPC object .<br />
struct ipc_perm<br />
{<br />
  key_t  key;<br />
  ushort uid;   /* owner euid and egid */<br />
  ushort gid;<br />
  ushort cuid;  /* creator euid and egid */<br />
  ushort cgid;<br />
  ushort mode;  /* access modes see mode flags below */<br />
  ushort seq;   /* sequence number */<br />
};<br />
irqaction</p>
<p>The irqaction data structure is used to describe the system&#8217;s interrupt handlers.<br />
struct irqaction {<br />
  void (*handler)(int, void *, struct pt_regs *);<br />
  unsigned long flags;<br />
  unsigned long mask;<br />
  const char *name;<br />
  void *dev_id;<br />
  struct irqaction *next;<br />
};<br />
linux_binfmt</p>
<p>Each binary file format that Linux understands is represented by a linux_binfmt data structure.<br />
struct linux_binfmt {<br />
  struct linux_binfmt * next;<br />
  long *use_count;<br />
  int (*load_binary)(struct linux_binprm *, struct  pt_regs * regs);<br />
  int (*load_shlib)(int fd);<br />
  int (*core_dump)(long signr, struct pt_regs * regs);<br />
};<br />
mem_map_t</p>
<p>The mem_map_t data structure (also known as page) is used to hold information about each page of physical memory.<br />
typedef struct page {<br />
  /* these must be first (free area handling) */<br />
  struct page        *next;<br />
  struct page        *prev;<br />
  struct inode       *inode;<br />
  unsigned long      offset;<br />
  struct page        *next_hash;<br />
  atomic_t           count;<br />
  unsigned           flags;     /* atomic flags, some possibly<br />
                                   updated asynchronously */<br />
  unsigned           dirty:16,<br />
                     age:8;<br />
  struct wait_queue  *wait;<br />
  struct page        *prev_hash;<br />
  struct buffer_head *buffers;<br />
  unsigned long      swap_unlock_entry;<br />
  unsigned long      map_nr;    /* page-&gt;map_nr == page &#8211; mem_map */<br />
} mem_map_t;<br />
mm_struct</p>
<p>The mm_struct data structure is used to describe the virtual memory of a task or process.<br />
struct mm_struct {<br />
  int count;<br />
  pgd_t * pgd;<br />
  unsigned long context;<br />
  unsigned long start_code, end_code, start_data, end_data;<br />
  unsigned long start_brk, brk, start_stack, start_mmap;<br />
  unsigned long arg_start, arg_end, env_start, env_end;<br />
  unsigned long rss, total_vm, locked_vm;<br />
  unsigned long def_flags;<br />
  struct vm_area_struct * mmap;<br />
  struct vm_area_struct * mmap_avl;<br />
  struct semaphore mmap_sem;<br />
};<br />
pci_bus</p>
<p>Every PCI bus in the system is represented by a pci_bus data structure.<br />
struct pci_bus {<br />
  struct pci_bus  *parent;     /* parent bus this bridge is on */<br />
  struct pci_bus  *children;   /* chain of P2P bridges on this bus */<br />
  struct pci_bus  *next;       /* chain of all PCI buses */</p>
<p>  struct pci_dev  *self;       /* bridge device as seen by parent */<br />
  struct pci_dev  *devices;    /* devices behind this bridge */</p>
<p>  void    *sysdata;            /* hook for sys-specific extension */</p>
<p>  unsigned char  number;       /* bus number */<br />
  unsigned char  primary;      /* number of primary bridge */<br />
  unsigned char  secondary;    /* number of secondary bridge */<br />
  unsigned char  subordinate;  /* max number of subordinate buses */<br />
};<br />
pci_dev</p>
<p>Every PCI device in the system, including PCI-PCI and PCI-ISA bridge devices is represented by a pci_dev data structure.<br />
/*<br />
 * There is one pci_dev structure for each slot-number/function-number<br />
 * combination:<br />
 */<br />
struct pci_dev {<br />
  struct pci_bus  *bus;      /* bus this device is on */<br />
  struct pci_dev  *sibling;  /* next device on this bus */<br />
  struct pci_dev  *next;     /* chain of all devices */</p>
<p>  void    *sysdata;          /* hook for sys-specific extension */</p>
<p>  unsigned int  devfn;       /* encoded device &amp; function index */<br />
  unsigned short  vendor;<br />
  unsigned short  device;<br />
  unsigned int  class;       /* 3 bytes: (base,sub,prog-if) */<br />
  unsigned int  master : 1;  /* set if device is master capable */<br />
  /*<br />
   * In theory, the irq level can be read from configuration<br />
   * space and all would be fine.  However, old PCI chips don&#8217;t<br />
   * support these registers and return 0 instead.  For example,<br />
   * the Vision864-P rev 0 chip can uses INTA, but returns 0 in<br />
   * the interrupt line and pin registers.  pci_init()<br />
   * initializes this field with the value at PCI_INTERRUPT_LINE<br />
   * and it is the job of pcibios_fixup() to change it if<br />
   * necessary.  The field must not be 0 unless the device<br />
   * cannot generate interrupts at all.<br />
   */<br />
  unsigned char  irq;        /* irq generated by this device */<br />
};<br />
request</p>
<p>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.<br />
struct request {<br />
    volatile int rq_status;<br />
#define RQ_INACTIVE            (-1)<br />
#define RQ_ACTIVE              1<br />
#define RQ_SCSI_BUSY           0xffff<br />
#define RQ_SCSI_DONE           0xfffe<br />
#define RQ_SCSI_DISCONNECTING  0xffe0</p>
<p>    kdev_t rq_dev;<br />
    int cmd;        /* READ or WRITE */<br />
    int errors;<br />
    unsigned long sector;<br />
    unsigned long nr_sectors;<br />
    unsigned long current_nr_sectors;<br />
    char * buffer;<br />
    struct semaphore * sem;<br />
    struct buffer_head * bh;<br />
    struct buffer_head * bhtail;<br />
    struct request * next;<br />
};<br />
rtable</p>
<p>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.<br />
struct rtable<br />
{<br />
    struct rtable     *rt_next;<br />
    __u32             rt_dst;<br />
    __u32             rt_src;<br />
    __u32             rt_gateway;<br />
    atomic_t          rt_refcnt;<br />
    atomic_t          rt_use;<br />
    unsigned long     rt_window;<br />
    atomic_t          rt_lastuse;<br />
    struct hh_cache   *rt_hh;<br />
    struct device     *rt_dev;<br />
    unsigned short    rt_flags;<br />
    unsigned short    rt_mtu;<br />
    unsigned short    rt_irtt;<br />
    unsigned char     rt_tos;<br />
};<br />
semaphore</p>
<p>Semaphores are used to protect critical data structures and regions of code. y<br />
struct semaphore {<br />
    int count;<br />
    int waking;<br />
    int lock ;                /* to make waking testing atomic */<br />
    struct wait_queue *wait;<br />
};<br />
sk_buff</p>
<p>The sk_buff data structure is used to describe network data as it moves between the layers of protocol.<br />
struct sk_buff<br />
{<br />
  struct sk_buff      *next;       /* Next buffer in list                   */<br />
  struct sk_buff      *prev;       /* Previous buffer in list               */<br />
  struct sk_buff_head *list;       /* List we are on                        */<br />
  int                 magic_debug_cookie;<br />
  struct sk_buff      *link3;      /* Link for IP protocol level buffer chains */<br />
  struct sock         *sk;         /* Socket we are owned by                */<br />
  unsigned long       when;        /* used to compute rtt&#8217;s                 */<br />
  struct timeval      stamp;       /* Time we arrived                       */<br />
  struct device       *dev;        /* Device we arrived on/are leaving by   */<br />
  union<br />
  {<br />
      struct tcphdr   *th;<br />
      struct ethhdr   *eth;<br />
      struct iphdr    *iph;<br />
      struct udphdr   *uh;<br />
      unsigned char   *raw;<br />
      /* for passing file handles in a unix domain socket */<br />
      void            *filp;<br />
  } h;</p>
<p>  union<br />
  {<br />
      /* As yet incomplete physical layer views */<br />
      unsigned char   *raw;<br />
      struct ethhdr   *ethernet;<br />
  } mac;</p>
<p>  struct iphdr        *ip_hdr;     /* For IPPROTO_RAW                       */<br />
  unsigned long       len;         /* Length of actual data                 */<br />
  unsigned long       csum;        /* Checksum                              */<br />
  __u32               saddr;       /* IP source address                     */<br />
  __u32               daddr;       /* IP target address                     */<br />
  __u32               raddr;       /* IP next hop address                   */<br />
  __u32               seq;         /* TCP sequence number                   */<br />
  __u32               end_seq;     /* seq [+ fin] [+ syn] + datalen         */<br />
  __u32               ack_seq;     /* TCP ack sequence number               */<br />
  unsigned char       proto_priv[16];<br />
  volatile char       acked,       /* Are we acked ?                        */<br />
                      used,        /* Are we in use ?                       */<br />
                      free,        /* How to free this buffer               */<br />
                      arp;         /* Has IP/ARP resolution finished        */<br />
  unsigned char       tries,       /* Times tried                           */<br />
                      lock,        /* Are we locked ?                       */<br />
                      localroute,  /* Local routing asserted for this frame */<br />
                      pkt_type,    /* Packet class                          */<br />
                      pkt_bridged, /* Tracker for bridging                  */<br />
                      ip_summed;   /* Driver fed us an IP checksum          */<br />
#define PACKET_HOST         0        /* To us                                 */<br />
#define PACKET_BROADCAST    1        /* To all                                */<br />
#define PACKET_MULTICAST    2        /* To group                              */<br />
#define PACKET_OTHERHOST    3        /* To someone else                       */<br />
  unsigned short      users;       /* User count &#8211; see datagram.c,tcp.c     */<br />
  unsigned short      protocol;    /* Packet protocol from driver.          */<br />
  unsigned int        truesize;    /* Buffer size                           */<br />
  atomic_t            count;       /* reference count                       */<br />
  struct sk_buff      *data_skb;   /* Link to the actual data skb           */<br />
  unsigned char       *head;       /* Head of buffer                        */<br />
  unsigned char       *data;       /* Data head pointer                     */<br />
  unsigned char       *tail;       /* Tail pointer                          */<br />
  unsigned char       *end;        /* End pointer                           */<br />
  void                (*destructor)(struct sk_buff *); /* Destruct function */<br />
  __u16               redirport;   /* Redirect port                         */<br />
};<br />
sock</p>
<p>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.<br />
struct sock<br />
{<br />
    /* This must be first. */<br />
    struct sock             *sklist_next;<br />
    struct sock             *sklist_prev;</p>
<p>    struct options          *opt;<br />
    atomic_t                wmem_alloc;<br />
    atomic_t                rmem_alloc;<br />
    unsigned long           allocation;       /* Allocation mode */<br />
    __u32                   write_seq;<br />
    __u32                   sent_seq;<br />
    __u32                   acked_seq;<br />
    __u32                   copied_seq;<br />
    __u32                   rcv_ack_seq;<br />
    unsigned short          rcv_ack_cnt;      /* count of same ack */<br />
    __u32                   window_seq;<br />
    __u32                   fin_seq;<br />
    __u32                   urg_seq;<br />
    __u32                   urg_data;<br />
    __u32                   syn_seq;<br />
    int                     users;            /* user count */<br />
  /*<br />
   *    Not all are volatile, but some are, so we<br />
   *     might as well say they all are.<br />
   */<br />
    volatile char           dead,<br />
                            urginline,<br />
                            intr,<br />
                            blog,<br />
                            done,<br />
                            reuse,<br />
                            keepopen,<br />
                            linger,<br />
                            delay_acks,<br />
                            destroy,<br />
                            ack_timed,<br />
                            no_check,<br />
                            zapped,<br />
                            broadcast,<br />
                            nonagle,<br />
                            bsdism;<br />
    unsigned long           lingertime;<br />
    int                     proc;</p>
<p>    struct sock             *next;<br />
    struct sock             **pprev;<br />
    struct sock             *bind_next;<br />
    struct sock             **bind_pprev;<br />
    struct sock             *pair;<br />
    int                     hashent;<br />
    struct sock             *prev;<br />
    struct sk_buff          *volatile send_head;<br />
    struct sk_buff          *volatile send_next;<br />
    struct sk_buff          *volatile send_tail;<br />
    struct sk_buff_head     back_log;<br />
    struct sk_buff          *partial;<br />
    struct timer_list       partial_timer;<br />
    long                    retransmits;<br />
    struct sk_buff_head     write_queue,<br />
                            receive_queue;<br />
    struct proto            *prot;<br />
    struct wait_queue       **sleep;<br />
    __u32                   daddr;<br />
    __u32                   saddr;            /* Sending source */<br />
    __u32                   rcv_saddr;        /* Bound address */<br />
    unsigned short          max_unacked;<br />
    unsigned short          window;<br />
    __u32                   lastwin_seq;      /* sequence number when we last<br />
                                                 updated the window we offer */<br />
    __u32                   high_seq;         /* sequence number when we did<br />
                                                 current fast retransmit */<br />
    volatile unsigned long  ato;              /* ack timeout */<br />
    volatile unsigned long  lrcvtime;         /* jiffies at last data rcv */<br />
    volatile unsigned long  idletime;         /* jiffies at last rcv */<br />
    unsigned int            bytes_rcv;<br />
/*<br />
 *    mss is min(mtu, max_window)<br />
 */<br />
    unsigned short          mtu;              /* mss negotiated in the syn&#8217;s */<br />
    volatile unsigned short mss;              /* current eff. mss &#8211; can change */<br />
    volatile unsigned short user_mss;         /* mss requested by user in ioctl */<br />
    volatile unsigned short max_window;<br />
    unsigned long           window_clamp;<br />
    unsigned int            ssthresh;<br />
    unsigned short          num;<br />
    volatile unsigned short cong_window;<br />
    volatile unsigned short cong_count;<br />
    volatile unsigned short packets_out;<br />
    volatile unsigned short shutdown;<br />
    volatile unsigned long  rtt;<br />
    volatile unsigned long  mdev;<br />
    volatile unsigned long  rto;</p>
<p>    volatile unsigned short backoff;<br />
    int                     err, err_soft;    /* Soft holds errors that don&#8217;t<br />
                                                 cause failure but are the cause<br />
                                                 of a persistent failure not<br />
                                                 just &#8216;timed out&#8217; */<br />
    unsigned char           protocol;<br />
    volatile unsigned char  state;<br />
    unsigned char           ack_backlog;<br />
    unsigned char           max_ack_backlog;<br />
    unsigned char           priority;<br />
    unsigned char           debug;<br />
    int                     rcvbuf;<br />
    int                     sndbuf;<br />
    unsigned short          type;<br />
    unsigned char           localroute;       /* Route locally only */<br />
/*<br />
 *    This is where all the private (optional) areas that don&#8217;t<br />
 *    overlap will eventually live.<br />
 */<br />
    union<br />
    {<br />
          struct unix_opt   af_unix;<br />
#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)<br />
        struct atalk_sock   af_at;<br />
#endif<br />
#if defined(CONFIG_IPX) || defined(CONFIG_IPX_MODULE)<br />
        struct ipx_opt      af_ipx;<br />
#endif<br />
#ifdef CONFIG_INET<br />
        struct inet_packet_opt  af_packet;<br />
#ifdef CONFIG_NUTCP<br />
        struct tcp_opt      af_tcp;<br />
#endif<br />
#endif<br />
    } protinfo;<br />
/*<br />
 *    IP &#8216;private area&#8217;<br />
 */<br />
    int                     ip_ttl;           /* TTL setting */<br />
    int                     ip_tos;           /* TOS */<br />
    struct tcphdr           dummy_th;<br />
    struct timer_list       keepalive_timer;  /* TCP keepalive hack */<br />
    struct timer_list       retransmit_timer; /* TCP retransmit timer */<br />
    struct timer_list       delack_timer;     /* TCP delayed ack timer */<br />
    int                     ip_xmit_timeout;  /* Why the timeout is running */<br />
    struct rtable           *ip_route_cache;  /* Cached output route */<br />
    unsigned char           ip_hdrincl;       /* Include headers ? */<br />
#ifdef CONFIG_IP_MULTICAST<br />
    int                     ip_mc_ttl;        /* Multicasting TTL */<br />
    int                     ip_mc_loop;       /* Loopback */<br />
    char                    ip_mc_name[MAX_ADDR_LEN]; /* Multicast device name */<br />
    struct ip_mc_socklist   *ip_mc_list;      /* Group array */<br />
#endif  </p>
<p>/*<br />
 *    This part is used for the timeout functions (timer.c).<br />
 */<br />
    int                      timeout;         /* What are we waiting for? */<br />
    struct timer_list        timer;           /* This is the TIME_WAIT/receive<br />
                                               * timer when we are doing IP<br />
                                               */<br />
    struct timeval           stamp;<br />
 /*<br />
  *    Identd<br />
  */<br />
    struct socket            *socket;<br />
  /*<br />
   *    Callbacks<br />
   */<br />
    void                     (*state_change)(struct sock *sk);<br />
    void                     (*data_ready)(struct sock *sk,int bytes);<br />
    void                     (*write_space)(struct sock *sk);<br />
    void                     (*error_report)(struct sock *sk);</p>
<p>};<br />
socket</p>
<p>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.<br />
struct socket {<br />
  short                type;         /* SOCK_STREAM, &#8230;             */<br />
  socket_state         state;<br />
  long                 flags;<br />
  struct proto_ops     *ops;         /* protocols do most everything */<br />
  void                 *data;        /* protocol data                */<br />
  struct socket        *conn;        /* server socket connected to   */<br />
  struct socket        *iconn;       /* incomplete client conn.s     */<br />
  struct socket        *next;<br />
  struct wait_queue    **wait;       /* ptr to place to wait on      */<br />
  struct inode         *inode;<br />
  struct fasync_struct *fasync_list; /* Asynchronous wake up list    */<br />
  struct file          *file;        /* File back pointer for gc     */<br />
};<br />
task_struct</p>
<p>Each task_struct data structure describes a process or task in the system.<br />
struct task_struct {<br />
/* these are hardcoded &#8211; don&#8217;t touch */<br />
  volatile long        state;          /* -1 unrunnable, 0 runnable, &gt;0 stopped */<br />
  long                 counter;<br />
  long                 priority;<br />
  unsigned             long signal;<br />
  unsigned             long blocked;   /* bitmap of masked signals */<br />
  unsigned             long flags;     /* per process flags, defined below */<br />
  int errno;<br />
  long                 debugreg[8];    /* Hardware debugging registers */<br />
  struct exec_domain   *exec_domain;<br />
/* various fields */<br />
  struct linux_binfmt  *binfmt;<br />
  struct task_struct   *next_task, *prev_task;<br />
  struct task_struct   *next_run,  *prev_run;<br />
  unsigned long        saved_kernel_stack;<br />
  unsigned long        kernel_stack_page;<br />
  int                  exit_code, exit_signal;<br />
  /* ??? */<br />
  unsigned long        personality;<br />
  int                  dumpable:1;<br />
  int                  did_exec:1;<br />
  int                  pid;<br />
  int                  pgrp;<br />
  int                  tty_old_pgrp;<br />
  int                  session;<br />
  /* boolean value for session group leader */<br />
  int                  leader;<br />
  int                  groups[NGROUPS];<br />
  /*<br />
   * pointers to (original) parent process, youngest child, younger sibling,<br />
   * older sibling, respectively.  (p-&gt;father can be replaced with<br />
   * p-&gt;p_pptr-&gt;pid)<br />
   */<br />
  struct task_struct   *p_opptr, *p_pptr, *p_cptr,<br />
                       *p_ysptr, *p_osptr;<br />
  struct wait_queue    *wait_chldexit;<br />
  unsigned short       uid,euid,suid,fsuid;<br />
  unsigned short       gid,egid,sgid,fsgid;<br />
  unsigned long        timeout, policy, rt_priority;<br />
  unsigned long        it_real_value, it_prof_value, it_virt_value;<br />
  unsigned long        it_real_incr, it_prof_incr, it_virt_incr;<br />
  struct timer_list    real_timer;<br />
  long                 utime, stime, cutime, cstime, start_time;<br />
/* mm fault and swap info: this can arguably be seen as either<br />
   mm-specific or thread-specific */<br />
  unsigned long        min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;<br />
  int swappable:1;<br />
  unsigned long        swap_address;<br />
  unsigned long        old_maj_flt;    /* old value of maj_flt */<br />
  unsigned long        dec_flt;        /* page fault count of the last time */<br />
  unsigned long        swap_cnt;       /* number of pages to swap on next pass */<br />
/* limits */<br />
  struct rlimit        rlim[RLIM_NLIMITS];<br />
  unsigned short       used_math;<br />
  char                 comm[16];<br />
/* file system info */<br />
  int                  link_count;<br />
  struct tty_struct    *tty;           /* NULL if no tty */<br />
/* ipc stuff */<br />
  struct sem_undo      *semundo;<br />
  struct sem_queue     *semsleeping;<br />
/* ldt for this task &#8211; used by Wine.  If NULL, default_ldt is used */<br />
  struct desc_struct *ldt;<br />
/* tss for this task */<br />
  struct thread_struct tss;<br />
/* filesystem information */<br />
  struct fs_struct     *fs;<br />
/* open file information */<br />
  struct files_struct  *files;<br />
/* memory management info */<br />
  struct mm_struct     *mm;<br />
/* signal handlers */<br />
  struct signal_struct *sig;<br />
#ifdef __SMP__<br />
  int                  processor;<br />
  int                  last_processor;<br />
  int                  lock_depth;     /* Lock depth.<br />
                                          We can context switch in and out<br />
                                          of holding a syscall kernel lock&#8230; */<br />
#endif<br />
};<br />
timer_list</p>
<p>timer_list data structure&#8217;s are used to implement real time timers for processes.<br />
struct timer_list {<br />
  struct timer_list *next;<br />
  struct timer_list *prev;<br />
  unsigned long expires;<br />
  unsigned long data;<br />
  void (*function)(unsigned long);<br />
};<br />
tq_struct</p>
<p>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.<br />
struct tq_struct {<br />
    struct tq_struct *next;   /* linked list of active bh&#8217;s */<br />
    int sync;                 /* must be initialized to zero */<br />
    void (*routine)(void *);  /* function to call */<br />
    void *data;               /* argument to function */<br />
};<br />
vm_area_struct</p>
<p>Each vm_area_struct data structure describes an area of virtual memory for a process.<br />
struct vm_area_struct {<br />
  struct mm_struct * vm_mm;  /* VM area parameters */<br />
  unsigned long vm_start;<br />
  unsigned long vm_end;<br />
  pgprot_t vm_page_prot;<br />
  unsigned short vm_flags;<br />
/* AVL tree of VM areas per task, sorted by address */<br />
  short vm_avl_height;<br />
  struct vm_area_struct * vm_avl_left;<br />
  struct vm_area_struct * vm_avl_right;<br />
/* linked list of VM areas per task, sorted by address */<br />
  struct vm_area_struct * vm_next;<br />
/* for areas with inode, the circular list inode-&gt;i_mmap */<br />
/* for shm areas, the circular list of attaches */<br />
/* otherwise unused */<br />
  struct vm_area_struct * vm_next_share;<br />
  struct vm_area_struct * vm_prev_share;<br />
/* more */<br />
  struct vm_operations_struct * vm_ops;<br />
  unsigned long vm_offset;<br />
  struct inode * vm_inode;<br />
  unsigned long vm_pte;      /* shared mem */<br />
};</p>
]]></content:encoded>
			<wfw:commentRss>https://www.emblogic.com/blog/01/linux-data-structures/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How the Command Line Parsing Works</title>
		<link>https://www.emblogic.com/blog/12/how-the-command-line-parsing-works/</link>
		<comments>https://www.emblogic.com/blog/12/how-the-command-line-parsing-works/#comments</comments>
		<pubDate>Fri, 30 Dec 2016 04:52:04 +0000</pubDate>
		<dc:creator><![CDATA[Shubham Gupta]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.emblogic.com/blog/?p=13832</guid>
		<description><![CDATA[How the Command Line Parsing Works There are two different command line parsers available with U-Boot: the old &#8220;simple&#8221; one, and the much more powerful &#8220;hush&#8221; shell: Old, simple command line parser supports environment variables (through setenv / saveenv commands) &#8230; <a href="https://www.emblogic.com/blog/12/how-the-command-line-parsing-works/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>How the Command Line Parsing Works<br />
There are two different command line parsers available with U-Boot: the old &#8220;simple&#8221; one, and the much more powerful &#8220;hush&#8221; shell:</p>
<p> Old, simple command line parser<br />
supports environment variables (through setenv / saveenv commands)<br />
several commands on one line, separated by &#8216;;&#8217;</p>
<p>variable substitution using &#8220;&#8230; ${_variablename_} &#8230;&#8221; syntax<br />
ALERT! NOTE: Older versions of U-Boot used &#8220;$(&#8230;)&#8221; for variable substitution. Support for this syntax is still present in current versions, but will be removed soon. Please use &#8220;${&#8230;}&#8221; instead, which has the additional benefit that your environment definitions are compatible with the Hush shell, too.<br />
special characters (&#8216;$&#8217;, &#8216;;&#8217;) can be escaped by prefixing with &#8216;\&#8217;, for example:<br />
        setenv bootcmd bootm \${address}<br />
You can also escape text by enclosing in single apostrophes, for example:<br />
        setenv addip &#8216;setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off&#8217;</p>
<p>Hush shell</p>
<p>similar to Bourne shell, with control structures like if&#8230;then&#8230;else&#8230;fi, for&#8230;do&#8230;done, while&#8230;do&#8230;done, until&#8230;do&#8230;done, &#8230;<br />
supports environment (&#8220;global&#8221;) 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).<br />
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 &#8216;$name&#8217; or &#8216;${name}&#8217;; to execute the contents of a variable directly you can type &#8216;$name&#8217; at the command prompt. Note that local variables can only be used for simple commands, not for compound commands etc.<br />
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 &#8216;$&#8217; sign to access them.<br />
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.<br />
Be careful when using the hash (&#8216;#&#8217;) character &#8211; like with a &#8220;real&#8221; Bourne shell it is the comment character, so you have to escape it when you use it in the value of a variable.<br />
Examples:</p>
<p>        setenv bootcmd bootm \$address<br />
        setenv addip &#8216;setenv bootargs $bootargs ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off&#8217;</p>
<p>Hush shell scripts<br />
Here are a few examples for the use of the advanced capabilities of the hush shell in U-Boot environment variables or scripts:</p>
<p>Example:</p>
<p>=&gt; setenv check &#8216;if imi $addr; then echo Image OK; else echo Image corrupted!!; fi&#8217;<br />
=&gt; print check<br />
check=if imi $addr; then echo Image OK; else echo Image corrupted!!; fi<br />
=&gt; addr=0 ; run check</p>
<p>## Checking Image at 00000000 &#8230;<br />
   Bad Magic Number<br />
Image corrupted!!<br />
=&gt; addr=40000 ;run check</p>
<p>## Checking Image at 00040000 &#8230;<br />
   Image Name:   ARM Linux-2.4.18<br />
   Created:      2003-06-02  14:10:54 UTC<br />
   Image Type:   ARM Linux Kernel Image (gzip compressed)<br />
   Data Size:    801609 Bytes = 782.8 kB<br />
   Load Address: 0c008000<br />
   Entry Point:  0c008000<br />
   Verifying Checksum &#8230; OK<br />
Image OK<br />
Instead of &#8220;echo Image OK&#8221; there could be a command (sequence) to boot or otherwise deal with the correct image; instead of the &#8220;echo Image corrupted!!&#8221; there could be a command (sequence) to (load and) boot an alternative image, etc. </p>
<p>Example:</p>
<p>=&gt; addr1=0<br />
=&gt; addr2=10<br />
=&gt; bootm $addr1 || bootm $addr2 || tftpboot $loadaddr $loadfile &amp;&amp; bootm<br />
## Booting image at 00000000 &#8230;<br />
Bad Magic Number<br />
## Booting image at 00000010 &#8230;<br />
Bad Magic Number<br />
TFTP from server 192.168.3.1; our IP address is 192.168.3.68<br />
Filename &#8216;/tftpboot/TRAB/uImage&#8217;.<br />
Load address: 0xc400000<br />
Loading: #################################################################<br />
         #################################################################<br />
         ###########################<br />
done<br />
Bytes transferred = 801673 (c3b89 hex)<br />
## Booting image at 0c400000 &#8230;<br />
   Image Name:   ARM Linux-2.4.18<br />
This will check if the image at (flash?) address &#8220;addr1&#8243; is ok and boot it; if the image is not ok, the alternative image at address &#8220;addr2&#8243; 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.<br />
14.2.17.4. General rules<br />
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.<br />
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.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.emblogic.com/blog/12/how-the-command-line-parsing-works/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>U-Boot Standalone Applications</title>
		<link>https://www.emblogic.com/blog/12/u-boot-standalone-applications/</link>
		<comments>https://www.emblogic.com/blog/12/u-boot-standalone-applications/#comments</comments>
		<pubDate>Thu, 29 Dec 2016 12:27:31 +0000</pubDate>
		<dc:creator><![CDATA[Shubham Gupta]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.emblogic.com/blog/?p=13829</guid>
		<description><![CDATA[U-Boot Standalone Applications U-Boot supports &#8220;standalone&#8221; 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. &#8230; <a href="https://www.emblogic.com/blog/12/u-boot-standalone-applications/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>U-Boot Standalone Applications<br />
U-Boot supports &#8220;standalone&#8221; applications, which are loaded dynamically; these applications can have access to the U-Boot console I/O functions, memory allocation and interrupt services.</p>
<p>A couple of simple examples are included with the U-Boot source code:</p>
<p>5.12.1. &#8220;Hello World&#8221; Demo<br />
examples/hello_world.c contains a small &#8220;Hello World&#8221; Demo application; it is automatically compiled when you build U-Boot. It&#8217;s configured to run at address 0&#215;00040000, so you can play with it like that:</p>
<p>TIP Note that the entry point of the program is at 0&#215;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.</p>
<p>=&gt; loads<br />
## Ready for S-Record download &#8230;<br />
~&gt;examples/hello_world.srec<br />
1 2 3 4 5 6 7 8 9 10 11 &#8230;<br />
[file transfer complete]<br />
[connected]<br />
## Start Addr = 0&#215;00040000</p>
<p>=&gt; go 40000 Hello World! This is a test.<br />
## Starting application at 0&#215;00040000 &#8230;<br />
Hello World<br />
argc = 7<br />
argv[0] = &#8220;40000&#8243;<br />
argv[1] = &#8220;Hello&#8221;<br />
argv[2] = &#8220;World!&#8221;<br />
argv[3] = &#8220;This&#8221;<br />
argv[4] = &#8220;is&#8221;<br />
argv[5] = &#8220;a&#8221;<br />
argv[6] = &#8220;test.&#8221;<br />
argv[7] = &#8220;&#8221;<br />
Hit any key to exit &#8230;</p>
<p>## Application terminated, rc = 0&#215;0<br />
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.</p>
<p>=&gt; tftp 40000 /tftpboot/hello_world.bin<br />
&#8230;<br />
=&gt; go 40000 This is another test.<br />
## Starting application at 0&#215;00040000 &#8230;<br />
Hello World<br />
argc = 5<br />
argv[0] = &#8220;40000&#8243;<br />
argv[1] = &#8220;This&#8221;<br />
argv[2] = &#8220;is&#8221;<br />
argv[3] = &#8220;another&#8221;<br />
argv[4] = &#8220;test.&#8221;<br />
argv[5] = &#8220;&#8221;<br />
Hit any key to exit &#8230;</p>
<p>## Application terminated, rc = 0&#215;0<br />
5.12.2. Timer Demo<br />
ALERT! This example is only available on MPC8xx CPUs.</p>
<p>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 &#8216;.&#8217; character, but this is just a demo program. The application can be controlled by the following keys:</p>
<p>   ? &#8211; print current values of the CPM Timer registers<br />
   b &#8211; enable interrupts and start timer<br />
   e &#8211; stop timer and disable interrupts<br />
   q &#8211; quit application</p>
<p> =&gt; loads<br />
   ## Ready for S-Record download &#8230;<br />
   ~&gt;examples/timer.srec<br />
   1 2 3 4 5 6 7 8 9 10 11 &#8230;<br />
   [file transfer complete]<br />
   [connected]<br />
   ## Start Addr = 0&#215;00040000</p>
<p> =&gt; go 40000<br />
   ## Starting application at 0&#215;00040000 &#8230;<br />
   TIMERS=0xfff00980<br />
   Using timer 1<br />
     tgcr @ 0xfff00980, tmr @ 0xfff00990, trr @ 0xfff00994, tcr @ 0xfff00998, tcn @ 0xfff0099c, ter @ 0xfff009b0</p>
<p>Hit &#8216;b&#8217;:<br />
   [q, b, e, ?] Set interval 1000000 us<br />
   Enabling timer<br />
Hit &#8216;?&#8217;:<br />
   [q, b, e, ?] &#8230;&#8230;..<br />
   tgcr=0&#215;1, tmr=0xff1c, trr=0x3d09, tcr=0&#215;0, tcn=0xef6, ter=0&#215;0<br />
Hit &#8216;?&#8217;:<br />
   [q, b, e, ?] .<br />
   tgcr=0&#215;1, tmr=0xff1c, trr=0x3d09, tcr=0&#215;0, tcn=0x2ad4, ter=0&#215;0<br />
Hit &#8216;?&#8217;:<br />
   [q, b, e, ?] .<br />
   tgcr=0&#215;1, tmr=0xff1c, trr=0x3d09, tcr=0&#215;0, tcn=0x1efc, ter=0&#215;0<br />
Hit &#8216;?&#8217;:<br />
   [q, b, e, ?] .<br />
   tgcr=0&#215;1, tmr=0xff1c, trr=0x3d09, tcr=0&#215;0, tcn=0x169d, ter=0&#215;0<br />
Hit &#8216;e&#8217;:<br />
   [q, b, e, ?] &#8230;Stopping timer<br />
Hit &#8216;q&#8217;:<br />
   [q, b, e, ?] ## Application terminated, rc = 0&#215;0<br />
5.12.3. Processor cache considerations<br />
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.</p>
<p>In the &#8220;Hello World&#8221; 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.</p>
<p>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.</p>
<p>To prepare an image of the &#8220;Hello World&#8221; 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</p>
<p>IMG = $(BOARD)_standalone.img<br />
IMG := $(addprefix $(obj),$(IMG))<br />
$(IMG):<br />
$(obj)%.img: $(BIN)<br />
   $(MKIMAGE) -n &#8220;Hello stand alone&#8221; -A ppc -O u-boot -T standalone -C none -a $(LOAD_ADDR) -d $(BIN) -v $@<br />
With this preparatory step added to the Makefile, the previously given &#8220;Hello World&#8221; console output example becomes</p>
<p>=&gt; tftp 600000 helloworld.img<br />
&#8230;<br />
=&gt; bootm 600000 Hello World! This is a test.<br />
WARNING: adjusting available memory to 30000000<br />
## Booting kernel from Legacy Image at 600000 &#8230;<br />
   Image Name:   Hello stand alone<br />
   Image Type:   PowerPC U-Boot Standalone Program (uncompressed)<br />
   Data Size:    25391 Bytes = 24.8 KiB<br />
   Load Address: 00040000<br />
   Entry Point:  00040000<br />
   Verifying Checksum &#8230; OK<br />
Hello World<br />
argc = 7<br />
argv[0] = &#8220;600000&#8243;<br />
argv[1] = &#8220;Hello&#8221;<br />
argv[2] = &#8220;World!&#8221;<br />
argv[3] = &#8220;This&#8221;<br />
argv[4] = &#8220;is&#8221;<br />
argv[5] = &#8220;a&#8221;<br />
argv[6] = &#8220;test.&#8221;<br />
argv[7] = &#8220;&#8221;<br />
Hit any key to exit &#8230;</p>
<p>=&gt;<br />
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.</p>
<p>5.12.4. Running on core other than core 0<br />
For Freescale PowerPC-based multi-core system, the following can be said.</p>
<p>U-Boot facilities are not available to stand alone applications, since U-Boot runs only on core 0</p>
<p>From Scott Wood ():</p>
<p>If you have true standalone code, you can release it on other CPUs using the<br />
&#8220;cpu  release&#8221; command.  That code will not have access to any U-Boot<br />
functionality.  Its entry state will be as described for secondary CPUs in [the]<br />
ePAPR [specification]. It will be the same as if an OS were spinning up its<br />
secondary cores by writing directly to the spin table.<br />
The ePAPR specification can be found at https://www.power.org/documentation/epapr-version-1-1/.</p>
<p>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.</p>
]]></content:encoded>
			<wfw:commentRss>https://www.emblogic.com/blog/12/u-boot-standalone-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Universal Boot Loader (&#8220;Das U-Boot&#8221;)</title>
		<link>https://www.emblogic.com/blog/12/the-universal-boot-loader-das-u-boot/</link>
		<comments>https://www.emblogic.com/blog/12/the-universal-boot-loader-das-u-boot/#comments</comments>
		<pubDate>Thu, 29 Dec 2016 12:15:13 +0000</pubDate>
		<dc:creator><![CDATA[Shubham Gupta]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.emblogic.com/blog/?p=13827</guid>
		<description><![CDATA[The Universal Boot Loader (&#8220;Das U-Boot&#8221;) 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 &#8230; <a href="https://www.emblogic.com/blog/12/the-universal-boot-loader-das-u-boot/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p> The Universal Boot Loader (&#8220;Das U-Boot&#8221;)<br />
Table of contents:<br />
1. Abstract<br />
? 1.1. Introduction<br />
? 1.2. History<br />
? 1.3. Supported Hardware<br />
? 1.4. Design Principles<br />
? 1.5. User Interface<br />
? 1.6. Basic Command Set<br />
1.7. Advanced Commands<br />
? 1.7.1. Logbuffer Manipulation Commands<br />
? 1.7.2. Bedbug Embedded Debugger Commands<br />
? 1.7.3. POST &#8211; Hardware Diagnose Commands<br />
?<br />
? 1.8. Environment Variables<br />
? 1.9. Boot Options<br />
? 1.10. Command Interpreters<br />
? 1.11. Standalone Programs<br />
1.12. Special Features<br />
? 1.12.1. Bitmap and Splash Screen Support<br />
? 1.12.2. Boot Count Limit<br />
? 1.12.3. Keyboard Support<br />
? 1.12.4. Automatic Updates</p>
<p>1.1. Introduction<br />
• The &#8220;Universal Bootloader&#8221; (&#8220;Das U-Boot&#8221;) is a monitor program.<br />
• Free Software: full source code under GPL<br />
• hosted on SourceForge: http://sourceforge.net/projects/u-boot<br />
• production quality: used as default boot loader by several board vendors<br />
• portable and easy to port and to debug<br />
• many supported architectures: PPC, ARM, MIPS, x86, m68k, NIOS, Microblaze<br />
• more than 216 boards supported by public source tree<br />
• many, many features<br />
1.1. Introduction 1<br />
1.2. History<br />
• Oct 22, 1999: fadsrom &#8211; Dan Malek =&gt; PPCBoot rev. 1.1<br />
• Dec 18, 1999: 8xxrom-0.3.0 &#8211; Magnus Damm, Raphael Bossek =&gt; PPCBoot rev. 1.2<br />
• Jul 07, 2000: Wolfgang Denk =&gt; PPCBoot rev. 1.3<br />
Jul 19, 2000: Wolfgang Denk =&gt; PPCBoot-0.4.1<br />
first public version of PPCBoot<br />
•<br />
Siemens PSE, Vienna: Development of a Bluetooth LAN Access Point with a MPC850 Processor that<br />
needed to be able to boot over Ethernet =&gt; first commercial sponsor<br />
•<br />
Aug 08, 2000: PPCBoot rev. 1.4 = PPCBoot-0.4.2<br />
(only PPC, only MPC8xx, 4 boards)<br />
•<br />
• Oct 01, 2000: added network support =&gt; PPCBoot-0.4.4<br />
• Oct 01, 2000: Stefan Roese: add support for IBM PPC401/403/405GP processors =&gt; PPCBoot-0.5.1<br />
• Nov 16, 2000: Murray Jensen: add support for MPC8260 =&gt; PPCBoot-0.6.2<br />
• Nov 20, 2000: Rob Taylor: add support for MPC8240 =&gt; PPCBoot-0.6.3<br />
• End 2000: PPCBoot-0.7.1 (MPC8xx, MPC8240, MPC8260, PPC401/403/405GP; 27 boards)<br />
• End 2001: PPCBoot-1.1.3 (MPC8xx, MPC8240, MPC8260, 7xx, 74xx, IBM 4xx, 63 boards)<br />
• Mar 2002: SYSGO: split ARMBoot project, separate (incompatible) source tree<br />
• Jul 2002: begin merging with ARMBoot tree<br />
Nov 2002: PPCBoot-2.0.0 (last release of PPCBoot)<br />
(PPC: 8xx, 824x, 826x, 7xx, 74xx, 4xx; ARM: StrongARM, ARM7, ARM9, XScale; &gt;106 boards)<br />
=&gt; Start U-Boot project: PPCBoot-2.0.0 = U-Boot-0.1.0<br />
•<br />
• Nov 2002: x86 support<br />
• Mar 2003: MIPS32<br />
• Apr 2003: MIPS64<br />
• Oct 2003: Altera NIOS-32<br />
• Dec 2003: Coldfire<br />
• Apr 2004: Microblaze<br />
today (31 May 2004): U-Boot-1.1.2<br />
(PPC: 5xx, 5xxx, 8xx, 824x, 826x, 85xx, 7xx, 74xx, 4xx;<br />
ARM: StrongARM, ARM720T, ARM92xT, S3C44B0, AT91RM9200, XScale;<br />
x86: SC520; m68k: Coldfire; MIPS32: 4Kc, Au1x00; MIPS64: 5Kc; NIOS32; Microblaze;<br />
&gt;216 boards in public tree; many more not submitted back<br />
•<br />
• several board manufacturers use U-Boot as default firmware on some or all of their boards<br />
1.3. Supported Hardware<br />
Architecture Processor Number of Boards<br />
PPC 5xx 2<br />
5xxx 6<br />
8xx 71<br />
824x 15<br />
826x 26<br />
85xx 3<br />
1.3. Supported Hardware 2<br />
7xx/74xx 11<br />
4xx 38<br />
ARM StrongARM 5<br />
ARM720T 3<br />
ARM92xT 11<br />
S3C44B0 1<br />
AT91RM9200 1<br />
XScale 8<br />
x86 SC520 2<br />
m68k Coldfire 2<br />
MIPS32 4Kc 2<br />
Au1x00 3<br />
MIPS64 5Kc 1<br />
NIOS32 3<br />
Microblaze 1<br />
Blackfin BF5xx 18<br />
1.4. Design Principles<br />
• easy to port to new architectures, new processors, and new boards<br />
• easy to debug: serial console output as soon as possible<br />
• features and commands configurable<br />
• as small as possible<br />
• as reliable as possible<br />
1.5. User Interface<br />
U-Boot uses a simple command line interface (CLI), usually over a serial console port.<br />
Two different command interpreters are available:<br />
• simple CLI<br />
• Bourne compatible shell (HUSH shell from Busybox)<br />
Configuration parameters and commands / command sequences (scripts !) can be stored in &#8220;environment<br />
variables&#8221; which can be saved to non-volatile storage (flash, EEPROM, NVRAM, etc.)<br />
1.5. User Interface 3<br />
1.6. Basic Command Set<br />
Information Commands<br />
? bdinfo &#8211; print Board Info structure<br />
? coninfo &#8211; print console devices and informations<br />
? flinfo &#8211; print FLASH memory information<br />
? iminfo &#8211; print header information for application image<br />
? imls &#8211; list all images found in flash<br />
? help &#8211; print online help<br />
•<br />
Memory Commands<br />
? base &#8211; print or set address offset<br />
? crc32 &#8211; checksum calculation<br />
? cmp &#8211; memory compare<br />
? cp &#8211; memory copy<br />
? md &#8211; memory display<br />
? mm &#8211; memory modify (auto-incrementing)<br />
? mtest &#8211; simple RAM test<br />
? mw &#8211; memory write (fill)<br />
? nm &#8211; memory modify (constant address)<br />
? loop &#8211; infinite loop on address range<br />
•<br />
Flash Memory Commands<br />
? cp &#8211; memory copy (program flash)<br />
? flinfo &#8211; print FLASH memory information<br />
? erase &#8211; erase FLASH memory<br />
? protect &#8211; enable or disable FLASH write protection<br />
•<br />
Execution Control Commands<br />
? autoscr &#8211; run script from memory<br />
? bootm &#8211; boot application image from memory<br />
? bootelf &#8211; Boot from an ELF image in memory<br />
? bootvx &#8211; Boot vxWorks from an ELF image<br />
? go &#8211; start application at address &#8216;addr&#8217;<br />
•<br />
Network Commands<br />
? bootp &#8211; boot image via network using BOOTP/TFTP protocol<br />
? cdp &#8211; Perform Cisco Discovery Protocol network configuration<br />
? dhcp &#8211; invoke DHCP client to obtain IP/boot params<br />
? loadb &#8211; load binary file over serial line (kermit mode)<br />
? loads &#8211; load S-Record file over serial line<br />
? nfs &#8211; boot image via network using NFS protocol<br />
? ping &#8211; send ICMP ECHO_REQUEST to network host<br />
? rarpboot- boot image via network using RARP/TFTP protocol<br />
? tftpboot- boot image via network using TFTP protocol<br />
•<br />
Environment Variables Commands<br />
? printenv- print environment variables<br />
? saveenv &#8211; save environment variables to persistent storage<br />
? askenv &#8211; get environment variables from stdin<br />
? setenv &#8211; set environment variables<br />
? run &#8211; run commands in an environment variable<br />
? bootd &#8211; boot default, i.e., run &#8216;bootcmd&#8217;<br />
•<br />
Filesystem Support (FAT, cramfs, JFFS2, Reiser)<br />
? chpart &#8211; change active partition<br />
•<br />
1.6. Basic Command Set 4<br />
? fsinfo &#8211; print information about filesystems<br />
? fsload &#8211; load binary file from a filesystem image<br />
? ls &#8211; list files in a directory (default /)<br />
? fatinfo &#8211; print information about filesystem<br />
? fatls &#8211; list files in a directory (default /)<br />
? fatload &#8211; load binary file from a dos filesystem<br />
? nand &#8211; NAND flash sub-system<br />
? reiserls- list files in a directory (default /)<br />
? reiserload- load binary file from a Reiser filesystem<br />
Special Commands<br />
? i2c &#8211; I2C sub-system<br />
? doc &#8211; Disk-On-Chip sub-system<br />
? dtt &#8211; Digital Thermometer and Themostat<br />
? eeprom &#8211; EEPROM sub-syste<br />
? fpga &#8211; FPGA sub-system<br />
? ide &#8211; IDE sub-system<br />
? kgdb &#8211; enter gdb remote debug mode<br />
? diskboot- boot from IDE device<br />
? icache &#8211; enable or disable instruction cache<br />
? dcache &#8211; enable or disable data cache<br />
? diag &#8211; perform board diagnostics (POST code)<br />
? log &#8211; manipulate logbuffer<br />
? pci &#8211; list and access PCI Configuraton Space<br />
? regdump &#8211; register dump commands<br />
? usb &#8211; USB sub-system<br />
? sspi &#8211; SPI utility commands<br />
•<br />
Miscellaneous Commands<br />
? bmp &#8211; manipulate BMP image data<br />
? date &#8211; get/set/reset date &amp; time<br />
? echo &#8211; echo args to console<br />
? exit &#8211; exit script<br />
? kbd &#8211; read keyboard status<br />
? in &#8211; read data from an IO port<br />
? out &#8211; write datum to IO port<br />
? reset &#8211; Perform RESET of the CPU<br />
? sleep &#8211; delay execution for some time<br />
? test &#8211; minimal test like /bin/sh<br />
? version &#8211; print monitor version<br />
? wd &#8211; check and set watchdog<br />
? ? &#8211; alias for &#8216;help&#8217;<br />
•<br />
1.7. Advanced Commands<br />
Some of the following commands depend on certain hardware features and may not be available on all boards.<br />
1.7. Advanced Commands 5<br />
1.7.1. Logbuffer Manipulation Commands<br />
Use a reserved area of system memory as log buffer;<br />
can be re-used by syslogd in Linux;<br />
content will survive reset / warm boot<br />
• log info &#8211; show pointer details<br />
• log log reset &#8211; clear contents<br />
• log log show &#8211; show contents<br />
• log log append &#8211; append to the logbuffer<br />
• setenv stdout log &#8211; redirect standard output to log buffer<br />
Used for example to pass POST results to Linux application code or for post-mortem checking of the Linux<br />
system logs.<br />
1.7.2. Bedbug Embedded Debugger Commands<br />
• ds &#8211; disassemble memory<br />
• as &#8211; assemble memory<br />
• break &#8211; set or clear a breakpoint<br />
• continue &#8211; continue from a breakpoint<br />
• step &#8211; single step execution.<br />
• next &#8211; single step execution, stepping over subroutines.<br />
• where &#8211; Print the running stack.<br />
• rdump &#8211; Show registers.<br />
1.7.3. POST &#8211; Hardware Diagnose Commands<br />
• cache &#8211; Cache test<br />
• watchdog &#8211; Watchdog timer test<br />
• i2c &#8211; I2C test<br />
• rtc &#8211; RTC test<br />
• memory &#8211; Memory test<br />
• cpu &#8211; CPU test<br />
• uart &#8211; UART test<br />
• ethernet &#8211; ETHERNET test<br />
• spi &#8211; SPI test<br />
• usb &#8211; USB test<br />
• spr &#8211; Special register test<br />
• sysmon &#8211; SYSMON test<br />
• dsp &#8211; DSP test<br />
1.8. Environment Variables<br />
Environment Variables (EV) can be used to configure the system and to store parameters for commands, and<br />
1.8. Environment Variables 6<br />
even commands and sequences of commands (simple scripts).<br />
Board Configuration<br />
baudrate, ethaddr, serial#, cpuclk<br />
•<br />
Startup Behaviour<br />
bootdelay, bootcmd<br />
•<br />
Network Parameters<br />
ipaddr, serverip, gatewayip, dnsip, netmask, hostname, rootpath, bootfile<br />
•<br />
Misc<br />
autoload (network lookup without download); autostart (start downloaded image); pram<br />
(reserve &#8220;protected RAM&#8221; area); silent (supress console messages); verify (disable CRC32<br />
checks); &#8230;<br />
•<br />
User Defined<br />
=&gt; setenv name word1 word2 word3<br />
=&gt; saveenv<br />
•<br />
The real power of EVs results from the fact that Unix shell like variable expansion is available. For example:<br />
=&gt; setenv ipaddr 192.168.3.71<br />
=&gt; setenv serverip 192.168.3.1<br />
=&gt; setenv netdev eth0<br />
=&gt; setenv hostname testbox<br />
=&gt; setenv rootpath /opt/eldk/ppc_8xx<br />
=&gt; setenv ramargs setenv bootargs root=/dev/ram rw<br />
=&gt; setenv nfsargs &#8216;setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath}&#8217;<br />
=&gt; setenv addip &#8216;setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off&#8217;<br />
=&gt; setenv kernel_addr 40040000<br />
=&gt; setenv ramdisk_addr 40100000<br />
=&gt; setenv flash_ram &#8216;run ramargs addip;bootm ${kernel_addr} ${ramdisk_addr}&#8217;<br />
=&gt; setenv flash_nfs &#8216;run nfsargs addip;bootm ${kernel_addr}&#8217;<br />
=&gt; setenv net_nfs &#8216;tftp 200000 ${bootfile};run nfsargs addip;bootm&#8217;<br />
=&gt; setenv net_ram &#8216;tftp 200000 ${bootfile};run ramargs addip;bootm 200000 ${ramdisk_addr}&#8217;<br />
Boot Kernel Image in flash with ramdisk in flash:<br />
=&gt; run flash_ram<br />
Boot Kernel Image in flash with root filesystem over NFS:<br />
=&gt; run flash_nfs<br />
Download Kernel Image over network and use root filesystem over NFS:<br />
=&gt; run net_nfs<br />
Download Kernel Image over network with ramdisk in flash:<br />
=&gt; run net_ram<br />
Step by step:<br />
=&gt; run flash_nfs<br />
1.8. Environment Variables 7<br />
Step Action Result in bootargs<br />
run<br />
nfsargs<br />
setenv bootargs root=/dev/nfs rw<br />
nfsroot=${serverip}:${rootpath}<br />
root=/dev/nfs rw<br />
nfsroot=192.168.3.1:/opt/eldk/ppc_8xx<br />
run addip<br />
setenv bootargs ${bootargs}<br />
ip=${ipaddr}:${serverip}:\<br />
${gatewayip}:${netmask}:\<br />
${hostname:${netdev}:off<br />
root=/dev/nfs rw<br />
nfsroot=192.168.3.1:/opt/eldk/ppc_8xx<br />
ip=192.168.3.71:192.168.3.1:::\<br />
testbox:eth0:off<br />
bootm<br />
40040000 boot Linux kernel<br />
Example: simple recovery strategy:<br />
=&gt; setenv bootcmd &#8216;run flash_ram; setenv kernel_addr ${alt_kernel}; run flash_ram; run net_ram&#8217;<br />
1.9. Boot Options<br />
U-Boot supports many different ways to load and boot an image.<br />
Basic command:<br />
&#8220;bootm&#8221; &#8211; Boot Image in memory (RAM, flash)<br />
Image:<br />
Header + Payload<br />
Header:<br />
? Creation Timestamp<br />
? Data Load Address<br />
? Entry Point Address<br />
? Data CRC Checksum<br />
? Operating System<br />
? CPU architecture<br />
? Image Type<br />
? Compression Type<br />
? Image Name<br />
Actions:<br />
? test CPU architecture and OS<br />
? test checksum (optional)<br />
? if compressed, uncompress<br />
? copy to load address<br />
? prepare boot arguments<br />
? start at entry point<br />
Load image in memory:<br />
? Serial Port: &#8220;loads&#8221; (S-Record), &#8220;loadb&#8221; (Kermit binary protocol)<br />
1.9. Boot Options 8<br />
? Ethernet: &#8220;tftp&#8221;, &#8220;bootp&#8221;, &#8220;dhcp&#8221;, &#8220;nfs&#8221;, &#8230;<br />
? Harddisk, CDROM: &#8220;ide read&#8221;<br />
? CompactFlash card etc.: &#8220;ide read&#8221;<br />
? USB Mass Storage Device: &#8220;usb read&#8221;<br />
? SCSI Disk and CDROM: &#8220;scsi read&#8221;<br />
? NAND flash with JFFS2 filesystem: &#8220;nboot&#8221;<br />
? Disk on Chip: &#8220;doc read&#8221;<br />
? PCI Bus: copy<br />
? &#8230;<br />
Supported Filesystems (read-only):<br />
? FAT<br />
? Reiser<br />
? JFFS2<br />
1.10. Command Interpreters<br />
Two command line interfaces:<br />
Simple (old) command interpreter:<br />
? sequential statements<br />
? statements separated by newline or &#8216;;&#8217;<br />
no conditional execution except simple builtin rules:<br />
&#8220;run cmd1; run cmd2; run cmd3&#8243;<br />
will always run all three commands<br />
?<br />
&#8220;run cmd1 cmd2 cmd3&#8243;<br />
will stop when a command fails<br />
?<br />
?<br />
? &#8220;scripts&#8221; (canned sequences of commands) avaialble using &#8220;autoscr&#8221; command<br />
•<br />
Hush Shell (from Busybox, see http://www.busybox.net/):<br />
? Bourne Shell compatible<br />
(local) shell variables (&#8220;name=val&#8221;), (global) environment variables (&#8220;setenv name<br />
val&#8221;)<br />
?<br />
? Conditionals: &#8220;if &#8230; then &#8230; else &#8230; fi&#8221;<br />
Control loops: &#8220;for &#8230; do &#8230; done&#8221;, &#8220;while &#8230; do done&#8221;, &#8220;until &#8230;<br />
do &#8230; done&#8221;<br />
?<br />
? Control operators: &amp;&amp; and || (AND and OR lists: &#8220;command1 &amp;&amp; command2&#8243;)<br />
? real shell scripts<br />
? no functions<br />
? no command substitution<br />
? no backquotes<br />
•<br />
1.11. Standalone Programs<br />
1.11. Standalone Programs 9<br />
U-Boot can dynamically load independent software modules, called &#8220;standalone programs&#8221;. Standalone<br />
programs have a standard C calling environment, and can use standard services like printf(), malloc(),<br />
install_hdlr().<br />
Used for:<br />
• special test software that is used in bring-up but shall not be included with customer release<br />
• software that is needed only occasionally<br />
• code that performs special actions that were not foreseen (software updates)<br />
• code that shall not be made available under GPL<br />
Example:<br />
#include<br />
#include<br />
int hello_world (int argc, char *argv[])<br />
{<br />
 int i;<br />
 app_startup(argv);<br />
 printf (&#8220;Example expects ABI version %d\n&#8221;, XF_VERSION);<br />
 printf (&#8220;Actual U-Boot ABI version %d\n&#8221;, (int)get_version());<br />
 printf (&#8220;Hello World\n&#8221;);<br />
 printf (&#8220;argc = %d\n&#8221;, argc);<br />
 for (i=0; i&lt;=argc; ++i) {<br />
 printf (&quot;argv[%d] = \&quot;%s\&quot;\n&quot;,<br />
 i,<br />
 argv[i] ? argv[i] : &quot;&#8221;);<br />
 }<br />
 return (0);<br />
}<br />
Run:<br />
=&gt; tftp 40000 /tftpboot/hello_world.bin<br />
&#8230;<br />
=&gt; go 40004 Hello World! This is a test.<br />
## Starting application at 0&#215;00040004 &#8230;<br />
Hello World<br />
argc = 7<br />
argv[0] = &#8220;40004&#8243;<br />
argv[1] = &#8220;Hello&#8221;<br />
argv[2] = &#8220;World!&#8221;<br />
argv[3] = &#8220;This&#8221;<br />
argv[4] = &#8220;is&#8221;<br />
argv[5] = &#8220;a&#8221;<br />
argv[6] = &#8220;test.&#8221;<br />
argv[7] = &#8220;&#8221;<br />
## Application terminated, rc = 0&#215;0<br />
1.12. Special Features<br />
• Bitmap and Splash Screen Support<br />
• Boot Count Limit<br />
• Keyboard Support<br />
1.12. Special Features 10<br />
• Automatic Updates<br />
1.12.1. Bitmap and Splash Screen Support<br />
Problem: booting Linux and starting a GUI takes a couple of seconds, but the user expects to see something<br />
&#8220;immediately&#8221; after power-on.<br />
Solution: display a static splash screen as soon as possible; available commands:<br />
• bmp info &#8211; print Bitmap info<br />
• bmp display &#8211; display bitmap image on screen<br />
• setenv splashimage addr &#8211; display spash screen image at address addr<br />
1.12.2. Boot Count Limit<br />
The Open Source Development Labs Carrier Grade Linux Requirements Definition says:<br />
CGL shall provide support for detecting a repeating reboot cycle due to recurring failures and will go to an<br />
offline state if this occurs.<br />
U-Boot allows to run an arbitrary command in such a case:<br />
• bootcount (EV) &#8211; number of reboots since power-on<br />
• bootlimit (EV) &#8211; maximum number of reboot cycles<br />
• altbootcmd (EV) &#8211; alternate boot action<br />
1.12.3. Keyboard Support<br />
Problem: make system behaviour dependent on keys pressed at power-on<br />
Solution: in U-Boot you can define one or more keys or key combinations and commands which are executed<br />
when these keys are pressed at power-on:<br />
&#8220;magic_keys&#8221; (EV) &#8211; List of characters for keys; for example:<br />
=&gt; setenv magic_keys 0123CB*<br />
•<br />
&#8220;key_magic_?_&#8221; (EV) &#8211; Key code or list of key codes for this action; scanned in the order as<br />
listed in magic_keys; for example:<br />
=&gt; setenv key_magic0 3a+3b<br />
=&gt; setenv key_magic1 3c<br />
=&gt; setenv key_magic2 4a<br />
=&gt; setenv key_magic3 4c+51<br />
=&gt; setenv key_magicC 3a+4a+5a<br />
=&gt; setenv key_magicB 52+53<br />
=&gt; setenv key_magic* 55+56<br />
•<br />
• &#8220;key_cmd?&#8221; (EV) &#8211; Action to be performed when corresponding key(s) are pressed; for example:<br />
1.12.3. Keyboard Support 11<br />
=&gt; setenv key_cmd0 setenv bootdelay 10<br />
=&gt; setenv key_cmd1 setenv addcons &#8216;console=ttyS0,${baudrate}&#8217;<br />
=&gt; setenv key_cmd2 setenv memtest on<br />
=&gt; setenv key_cmd3 setenv bootcmd run old_version<br />
=&gt; setenv key_cmdC setenv bootcmd run recovery<br />
=&gt; setenv key_cmdB setenv bootcmd run usb_update<br />
=&gt; setenv key_cmd* setenv bootcmd run demo_mode<br />
Example: after a software update, the user can select to boot the old software version (&#8220;run old_version&#8221;) by<br />
holding the keys with keycodes &#8220;4c&#8221; and &#8220;51&#8243; at power-on.<br />
1.12.4. Automatic Updates<br />
Problem:<br />
Distribute Software Updates to customers<br />
Solution:<br />
use cheap standard media like USB memory sticks<br />
Implementation:<br />
• Keep BOM (Versions, Timestamps etc.) in persistent memory (EEPROM etc.)<br />
• When booting, check whether a USB memory stick is plugged in.<br />
If one is found:<br />
If prepare.img is found load it into memory.<br />
If it is valid then run it (always).<br />
1.<br />
If preinst.img is found load it into memory.<br />
If it is valid then run it. Update the EEPROM.<br />
2.<br />
If firmware.img is found load it into memory.<br />
If it is valid, burn it into FLASH and update the EEPROM.<br />
3.<br />
If kernel.img is found load it into memory.<br />
If it is valid, burn it into FLASH and update the EEPROM.<br />
4.<br />
If app.img is found load it into memory.<br />
If it is valid, burn it into FLASH and update the EEPROM.<br />
5.<br />
If disk.img is found load it into memory.<br />
If it is valid, burn it into FLASH and update the EEPROM.<br />
6.<br />
If postinst.img is found load it into memory.<br />
If it is valid then run it. Update the EEPROM.<br />
7.<br />
•<br />
1.13. Resources, Summary<br />
Resources:<br />
• The U-Boot project is hosted at Sourceforge: http://sourceforge.net/projects/u-boot<br />
• Tarballs can be found either at sourceforge.net or at the DENX ftp server.<br />
• There is a pretty active u-boot-users mailing list.<br />
The Mailing list archive can be viewed at sourceforge.net (if it works &#8211; it is regularly broken, so don&#8217;t<br />
get discouraged and try again later).<br />
•<br />
The DENX U-Boot and Linux Guide is a Wiki based documentation documenting U-Boot and its<br />
interaction with Linux. It can be viewed (and improved) at www.denx.de. The whole DULG web<br />
•<br />
1.13. Resources, Summary 12<br />
packed into a single HTML page or a PDF file is also available (TQM8xxL version, i.e. PowerPC<br />
based).<br />
• The current README file can be viewed through viewcvs at sourceforge.net<br />
Sample configuration files for the Abatron BDI2000 debugger are available at the FTP Server at<br />
DENX.<br />
•<br />
• Even more useful links can be found in the DENX Training wiki documentation at www.denx.de.<br />
Summary:<br />
• U-Boot is a very active community project.<br />
It lives from the spritit of Free Software. It would be impossible without the numberless contributions<br />
of other developers.<br />
•<br />
1.13. Resources, Summary 13</p>
]]></content:encoded>
			<wfw:commentRss>https://www.emblogic.com/blog/12/the-universal-boot-loader-das-u-boot/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tricky C interview questions</title>
		<link>https://www.emblogic.com/blog/12/tricky-c-interview-questions/</link>
		<comments>https://www.emblogic.com/blog/12/tricky-c-interview-questions/#comments</comments>
		<pubDate>Thu, 29 Dec 2016 09:49:18 +0000</pubDate>
		<dc:creator><![CDATA[Shubham Gupta]]></dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.emblogic.com/blog/?p=13825</guid>
		<description><![CDATA[1.Give a fastest way to multiply any number by 9. Answer: #include #include void main() { int n; printf(“Enter a number:”); scanf(“%d”,&#38;n); printf(“%d”, (n&#60;&#60;3)+n); getch(); } 2. How to measure the size of any variable without “sizeof” operator? Answer: #define &#8230; <a href="https://www.emblogic.com/blog/12/tricky-c-interview-questions/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>1.Give a fastest way to multiply any number by 9.<br />
Answer:<br />
#include<br />
#include<br />
void main()<br />
{<br />
int n;<br />
printf(“Enter a number:”);<br />
scanf(“%d”,&amp;n);<br />
printf(“%d”, (n&lt;&lt;3)+n);<br />
getch();<br />
}<br />
2.      How to measure the size of any variable without “sizeof” operator?<br />
Answer:<br />
#define   size_of(x)   ((char *)(&amp;x+1) – (char *)&amp;x)<br />
void main()<br />
{<br />
Short int x;<br />
Printf(“%d”,size_of(x));<br />
}</p>
<p>Explanation:<br />
By using the &amp;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 (&amp;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.</p>
<p>3.      How to measure the size of any variable without using “sizeof” operator?<br />
Answer:<br />
#define SIZE_OF(T) (((T *)0)+1)<br />
void main()<br />
{<br />
clrscr();<br />
printf(“%d”,SIZE_OF(long int));<br />
}</p>
<p>Explanation:</p>
<p>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.</p>
<p>4.      Write code snippets to swap two variables in five different ways.<br />
Answer:<br />
a.      /* swapping using three variables*/ (Takes extra memory space)<br />
Int a=5, b=10, c;<br />
c=a;<br />
a=b;<br />
b=c;</p>
<p>b.      /* using arithmetic operators */<br />
a=a+b;<br />
b=a-b;<br />
a=a-b;</p>
<p>c.       /* using bit-wise operators */<br />
a=a^b;<br />
b=b^a;<br />
a=a^b;</p>
<p>Line<br />
Operation<br />
Value of a<br />
Value of b</p>
<p>1<br />
-<br />
5<br />
10<br />
Initial values<br />
2<br />
a=a^b<br />
15<br />
10</p>
<p>3<br />
b=a^a<br />
15<br />
5</p>
<p>4<br />
a=a^b<br />
10<br />
5<br />
values after swapping</p>
<p>d.      /* one line statement using bit-wise operators */ (most efficient)<br />
a^=b^=a^=b;</p>
<p>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.</p>
<p>e.       /* one line statement using arithmetic &amp; assignment operators */<br />
a=(a+b) &#8211; (b=a);<br />
In the above axample, parenthesis operator enjoys the highest priority &amp; 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.</p>
<p>5.      How to swap between first &amp; 2nd byte of an integer in one line statement?<br />
Answer:<br />
int x=0&#215;1234;<br />
x = x&lt;&gt;8;</p>
<p>Explanation:<br />
Let x = 0&#215;1234</p>
<p>x                    = 00010010   00110100<br />
x&lt;&gt;8            = 00000000   00010010<br />
x&lt;&gt;8  = 00110100   00010010  i.e. value of ‘x’ after swap is 0&#215;3412</p>
<p>6.      What is the efficient way to divide a no. by 4?<br />
Answer:<br />
x = x&gt;&gt;2;</p>
<p>7.      Suggest an efficient method to count the no. of 1’s in a 32 bit no. Remember without using loop &amp; testing each bit.<br />
Answer:<br />
(i)                 int count_set_bits (long n)<br />
{<br />
             int count = 0;<br />
             while (n)<br />
             {<br />
             count ++;<br />
             n &amp; = n-1;<br />
             }<br />
            return (count);<br />
            }<br />
(ii)               int count_set_bits (long n)<br />
{<br />
return (n ? 1+ count_set_bits (n&amp;n-1) : 0);<br />
}</p>
<p>Explanation:</p>
<p>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’ &amp; the loop terminates. The logic needs conversion of every 1 to 0, which can be achieved by making a bitwise ‘&amp;’ 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).<br />
Let n= 30<br />
            30 = 00011110<br />
            29 = 00011101<br />
(30 &amp; 29) = 00011100</p>
<p>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 &amp;=n-1). This step is repeated until n becomes ‘0’.</p>
<p>8.      Test whether a no. is power of 2 or not.<br />
Answer:<br />
void main ()<br />
{<br />
int n;<br />
printf (“\n Enter any no:”);<br />
scanf (“%d”, &amp; n);<br />
if (n &amp; &amp; ((n &amp; n-1) = = 0))<br />
    printf (“It is power of 2”);<br />
else<br />
   printf (“It is not power of 2”);<br />
}<br />
Test:<br />
Enter any no: 32<br />
It is power of 2</p>
<p>Enter any no: 56<br />
It is not power of 2</p>
<p>Explanation:</p>
<p>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’ &amp; rest are must be ‘0’.<br />
For example the number 32 has a binary representation of 00100000.</p>
<p>9.      How to check endianness of the computer.</p>
<p>Answer:<br />
Logic-1<br />
void main ()<br />
{<br />
int x = 300;<br />
if ((* ((unsigned char *) &amp; x) == 1)<br />
    &amp;&amp; (*(unsigned char*) &amp; x+1) == 44))<br />
    printf (“BIG ENDIAN”);<br />
else<br />
    printf (“LITTLE ENDIAN”);<br />
}</p>
<p>Logic-2<br />
void main ()<br />
{<br />
union xxx<br />
{<br />
unsigned int x;<br />
unsigned char ch[2];<br />
};<br />
union xxx p = {300};<br />
if ((p.ch [0] = = 1) &amp;&amp; (p. ch [1] == 44))<br />
    printf (“BIG ENDIAN”);<br />
else<br />
    printf (“LITTLE ENDIAN”);<br />
}</p>
<p>Explanation:<br />
00000001<br />
00101100<br />
1<br />
44<br />
 Big Endian:</p>
<p>00101100<br />
00000001<br />
44<br />
1<br />
              Little Endian:     </p>
<p>            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.<br />
            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 &amp; 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 &amp; the 2nd byte will be 1 according to the DCBA data storage format.<br />
Logic-1:<br />
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 &amp; 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”.<br />
Logic-2:<br />
In this logic, we have taken the union called xxx with 2 members &#8211; 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 &amp; p.ch[1] with 44. If it matches, its “Big-endian”, else “little endian”.</p>
<p>10.  Write a C-program which does the addition of two integers without using ‘+’ operator.</p>
<p>Answer:<br />
Logic-1:<br />
c = a – (-b);<br />
as a+b is equivalent to a – (-b), binary ‘+’ operator is replaced by one unary ‘-‘ &amp; one binary ‘-‘ operator.</p>
<p>Logic-2:<br />
void main ()<br />
{<br />
int a,b,c;<br />
printf (“\n Enter any two numbers”);<br />
scan f (“%d %d”, &amp;a, &amp;b);<br />
asm mov ax, a;<br />
asm mov bx, b;<br />
asm aad ax, bx;<br />
asm mov c, ax;<br />
printf ( “%d”, c);<br />
}</p>
<p>11.  Write a C-program to find the smallest of three integers without using any of the comparision operators.</p>
<p>Answer:<br />
void main ()<br />
{<br />
int a,b,c;<br />
printf (“\n Enter three numbers”);<br />
scan f (“%d %d %d”, &amp;a, &amp;b, &amp;c);<br />
if ((a-b) &amp; 32768)<br />
{<br />
if ((a-c) &amp; 32768)<br />
printf (“ %d”, a);<br />
else<br />
printf (“ %d”, c);<br />
}<br />
else<br />
if ((b-c) &amp; 32768)<br />
printf (“ %d”, b);<br />
else<br />
printf (“ %d”, c);<br />
}</p>
<p>Explanation:</p>
<p>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 &amp; operator with the sign bit (i.e. 32768 or 15th bit).</p>
<p>12.  Find the maximum &amp; minimum of two numbers in a single line without using any condition &amp; loop.</p>
<p>Answer:<br />
void main ()<br />
{<br />
int a=15, b=10;<br />
printf (“ max = %d, min = %d”, ((a+b) + abs(a-b)) /2, ((a+b) – abs (a-b)) /2);<br />
}</p>
<p>13.  What “condition” expression can be used so that the following code snippet will print Hello world.</p>
<p>Answer:<br />
if “condition”<br />
printf (“ Hello”);<br />
else<br />
printf (“ world !”);</p>
<p>Answer:<br />
void main ()<br />
{<br />
if ( ! printf (“Hello”));<br />
printf (“Hello”);<br />
else<br />
printf (“world !”);<br />
}</p>
<p>Explanation:<br />
As we know the printf function displays the string &amp; 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.</p>
<p>14.  How to print number from 1 to 100 without using conditional operators.</p>
<p>Answer:<br />
void main ()<br />
{<br />
int  i=0;<br />
while (100 – i++)<br />
printf (“ %d”, i);<br />
}</p>
<p>15.  WAP to print 100 times “Hello” without using loop &amp; goto statement.</p>
<p>Answer:<br />
void main()<br />
{<br />
show (1, 100);<br />
}<br />
show (int x, int y)<br />
{<br />
if (x&gt;=y)<br />
return;<br />
printf (“\n Hello”);<br />
show (x+1, y);<br />
}<br />
i.e. Recursive function</p>
<p>16.  Write the equivalent expression for x%8.</p>
<p>Answer:<br />
x &amp; 7;</p>
<p>Explanation:<br />
x = 21 = 00010101<br />
       7   = 00000111<br />
x &amp; 7  = 00000101 (which is 5)</p>
]]></content:encoded>
			<wfw:commentRss>https://www.emblogic.com/blog/12/tricky-c-interview-questions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Replace a Switch-Statement with function pointer</title>
		<link>https://www.emblogic.com/blog/12/how-to-replace-a-switch-statement-with-function-pointer/</link>
		<comments>https://www.emblogic.com/blog/12/how-to-replace-a-switch-statement-with-function-pointer/#comments</comments>
		<pubDate>Thu, 29 Dec 2016 06:36:34 +0000</pubDate>
		<dc:creator><![CDATA[Shubham Gupta]]></dc:creator>
				<category><![CDATA[Character Driver]]></category>

		<guid isPermaLink="false">http://www.emblogic.com/blog/?p=13822</guid>
		<description><![CDATA[float Plus (float a, float b) { return a+b; } float Minus (float a, float b) { return a-b; } float Multiply(float a, float b) { return a*b; } float Divide (float a, float b) { return a/b; } // &#8230; <a href="https://www.emblogic.com/blog/12/how-to-replace-a-switch-statement-with-function-pointer/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>float Plus    (float a, float b) { return a+b; }<br />
float Minus   (float a, float b) { return a-b; }<br />
float Multiply(float a, float b) { return a*b; }<br />
float Divide  (float a, float b) { return a/b; }</p>
<p>// Solution with a switch-statement &#8211;  specifies which operation to execute<br />
void Switch(float a, float b, char opCode)<br />
{<br />
   float result;</p>
<p>   // execute operation<br />
   switch(opCode)<br />
   {<br />
      case &#8216;+&#8217; : result = Plus     (a, b); break;<br />
      case &#8216;-&#8217; : result = Minus    (a, b); break;<br />
      case &#8216;*&#8217; : result = Multiply (a, b); break;<br />
      case &#8216;/&#8217; : result = Divide   (a, b); break;<br />
   }</p>
<p>   cout &lt;&lt; &quot;Switch: 2+5=&quot; &lt;&lt; result &lt;&lt; endl;         // display result<br />
}</p>
<p>// Solution with a function pointer &#8211;  is a function pointer and points to<br />
// a function which takes two floats and returns a float. The function pointer<br />
// &#8220;specifies&#8221; which operation shall be executed.<br />
void Switch_With_Function_Pointer(float a, float b, float (*pt2Func)(float, float))<br />
{<br />
   float result = pt2Func(a, b);    // call using function pointer</p>
<p>   cout &lt;&lt; &quot;Switch replaced by function pointer: 2-5=&quot;;  // display result<br />
   cout &lt;&lt; result &lt;&lt; endl;<br />
}</p>
<p>// Execute example code<br />
void Replace_A_Switch()<br />
{<br />
   cout &lt;&lt; endl &lt;&lt; &quot;Executing function &#039;Replace_A_Switch&#039;&quot; &lt;&lt; endl;</p>
<p>   Switch(2, 5, /* &#039;+&#039; specifies function &#039;Plus&#039; to be executed */ &#039;+&#039;);<br />
   Switch_With_Function_Pointer(2, 5, /* pointer to function &#039;Minus&#039; */ &amp;Minus);<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>https://www.emblogic.com/blog/12/how-to-replace-a-switch-statement-with-function-pointer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
