simple examples of how to

Wednesday, October 5, 2011

[Linux Device Driver] Good hints to analyze linux networking driver source code

There are several mandatory points that all networking drivers should implement.

Lookup hints: net_device_ops, dev_queue_xmit, netif_rx, napi_gro_receive, netif_napi_add, request_irq, open_softirq, tasklet_init, request_firmware

Those are the interfacing parts to the linux networking kernel and should be used or implemented in the drivers

for instance, net_device_ops->ndo_xmit_start is the callback function called when kernel wants to send a packet.

netif_rx or napi_gro_receive is the function that takes a skb (or skbs) that are sent to the upper layer (host).

dev_queue_xmit is for forwarding the packets at the L2 (such as L2 switching)

netif_napi_add registers napi callback for polling the device receive

request_irq takes a function pointer for interrupt handler: that is the one that called whenever a packet is delivered to the device

open_softirq and tasklet_init are starting points of bottom-half. Bottom-half is for processing heavy load part of ISR (interrupt service routine). Top-half (fast and light) and bottom-half (slow and heavy).

If driver uses request_firmware, it means that this driver loads the firmware to the micro-controller in the device.

How to write PCI driver in Linux (good start)

http://free-electrons.com/doc/pci-drivers.pdf

The packet processing function trace in ixgbe driver

How to receive packets:
Two ways:
- using napi (poll): register netpoll function to napi (ixgbe_netpoll) that performs clean the rx_ring and sends all the packet up to the upper layer
- calls ixgbe_msix_clean_rings()
- calls ixgbe_clean_tx_irq()
- calls ixgbe_receive_skb() or napi_gro_receive()

- what is the other? who writes to rx_ring???


How to send packets:
One way:
- use ixgbe_xmit_frame() function calls ixgbe_xmit_frame_ring()

What is the source code of the ethernet driver (NetXtreme BCM5761e)

it is tg3.c located at
drivers/net/tg3.c

Tuesday, October 4, 2011

[Linux Device Driver] intel ixgbe source code analysis (part1: where is the entry?)

ixgbe

[ixgbe_main.c] ixgbe_init_module called

[ixgbe_main.c] dca_register_notify called

[ixgbe_main.c] pci_register_driver called
-->

[ixgbe_main.c] ixgbe_probe called # here actual initialization of ethernet device is performed
/**
* ixgbe_probe - Device Initialization Routine
* @pdev: PCI device information struct
* @ent: entry in ixgbe_pci_tbl
*
* Returns 0 on success, negative on failure
*
* ixgbe_probe initializes an adapter identified by a pci_dev structure.
* The OS initialization, configuring of the adapter private structure,
* and a hardware reset occur.
**/



#endif
static struct pci_driver ixgbe_driver = {
.name = ixgbe_driver_name,
.id_table = ixgbe_pci_tbl,
.probe = ixgbe_probe,
.remove = __devexit_p(ixgbe_remove),
#ifdef CONFIG_PM
.suspend = ixgbe_suspend,
.resume = ixgbe_resume,
#endif
#ifndef USE_REBOOT_NOTIFIER
.shutdown = ixgbe_shutdown,
#endif
#ifdef HAVE_PCI_ERS
.err_handler = &ixgbe_err_handler
#endif
};

Monday, October 3, 2011

[Kernel system function trace] What happen "ifconfig eth0 up"

what would happen if I type
$ ifconfig eth0 up

ifconfig binary uses ioctl to send message SIOCSIFFLAGS:

Then, the function trace of the above action in linux kernel is the following

[net/socket.c] sock_ioctl() called
----> sock->ops->ioctl() called

[net/ipv4/af_inet.c] inet_ioctl() called # sock->ops->ioctl == inet_ioctl

[net/ipv4/devinet.c] devinet_ioctl() called
# in this function (devinet_ioctl), we got a quite important conversion
# that we convert net (struct net) and ifname to the dev (struct net_device)
# using the function __dev_get_by_name() defined in [net/core/dev.c]

[net/core/dev.c] dev_change_flags() called
# after changing the flags, since it is up flag (interface-up event),
# this interface-up event should be notified to other "things" that are interested
# this notification is done by rtnetlink

[net/core/rtnetlink.c] rtmsg_ifinfo() called # to notify the interface-up event

[net/core/rtnetlink.c] rtnl_notify() called
# in this function, we use rtnl field in net (struct net) as the sock group
# who are interested in this interface-up event (after referred as sk)

[net/netlink/af_netlink.c] nlmsg_notify() called
# this function use either nlmsg_multicast or nlmsg_unicast, lets assume nlmsg_multicast

[include/net/netlink.h] nlmsg_multicast called()

[net/netlink/af_netlink.c] netlink_broadcast() called

[net/netlink/af_netlink.c] do_one_broadcast() called multiple times

[net/netlink/af_netlink.c] netlink_broadcast_deliver() called
# now in this function, the message packed in skb is delivered to the sk (struct sock)
# by putting skb into the sk_receive_queue field (list_head) in the sk (struct sock)

Saturday, October 1, 2011

[Linux] How to partition, format, and mount a second harddrive

Let's assume the second harddrive is /dev/sdb

first, partition it

$ sudo fdisk /dev/sdb
it has self-explanining CLI

If you create just one primary partition, it will give /dev/sdb1.
We are going to format and mount sdb1

formatting
$ mkfs.ext4 /dev/sdb1

mounting

add a line in /etc/fstab

# second harddrive (sdb1)
/dev/sdb1 /mnt ext4 defaults 0 0

then do this
$ sudo mount -a