Wednesday, November 25, 2009

CCS v4 Linux Aware Debugging

CCS v4 Linux Aware Debugging

Below are the steps for debugging linux running on beagleboard using CCS v4.

My target Environment:
MMC Card: U-boot.bin, uImage, ramdisk,gz, MLO, noraml.src

After compiling the kernel do a objdump with the linux image i.e.vmlinux
arm-none-guneabi-objdump -D vmlinux >> vmlinux.obj

Insert MMC card and power on the target board. Now the target board is up with linux
Open CCS v4
Tools-> New target configuration
After configuring the debugger and target go to Advanced tab and under each core delete "initialization script" whihc is a GEL file.
Target->Launch TI debugger
Target->Load Symbols (browse to vmlinux)
On the debug tag right click on the emulator -> Edit Source lookup (browse to vmlinux.obj and add the linux source dir)

Now the various process and threads appear on the debug window.
To tarace the kernel flow from boot apply breakpoint at 0x80008000 and Target->Reset->System Reset

Friday, May 22, 2009

Debugging Linux on CCS

Though Linux cant be debugged using CCS, by doing some changes to the memory, CCS can be used to debug linux untill is MMC is turned ON. This is most required in board bring up projects.

On compiling linux code we get the image vmlinux in elf32 format. In order to lead this image through CCS this needs to be converted to the .out type.
The kernel image vmlinux, has a start address, VMA and LMA set to 0xC0008000. But 0xC0008000 does not map to a valid loadable address in the DaVinci/OMAP system. So, when vmlinux image is tried to download via CCS on the target, CCS complainsthat the memory map of the target does not match the program address. Hence vmlinux cannot be downloaded to the target directly.To circumvent this problem, the LMA of the vmlinux image is changed from 0xC0008000 to 0x80008000 which maps correctly into the target system memory. This conversion of vmlinux can be done by the script conv-elf-to-out.sh.This also helps in direct debugging of the kernel with ICE without necessarily flashing the kernel into the NOR flash.

conv-elf-to-out.sh
#!/bin/sh
# This shell script converts given input file of elf32-littlearm

# format to output file which is also elf32-littlearm format but
# the LMA (load memory addresses) are shifted by 0x40000000 so
# that it can be downlaodable by CCS on the target. This script
# is used to mainly, convert compiled linux image vmlinux to
# downloadable image vmlinux.out whose LMA starts from 0x80008000
usage()

{
echo ""
echo " Incomplete command line .. missing inputs " ;
echo " Usage : sh conv-elf-to-out.sh " ;
echo " Example : sh conv-elf-to-out.sh /home/linux/vmlinux /home/linux/vmlinux.out" ;
echo ""
exit 0;
}
if [ -z "$1" -o -z "$2" ] ;

then usage
fi
if [ ! -f "$1" ] ;

then echo " File not found : $1 "
exit 0;
fi
echo "Converting "$1" to "$2" "
arm-none-linux-gnueabi-objcopy $1 $2
arm-none-linux-gnueabi-objcopy $(arm_v5t_le-objdump -h $2 awk '$1~/^[0-9]/ && $5 {print $2}' while read s; do echo --change-section-lma $s-0x40000000; done) $2
arm-none-linux-gnueabi-objcopy --set-start 0x80008000 $2
echo "Changed the LMA of ""$1"" to 0x80008000 in ""$2"" "

Note: Once the MMU is turned ON, CCS can further not be used to debug, but can be used to trace the code in assembly code. In order to do this disable memory mapping by Options->Memory Map and Disable Memory Map

Tuesday, May 19, 2009

Booting Linux on ARM Processor in Depth

  • Kernel entry point is in arch/arm/kernel/head.S
    This file starts with a check (TEXT_ADDR & 0xffff) != 0x8000, this is because page tables are placed 16k below KERNEL_RAM_VADDR
    arch/arm/kernel/head.S: stext
    enable supervisor mode
    disable IRQ
    call __lookup_processor_type
    defined in arch/arm/kernel/head-common.S
    search list of supported processor types __proc_info_begin
    kernel may be built to support more than one processor type
    list of proc_info_list structs
    defined in arch/arm/mm/proc-arm926.S and other corresponding proc-*.S files
    linked into list by section declaration: .section ".proc.info.init"
    return pointer to proc_info_list struct corresponding to processor if found, or loop in
    error if not
    call __lookup_machine_type
    defined in arch/arm/kernel/head-common.S
    search list of supported machines (boards)
    kernel may be built to support more than one board
    list of machine_desc structs
    machine_desc struct for boards defined in board-specific file vx115_vep.c
    linked into list by section declaration that's part of MACHINE_DESC macro
    return pointer to machine_desc struct corresponding to machine (board)
    call __vet_atags

    defined in arch/arm/kernel/head-common.S
    validate the R2 reg, which locates to the structure that holds the parameters passed
    by the
    bootloader.
    Return either valid atags pointer or zero
    call __create_page_tables to set up initial MMU tables
    Return – R4 containing the physical page table address
    set lr to __enable_mmu, r13 to address of __switch_data
    lr and r13 used for jumps after the following calls
    __switch_data defined in arch/arm/kernel/head-common.S
    call the __cpu_flush function pointer in the previously returned proc_info_list struct
    offset is #PROCINFO_INITFUNC into struct
    this function is __arm926_setup for the ARM 926EJ-S, defined in arch/arm/mm/proc-arm926.S
    initialize caches, writebuffer jump to lr, previously set to address of __enable_mmu
    __enable_mmu
    set page table pointer (TTB) in MMU hardware so it knows where to start page-table walks
    enable MMU so running with virtual addresses
    jump to r13, previously set to address of __switch_data, whose first field is address of __mmap_switched
    __switch_data defined in arch/arm/kernel/head-common.S
    arch/arm/kernel/head-common.S: __mmap_switched
    . copy data segment to RAM
    . zero BSS
    . branch to start_kernel


    Start_kernel – (init/main.c)
    tick_init – (kernel/time/tick-common.c)
    setup_arch (arch/arm/kernel/setup.c)
    Locate processor in the list of supported processors and print CPU version and name
    Setup stack for exception handlers
    Setp page tables
    setup_command_line (init/main.c)
    Store the unmodified and modified command line parameters for future ref
    build_all_zonelists (mm/page_alloc)
    Construct zonelist for each memory zone(DMA, DMA32, NORMAL, HIGH_MEMORY, MOVABLE). Zonelist specifies the zones/nodes to visit when allocation request for a selected zone/node is not met. This is called overflow or fallback.
    setup_log_buf (kernel/printk.c)
    Allocate memory for log_buf, free early log_buf and copy early log buf to newly allocated log_buf
    mm_init (init/main.c)
    Initialize memory allocators. Calculate available, reserved and highmem.
    sched_init (kernel/sched.c)
    Setup the scheduler, note we still have not enabled preemption and interrupts.
    preempt_disable(include/linux/preempt.h)
    Preemption is enabled, and in the previous step scheduler is also initialized.
    init_IRQ (arch/arm/kernel/irq.c)
    init_timers (kernel/timer.c)
    hrtimers_init (kernel/hrtimer.c)
    softirq_init (kernel/softirq.c)
    local_irq_enable(include/linux/irqflags.h)
    console_init (drivers/char/tty_io.c)
    vfs_caches_init (fs/dcache.c)
    mnt_init (fs/namespace.c)
    init_rootfs (fs/ramfs/inode.c)
    init_mount_tree (fs/namespace.c)
    bdev_cache_init (fs/block_dev.c)
    chrdev_init (fs/char_dev.c:)
    signals_init (kernel/signal.c)
    rest_init (init/main.c)
    kernel_thread ( arch/arm/kernel/process.c)
    kernel_thread() creates a kernel init thread and control is given to kernel_init().
    Kthreadd
    Is a kernel thread deamon, all kthreads are forked off this thread
    kernel_init (init/main.c)
    smp_prepare_cpus (arch/arm/smp.c)
    smp_init(kernel/smp.c)
    do_basic_setup (init/main.c)
    driver_init (drivers/base/init.c)
    do_initcalls (init/main.c)
    Calls all subsytems init functions, __initcall_start doesn’t appear anywhere in *.c or *.h file, it is present in linker script (*.lds)
    prepare_namespace (init/do_mounts.c)
    Decides where to mount and mounts the ramdisk
    init_post (init/main.c)
    Initial boot is done clear all initmem segments

Monday, May 18, 2009

Install and Configure D-Link Wireless USB Adapter

Step 1: Download archive Manager ftp://ftp.linux-wlan.org/pub/linux-wlan-ng/linux- wlan-ng-0.2.3.tar.gz
to /usr/src/linux-wlan-ng-0.2.3.

Step 2: unpack them run ./configure

Step 3: In the source dir, type `make config` and answer the
following:

------------- Linux WLAN Configuration Script -------------
The default responses are correct for most users.
Build Prism2.x PCMCIA Card Services (_cs) driver? (y/n) [n]: n
Build Prism2 PLX9052 based PCI (_plx) adapter driver? (y/n) [n]: n
Build Prism2.5 native PCI (_pci) driver? (y/n) [n]: n
Build Prism2.5 USB (_usb) driver? (y/n) [y]: y
Linux source directory [/usr/src/linux]:
The kernel source tree is version 2.4.18.
The current kernel build date is Sun Mar 17 04:51:47 2002.
Alternate target install root directory on host []:
Module install directory [/lib/modules/2.4.18]:
It looks like you have a BSD-ish init file setup.
You'll need to edit /etc/rc.d/rc.S to invoke /etc/rc.d/rc.wlan
(for ISA/PCMCIA cards) so that wlan cards will be started at boot
time.

Target Architecture? (i386, ppc, arm, or alpha) [i386]:
Prefix for build host compiler? (rarely needed) []:
Compiling with a cross compiler? (y/n) [n]:
Build for debugging (see doc/config.debug) (y/n) [n]:


***********Configuration successful.

Step 4: Type: `make all`
Step 5: Type: `make install
Step 6: # vi wlan.conf
SSID_wlan0="your_ssid"

Step 7: # cp wlancfg-DEFAULT wlancfg-your_ssid
Step 8: # vi wlancfg-your_ssid

lnxreq_hostWEPEncrypt=true
lnxreq_hostWEPDecrypt=true
dot11PrivacyInvoked=true
dot11WEPDefaultKeyID=0
dot11ExcludeUnencrypted=true
dot11WEPDefaultKey0=12:34:56:78:90
AuthType="sharedkey"

Step 9: # vi /etc/modprobe.conf
alias wlan0 prism2_usb

Step 10: # vi /etc/sysconfig/network-scripts/ifcfg-wlan0

DEVICE=wlan0
ONBOOT=yes
BOOTPROTO=dhcp
TYPE=wireless
Step 11: # modprobe prism2_usb prism2_doreset=1

Step 12: # Add the following to: /etc/hotplug/usb/prism2_usermap

Prism2 0x0003, vendor Id, device Id
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00


***********The LINK light will come.

Step 13: # lsmod

Module Size Used by
prism2_usb 72836 0
p80211 29840 2 prism2_usb

Step 14: # ifup wlan0
Step 15: # ifconfig wlan0

wlan0 Link encap:Ethernet HWaddr 00:0D:88:67:8D:42
inet addr:192.168.0.196 Bcast:192.168.0.255
Mask:255.255.255.0

UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:694 errors:0 dropped:0 overruns:0 frame:0
TX packets:757 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:240526 (234.8 KiB) TX bytes:100360 (98.0 KiB)

Security Issue(Enabling WEP128)

If you are concerned about security - you
Should enable WEP 128.It won't make you much more secure but
at least you won't be totally open. On the other hand it
usually does slow the connection. WEP works in 0.1.14-pre3
and newer. Enabling it is simple:

1. Generate 3-4 26 hex-digits keys - you may use nwepgen but be
carefull as some OSs (like Windows XP) use different
algorithms so always use 26-hex digits form, not the
password string - the latter is only usefull to recover the
key if you forgotten it (but recover it with THE SAME
program you used to generate it)

2. Enable WEP128 on your AP and enter keys there, pick one you
will use: I suggest not the first one as this is the one
which is usually tried first if someone tries to hack in
3. Edit /etc/wlan.conf, these are the important lines:

dot11PrivacyInvoked=true
dot11WEPDefaultKeyID=2 # 0|1|2|3
dot11WEPDefaultKey0=xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
dot11WEPDefaultKey1=xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
dot11WEPDefaultKey2=xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
dot11WEPDefaultKey3=xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
AuthType="sharedkey"

4. restart wlan and replug the card and should be fine. If it
does not work - try rebooting.

Steps to update kernel and enable wireless

To upgrade the kernel you must have the kenel source i.e .src.rpm file.
If you don’t have follow the following steps
· Download the corresponding kernel.src.rpm file from www.sourceforge.com
· # rpm –ivh kernel-2.6.10-1.741.src.rpm
· # rpmbuild –bp –target=norarch /usr/src/redhat/SPECS/kernel-2.6.spec

$ cd /usr/src
$ ln -s redhat/BUILD/kernel-2.6.10/linux-2.6.10/ linux
$ ln -s redhat/BUILD/kernel-2.6.10/linux-2.6.10/ linux-2.6.10
$ cd /linux-2.6.17.7
$ make mrproper
$ uname –rm(to know what is our architecture i.e i386,i486,i686)
$ cp /usr/src/linux-2.6.10/configs/kernel-2.6.10-i686.config /usr/src/linux-2.17.7 /.config
$ make oldconfig
$ make menuconfig or make xconfig(Don’t select SElinux,video for linux v4l(DVB),Enable all Wep extensions)


Enable CONFIG_NET_WIRELESS
CONFIG_FW_LOADER Generic Driver Options
CONFIG_CRC32
CONFIG_CRC_CCITT
$ make all
$ make modules_install
$ make install
modify grub.conf according to your needs
vi /boot/grub/grub.conf
default=1 points to the previous kernel set default=0 to
the new kernel.