-------------------------------------------------------------- -------------------------------------------------------------- Embedded Linux,Linux Porting & Device Driver -------------------------------------------------------------- 6 days ( 3 modules ) M1: basic linux programming C programmer -> Linux Programmer ( x86 Arch) windows platform - lib -> app linux os + lib - app linux basic commands shell scripting & Makefiles multiprocessing multithreading IPC socket programing debuggin of app M2: Linux Porting on ARM - toolchain - bootloader - linux kernel - Rootfs M3: Device Drivers - Kernel Module Program - Char drivers - Interrpt programming - Kern Sync - kernel debug - kgdb - printk - sudo file sys debug fs procfs sysfs - Hardware JTAG - intro ( advn device drivers ) ------------------------------------------------------------- Host Setup for eLinux Development: 1. Install Ubuntu-12.04LTS 2. Download and run the elunux_pkg.sh script for additional packages $ wget ftp://ftp.phytec.de/pub/Products/India/ Cosmic-AM335x/Linux/PD13.0.0/tools/scripts/elinux_pkg.sh $ chmod +x elinux_pkg.sh $ sudo ./elinux_pkg.sh x86 -bios - POST - bootstrap loader bootable device active primary partion ( MBR ) loads the bootloader and run it - Bootloader basic hardware init load the kernel - kernel - harware init - start services - mounts the RFS - Rootfs utilities + app --------------------- Linux Kernel: - Scheduler - process mgmt - memory mgmt - device mgmt - files system - network - sound Linux Dist: Shell commands: ps -axf cat /etc/init.d/rc | more dir structure unix / - bin - lib - dev ( device nodes ) /dev/ttyS0 - etc ( system config files ) - var - home - opt ctl+ alt + t ls ( list ) display files and dir ls / -l ls /bin pwd ( present working dir ) dir commands: ( cd ,pwd , mkdir, rmdir, rm, mv ) 1. cd ( change dir ) synt: cd path types: relate absloute /home/dell cd / cd ../../ .. parent dir . current dir 2. mkdir cd mkdir elinux ls cd elinux pwd elinux -tools -scripts mkdir -p tools/scripts rmdir tools/scripts rmdir tools cd tools rmdir scripts cd .. rmdir tools mkdir -p tools/scripts rm -r tools/scripts cd ~/elinux mkdir -p tools/scripts ls tools mv tools/scripts . ls tools mv scripts script mv ./scripts ./script files commands: ( gedit, vi, cat, rm, mv, cp ) [ chmod -R, chown ] bin semi-bin text gedit test.c & vi test.c echo "hello" echo "hello" > test.txt cat test.txt echo "hi" >> test.txt ls / >> ~/elinux/tools/scripts/test.txt pwd ~/elinux/tools/s1/ ~/elinux/tools/s2/ cp pwd ~/elinux/ mkdir tools/s1 tools/s2 cp tools/scripts/test.txt tools/s1 cp tools/scripts/test.txt tools/s2 cp tools/scripts/test.txt . ls -l U G O -rwxrwxrwx file type chmod +x chmod -x chmod 000 ls -l chmod 200 ls -l chmod 111 ls -l chmod 444 ls -l chmod chmod 770 sudo chown root:root test.txt ls -l nobody ------------------------------------- grep --help grep grep -nr strcpy /usr/include/* find find /usr/include -name string.h find /usr/include -name '*string*' cd ~/elinux gedit f1.txt 1 2 3 4 5 gedit f2.txt 1 9 3 svn git clearcase cat *.txt diff -uNbr f1.txt f2.txt > modi.patch mkdir pt cp f1.txt pt cd pt patch --help patch < ../modi.path tar -zcvf tools.tar tools mkdir bak mv tools bak/ ls tar -xvf tools.tar more commands: ( uname, file, locate, touch, du, df, fdisk, dd, mount, umount, ) /dev/sda4 du . dd if=/dev/sdc of=sdcard.img (backup) dd if=sdcard.img of=/dev/sdc ( restore ) Shell Scripting ------------------------------------- bash dash ------------- To change the shell sudo rm /bin/sh sudo ln -s /bin/bash /bin/sh -------------- ls /bin/*sh* -l env PATH gedit first.sh #!/bin/sh a=10 b=20 c=`expr $a + $b` echo $a + $b = $c echo "End of the script..." if() { } else { } if if [ $a -gt $b ] then else fi printf("%s %s %s",argv[0], argv[1] ...) echo $0 $1 $2 echo "Num " $# echo "all " $@ shift 2 echo $0 $1 $2 echo "Num " $# echo "all " $@ ./first.sh a1 a2 a3 a4 a5 a6 ----------------------------------------------------------------------- Makefiles --------- gedit hello.c & #include #include "sum.h" main() { printf(" this is the first app on Linux %d \n",sum(10,20)); return 0; } gcc sum.c hello.c -o hello ./hello gedit sum.c #include "sum.h" int sum(int a, int b) { return a+b; } gedit sum.h #ifndef _SUM_H #define _SUM_H extern int sum(int,int); #endif gcc -c sum.c -o sum.o gcc hello.c sum.o -o hello assembler compiler linker fileformat converter 8051 led.c vasu() { while(1) { 0x90 = 0xff; 0x5490ff for(...) 0x90 = 0x00; for( ... ) } } strat.S (startup code) - low level hw init - vector table init - memory init - add hardware init - call c funt Keil_8051: start.S - a51.exe - start.o led.c - c51.exe -> led.o 8051.ld ( linker script ) start.o led.o -> bl51.exe -> led.obj led.obj - oh51.hex - led.bin /led.bin records header opcodes footer( crc) assemble compiler linker ( linker locator ) fileconverter as gcc ld objcopy int g; stack heap bss data text make <- Makefile CC=gcc DELC=rm -rf all: hello.c sum.o sum.h @ echo "This is my first makefile to compile sum app" ${CC} sum.o hello.c -o hello sum.o: sum.c sum.h ${CC} -c $< -o $@ clean: ${DELC} sum.o hello.o hello rule_name: make -> make all or make make clean ----------------------------------------------------------------------- Linux processes The running program instance is called process in Linux List all the process runing ps -axf Try printing the process id and parent process id using getpid() & getppid() while(1) { printf(" My pid is %d & My parent pid is %d\n",getpid(), getppid()); sleep(2); } Try to kill the above process from other terminal sudo kill -9 Multi Processing: ================ system exec fork clone lib pthread gedit systest.c #include #include < main() { int retval; printf("This is test prg for system api \n"); retval=system("/bin/ls -l"); printf("The return value of system api is %d\n",retval); return 0; } exectest.c #include #include < main() { int retval; char *v[3]={ "ls","-l",NULL}; printf("This is test prg for system api \n"); retval=execv("/bin/ls",v); printf("The return value of execv api is %d\n this got printed since some error in execv func execution",retval); return 0; } gcc exectest.c -o extest ./extest forktest.c #include #include < gps_read(int c) { while(c--) { printf(" This is child proess %d %d\n",getpid(),getppid()); sleep(2); } exit(0); } gsm_send(int c) { while(c--) { printf(" This is parent proess %d \n",getpid()); sleep(2); } wait(); printf(" This is parent proess %d \n",getpid()); } main() { int pid,cpid,i; pid = getpid(); printf("Hello world I will sleep for 5 sec \n"); sleep(5); printf("test prg fork current process pid is %d \n",pid); cpid=fork(); if(cpid == 0) { i=15; gps_read(i); } else { i=25; gsm_send(i); } return 0; } ./forktest While running the above program check the process in one more terminal ps -axf | grep forktest process threads security | performance pthreads: void * my_thread_fun(void *args) { int t=5; while(t--){ printf("in thread %d %s\n",getpid(),(char *)args); sleep(1); } pthread_exit((void *)args); } main() { int i=5; void *retval; pthread_t tid,tid2,tid3; pthread_attr_t t_attr; pthread_attr_init(&t_attr); //pthread_attr_setdetachstate(&t_attr,PTHREAD_CREATE_DETACHED); pthred_create(&tid,&t_attr,my_thread_fun,"vasu"); pthred_create(&tid2,&t_attr,my_thread_fun,"dev"); pthred_create(&tid3,&t_attr,my_thread_fun,"b"); while(i--) { printf("This is in main thread %d\n",getpid()); sleep(1); } pthread_join(tid,&retval); printf("Return value of thread1 is %s",(char *)retval); pthread_join(tid2,&retval); printf("Return value of thread2 is %s",(char *)retval); pthread_join(tid3,&retval); printf("Return value of thread3 is %s",(char *)retval); return 0; } gcc ...... -lpthread find /usr/include -name pthread.h gedit /usr/include/pthread.h pthread_attr_setdetachstate() ---------------------------------------------------------------- IPC: pipe ( simple communication in related process only) fifo ( system level process communication ) message_queue ( managaed ) shared_memory ( high performance for bulk data sharing) semaphore socket pipetest.c main() { int pid,cpid,i; int fd[2]; char buff[20]; printf("test prg fork current process pid is %d \n",pid); pipe(fd); cpid=fork(); if(cpid == 0) { printf("Child Proess sending data \n"); close(fd[0]); write(fd[1],"Hello",6); close(fd[1]); exit(0); } else { printf("Parent Proess rx data \n"); close(fd[1]); read(fd[0],buff,6); printf("Parent Proess rx.ed data %s\n",buff); close(fd[0]); } return 0; } gedit fifoRx.c #define FIFOFILE "fifofile" main() { int fd,len; char buff[20]; printf("Test fifos ...\n"); mkfifo(FIFOFILE,0666); // Creates the fifo file fd=open(FIFOFILE,0666); len = read(fd,buff,20); buff[len]=0; printf("Received data %d %s\n",len,buff); close(fd); //unlink(FIFOFILE); } fifoTx.c fd=open(FIFOFILE,0666); len = write(fd,"embeedlinux",12); printf("Data bytes sent %d \n",len); close(fd); mymsg.h struct mymsg { long msg_type; char msg_data[20]; }; msgqrx.c #include "mymsg.h" main() { int qid; key_t keyval; struct mymsg msgbuff; int i=5; keyval = ftok(".","h"); if((qid = msgget( keyval, IPC_CREAT | 0660 )) == -1) { return -1; } while(i--) { msgrcv(qid,&msgbuff,sizeof(struct mymsg),5,0); printf("Msg rxed from client %d data is %s ",msgbuff.msg_type, } msgbuff.data); } msgqtx1.c #include "mymsg.h" main() { int qid; key_t keyval; struct mymsg msgbuff; keyval = ftok(".",'h'); if((qid = msgget( keyval, IPC_CREAT | 0660 )) == -1) { return -1; } msgbuff.msg_type = 5; strcpy(msgbuff.msg_data,"Hello"); msgsnd(qid,&msgbuff,sizeof(struct mymsg),0); printf("Msg tx %d data is %s\n ",msgbuff.msg_type, msgbuff.data); } grep IPC_CREAT /usr/include/* -nr msgqtx2.c #include "mymsg.h" main() { int qid; key_t keyval; struct mymsg msgbuff; keyval = ftok(".","h"); if((qid = msgget( keyval, IPC_CREAT | 0660 )) == -1) { return -1; } msgbuff.msg_type = 6; strcpy(msgbuff.msg_data,"client2"); msgsnd(qid,&msgbuff,sizeof(struct mymsg),0); printf("Msg tx %d data is %s\n ",msgbuff.msg_type, msgbuff.data); } msgqtx3.c #include "mymsg.h" main() { int qid; key_t keyval; struct mymsg msgbuff; keyval = ftok(".","h"); if((qid = msgget( keyval, IPC_CREAT | 0660 )) == -1) { return -1; } msgbuff.msg_type = 7; strcpy(msgbuff.msg_data,"Hello"); msgsnd(qid,&msgbuff,sizeof(struct mymsg),0); printf("Msg tx %d data is %s\n ",msgbuff.msg_type, msgbuff.data); } shmwr.c #include "mymsg.h" #define SHM_SIZE 1024 main() { int shmid; key_t keyval; int *data; keyval = ftok(".","h"); if((shmid = shmget( keyval, SHM_SIZE, IPC_CREAT | 0770 )) == -1) { return -1; } data= (int * )shmat(shmid, 0,0); if(data == -1 ) { printf("ERROR: Unable to get Shared Memory Ptr\n"); return -1; } *data = 20; } shmrd.c main() { int qid; key_t keyval; int *data; keyval = ftok(".","h"); if((shmid = shmget( keyval, SHM_SIZE, IPC_CREAT | 0770 )) == -1) { return -1; } data = (int *) shmat(shmid, 0,0); printf(" data %d ", *data); } ----------------------------------------------------------------------- Unix Socket --------------------------- Server: #define MY_SOCK_PATH /home/vasu/work/sock_tmp 1. Copy the initial code from bind man page rx_sz = recv(cfd,rxbuff,20,0); if(rx_sz != -1 ) { rxbuff[rx_sz]=0; printf("Data received from client %s",rxbuff); } else printf("Error while data received \n"); tx_sz = send(cfd,"ACK_RXED",8,0) if(tx_sz !=-1) printf("Send data sucess full %d\n",tx_sz); else printf("Error while sending data \n"); close(sfd); close(cfd); unlink(MY_SOCK_PATH); ----------------------- Client: char rxbuff[20]; if(connect(cfd,(struct sockaddr_un *)&myaddr,sizeof(myaddr))==-1) { perror("connect"); exit(1); } retval = send(cfd,"Hello",6,0); printf("data send from client %d \n",retval); recv(cfd,rxbuff,20,0); printf("Data rxed from server %s %d \n",rxbuff,strlen(rxbuff)); close(cfd); } -------------------------------------- #include #include #include #include #define PORT 5555 char rxbuff[20],txbuff[20]="ServerTestMsg"; server.sin_family=AF_INET; server.sin_port=htons(PORT); server.sin_addr.s_addr=inet_addr("127.0.0.1"); retval = recv(cfd,rxbuff,6,0); printf("Data rxed from server %s %d \n",rxbuff,strlen(rxbuff)); retval = send(cfd,txbuff,20); printf("data sent to client %d \n",retval); close(cfd); close(sfd); ----------------------------------------------- Linux Poriting on ARM SOM: SOC + RAM + Flash + PMIC + ( usb hum, eth phy ) ------- RENESAS ------- sudo apt-get install openssh-server sudo apt-get install lib32z1-dev 1. Connect the hachiko board using mini-usb port which is console port ( uart0-ftdi) verify using "dmesg" command and identify the /dev/ttyUSBN 2. sudo minicom -s Opens the configuration window Serial port Setup Press A and change the it to /dev/ttyUSB0kk 3. restart the board to boot loader comman prompt. 4. Set host ready: install tftp & nfs server run tftp script file $ sudo sh tftp-script.sh verify installed servers by: ls /var/lib/tftpboot ls /nfsroot 5. Testing tftp server $cp test_file /var/lib/tftpboot $ rm test_file $ ls $tftp localhost tftp> b // binary transfer mode tftp> get test_file tftp>q $ ls // test_file shoule be availble in work dir 6. To set the ip address ifconfig eth0 192.168.1.78 ping 192.168.1.68 7. To get the file from server tftp -g 192.168.1.68 -r test_file tftp server setup: 1. create the confifile 2. restart the serice 3. to test create the dir sudo mkdir /var/lib/tftpboot change the permission sudo chmod +wr -R /var/lib/tftpboot 4. copy test file cp hello.c /var/lib/tftpboot rm hello.c 5. tftp localhost tftp> get hello.c tftp> quit ls ( hello.c ) NFS Server Setup: sudo gedit /etc/exports #add the below line in the end of exports file /nfsroot *(rw,sync,no_subtree_check,no_root_squash) s sudo mkdir /nfsroot sudo chmod 777 -R /nfsroot sudo /etc/init.d/nfs-kernel-server restart Testing nfs cd ~/elinux/work mkdir nfsdir sudo mount localhost:/nfsroot nfsdir -------------------------------------------------------------- Booting of the Target: Board( SOC ( iFlash, iRam ), DDRRAM, NAND, NOR, SDCard ) Striped Bootloader ( serial, clock, DDR, Nand ) soc(AM335x) can boot from what all device ( nor, nand, spiFlash, serial,eth,usb, sdcard ..) PowerOn-> bootCode (iFlash) -> loads first bin (PBL) iRam -> PBL init DDR and loads the BL -> BL can flash / load / run the kernel & rootfs -------------------------------------------------------- Flashing Bootloader / Kernel Images on Target: 1. Copy the Bootloader image in /var/lib/tftpboot/ cd ~/elinux/work cp ../dvd//images/barebox-image /var/lib/tftpboot 2. configure the host ip address edit networks -> wired connection (edit ) -> ipv4 settings -> add -> 192.168.1.2 255.255.255.0 -> Apply 3. configure the target ip address ifup eth0 devinfo eth0 ping 192.168.1.2 barebox$ help tftp ls cd /tmp tftp barebox-image ls erase /dev/nand0.barebox.bb cp barebox-image /dev/nand0.barebox.bb ----------------------------------------- Flasing Bootloader using NFS ----------------------------------------- 1. Copy the Bootloader image in /nfsroot cd ~/elinux/work cp ../dvd//images/barebox-image /nfsroot 2. On Target barebox command prompt ifup eth0 devinfo eth0 ping 192.168.1.2 cd mnt mkdir nfsdir mount -t nfs 192.168.1.2:/nfsroot nfsdir ls nfsdir erase /dev/nand0.barebox.bb cp nfsdir/barebox-image /dev/nand0.barebox.bb ----------------------------------------------------------------- Toolcahin: ( turboC / turboC++ ) ---------------------------------------------- bin gcc -> gcc.org as,,ld,objcopy , objdump, nm, string ... -> binutils lib -> glibc include - linux kernel ARCH -> core -> soc -> board Toolchin can obtained: a. Compile it from the scratch b. Compile it using Build System ( BuildRoot, ScratchBox, OpenEmbedded, Yocto, ptxDist) c. get the pre-built Installing toolchain for target: go to work cd ~/elinux/work tar -xvf ../dvd//tools/toolchain/arm-cortexa8-linux-gnueabihf.tar.bz2 cd arm-cortexa8-linux-gnueabihf/gcc-..../bin ls pwd cd ~/elinux/work ; gedit envsetup.sh & envsetup.sh ----------------------- export PATH=$PATH: To Execute the envsetup.sh chmod +x envsetup.sh . envsetup.sh --------------------------------------------------------------------- cd ~/elinux/work tar -xvf ../dvd//src/bootloader/barebox/... ls arc/arm/configs/rana gedit ../envsetup.sh export ARCH=arm export CROSS_COMPILE=arm-cortexa8-linux-gnueabihf- . ../envsetup.sh make distclean make _mlo_defconfig //board_name in arch/arm/configs make // this will build your Primay bootloader -> MLO make _defconfig //board_name in arch/arm/configs make // this will build your bootloader -> barebox-image gedit common/startup.c "running /env/bin/init ...." make ------------------------------------------------------------------ Compiling U-Boot - Firware update - different options to Flash the images - prepares the env for OS - data sharing between u-boot & kernel is done by DataStructure called ATAG. cd ~/elinux/work tar -xvf ../dvd/OpenBoard/src/bootloader/uboot/u-boot.tar.gz u-boot - arch arm -cpu armv7 omap-common omap3 ti-81xx start.S u-boot.lds -lib -board.c -board phytec pcm051 pcm051.c -drivers -common main.c uboot compilation # make sure the toolchain path, ARCH & CROSS_COMPILE has been set make distclean make pcm051_config // see boardname in include/configs/ make // On sucess u-boot.bin is created ---------------------------------------------- Linux Kernel: cd ~/elinux/work tar -xvf ../dvd//src/linux/linux-3.2.tar.bz2 cd linux-3.2 ls arch/arm/configs/_defconfig // rana_am335x , pcm051lb are the board name make distclean make _defconfig //board_name in arch/arm/configs make uImage -j4 // this will build your linux kernel arch/arm/boot/uImage is created 1. copy the uImage to tftpboot folder 2. go to target tftp the uImage erase /dev/nand0.kernel.bb cp --------------------------------------------------------------- Linux Kernel - Kernel Dir Stru - Code Flow - Kernel Build system ( Kconfig ) - different Kernel images ( vmlinux, Image, uImage zImage ) Bootloader -> copy the uImage to ram, fills the registers with processor id & machine-id, then prepares the ATAG datastructure and copy it in RAM location. jump. linux - arch arm plat- mach- kernel ( head.S, head-common.S, debug.S ) configs ( _defconfig ) boot ( linux bootstrap code ) compress ( head.S, misc.c ) tools ( mach-types ) - drivers - Documentation - init (main.c ) - kernel - fs - net - sound ---------------------- arch/arm/kernel/head.S, head-common.S stext p->init_machine(); -> rana_am335x_init(); start_kernel ->rest_init- - kthread - kernel_init - init_post() ---------------------------------------- Kernel Config System ( Kconfig ) linux -> dirvers -> misc -> Kconfig KCS has collection of Kconfig files .config file autoconf.h Makefile Kconfig config SLED_DRV tristate "My satus led" depnds on I2C default y help this is a test driver configuration . ../env.sh // Set the toolchian make menuconfig ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- "Enable the image sensor driver " make uImage copy the uImage from arch/arm/boot/ to /var/lib/tftpboot tftp uImage bootm uImage Makefile: obj-$(CONFIG_SLED_DRV) +=sled.o obj-y += sled.o // will be linked in vmlinux obj-m +=sled.o // sled.ko will be generated need to be part to RFS obj- += sled.o gedit vt100.c cd ~/work/linux-3.8.13 find /driver -name '*.o' > objlist_drivers.txt find /arch/arm -name '*.o' > objlist_arm.txt gedit objlist.txt ----------------------- Buildroot: Building rootfile system 1. go to cd ~/work/DVD/buildroot --->>>dirctory 2. Extract buildroot to work directory $tar -xvf -C ~/work $mkdir ~/work/buildroot-2014.05/output $cp -rf rootfs_overrlay ~/work/buildroot-2014.05/output $cp -rf dl ~/work/ $cp hachiko_defconfig ~/work/buildroot-2014.05 $cd ~/work/buildroot-2014.05 $ln -s ../dl dl 3. go to ~/work/buildroot.2014.05 $. ~/work/env.sh $cp hachiko_defconfig configs/ $make hachiko_defconfig $make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig to test the RFS by buildroot sudo mv /nfsroot /nfsroot_bakup sudo mkdir /nfsroot cd ~/work/buildroot-2014.05 sudo tar -xvf output/images/rootfs.tar.bz2 -C /nfsroot/ --------------------------------------------------------------------------------- extern int sum(int,ini); #include #include #include static char *strval = "world"; static int num = 1; module_param(num, int, S_IRUGO); module_param(strval, charp, S_IRUGO); int sum(int a, int b) { return a+b; } EXPORT_SYMBOL(sum); int init_module(void) { printk(KERN_ALERT "This is test driver %d %d %s \n",sum(10,2)); return 0; } void cleanup_module(void) { printk(KERN_ALERT "This is test driver %d %s..... \n\n\n\n\n",num,strval); } MODULE_LICENSE("GPL"); grep obj-y * -nr sudo insmod m1.ko num=100 strval=elinux lsmod | grep m1 ------------------------------------------------------------- vmlinux in linux dir Image arch/arm/boo compressed + bootstap is added zImage zImage + UbootHeader ( is done by mkimage ) uImage --------------------------------------------------------------- RFS: Components of Root File System - Unix Dir Structure ( mkdir - device nodes ( mknode - Scripts ( gedit - bin ( busybox ) - lib [ optional ] hello.c printf("%s",argv[0]); gcc hello.c -o hello ./hello -> hello ln -s hello vasu ./vasu -> vasu ln -s hello ls ./ls -> ls main.c ls.c mkdir.c tar.c main() { if(!strcmp(argv[0],"ls") do_ls(); if(!strcmp(argv[0],"mkdir") do_mkdir(); gcc main.c -o busybox busybox ls -> busybox ./ls Compiling RFS using buirldroot cd ~/elinux/work tar -xvf ../dvd//buildsystem/buildroot/buil... tar -xvf ../dvd/dl.tar.bz2 cd buildroot cd buildroot.. make distclean rm dl ; ln -s ../dl dl make _defconfig make // images would be created in output/images dir -------------------------------------------------------- Boot the Rootfs in NFS Server 1. extract the rootfs in /nfsroot sudo tar -xvf ~/elinux/dvd/phyBoard/images/root.tar.bz2 -C /nfsroot cp ~/elinux/work/linux-3.2/arch/arm/boot/uImage /var/lib/tftpboot/linuximage 2. configure the bootloader to boot with NFS go to barebox command pompt exit option 3 tftp -r -g ------------------------------------ Device Drivers: - Kernel Modules cd ~/elinux/work mkdir dd ; cd dd cp ../linux-3.2/drivers/misc/vt100.c m1.c gedit Makefile #K_SRC=${HOME}/elinux/work/linux-3.2 K_SRC=/lib/modules/`uname -r`/build obj-m += m1.o all: make -C ${K_SRC} M=${PWD} modules HOST: cp m1.ko /nfsroot/home TARGET: insmod m1.ko lsmod cat /proc/modules dmesg rmmod m1 -------------------------------------------------------------- Device Drivers: - Char Driver - Block Drivers - Network Drivers - Misc Drivers open,close,read,write,ioctl,mmap gedit myled.c #include #include #include #define LED_ON 51 #define LED_OFF 52 int myled_ioctl(struct file *fp,unsinged int cmd,unsinged long argp) { printk( ... switch(cmd) { case LED_ON: gpio_set_value(103,1); break; case LED_OFF: gpio_set_value(103,0); break; default: printfk(KERN_INFO"Invalid led driver command \n"); } return 0; } struct file_operations myled_fops = { .owner = THIS_MODILE, .open = myled_open, .release = myled_close, .read = myled_read, .write = myled_write, .unlocked_ioctl = myled_ioctl }; int init_module(void) { printk(KERN_ALERT "This is test driver \n"); maj_num = register_chrdev(0,"MY_LED",&myled_fops); return 0; } void cleanup_module(void) { printk(KERN_ALERT "This is test driver \n\n\n\n\n"); unregister_chrdev(maj_num,"MY_LED"); } MODULE_LICENSE("GPL"); ---------------------------------- sudo insmod myled.ko cat /proc/devices maj name sudo mknod /dev/myled c 248 0 --------------------------------------------- gedit myapp.c main() { int fd; int retval; char buff[20]; int status=0; fd=open("/dev/myled",0666); printf(" open %d \n",fd); // retval = write(fd,"Hello",6); // printf(" write %d \n", retval); while(i--) { status = !status; if(status) { retval = ioctl(fd,LED_ON,0); printf(" LED ON \n") } else { retval = ioctl(fd,LED_OFF,0); printf(" LED OFF \n"); } } retval = read(fd,buff,6); printf(" read %d \n", retval); retval = close(fd); printf("file closed %d\n",retval); } sudo chmod 777 /dev/myled ------------------------------- cd ~/elinux/work mkdir cosmic cd cosmic tar -xvf ../../dvd/Cosmic-AM335x/src/linux/linux-tar.bz2 tar -xvf ../../dvd/Cosmic-AM335x/tools/toolchain/arm..... cp ../envsetup.sh . gedit envsetup.sh // change the path of the toolcain for cosmic go to linux dir configure it and compile ( pcm051lb ) ----------------------------------------------------------------- /linux/drivers/gpio gpiolib.c gpio-ompa.c GPIO3_7 = (3x32) + 7 #include gpio_request(103,"SLED1"); ( take ) gpio_direction_output(103,1); ( configure ) gpio_set_value( ( act ) status = !status; if( status ) gpio_set_value(103,1); else gpio_set_value(103,0); gpio_free(103); ( release ) ----------------------------------------------------------- Linux Kernel Intterup linux/kernel/irq/ manage.c all the apis are available for the dirvers the irq_chip is the hook to integrate the hardware interrupt controller. arch/arm/mach-omap2/irq.c irq_setup_generic_chip /arch/arm/plat-omap/include/plat/irqs.h # #include #include #include button_isr_rest() { } request_irq(irq_num,handler,flags,name,devid); irqreturn_t button_isr(int irq, void *dev) { toggle_led(); schedule_tasklet(button_isr_rest()); schedule_ return IRQ_HANDLED; // if you do not handle IRQ_NONE } init gpio_request(41,"button1"); gpio_direction_input(41); request_irq( gpio_to_irq(41),button_isr,IRQ_TYPE_EDGE_FALLING "MY_BUTTON1",NULL); cleanup free_irq( gpio_to_irq(41),NULL); free_gpio(41); ,switch_handler,IRQ_TYPE_EDGE_RISING,\ "switch_handler",(void*)104)) ----------------------------------------------------------- Bottom Half: the seperated tread of the ISR Schedulet to kernel by the driver. -Sorftirq -tasklet -workqueue ( process context ) Kernel Concuerrency: arm-cortexa8-linux-gnueabi-gcc hello.c -o hello -g Taget: transfer to target & execute below command ifcofig eth0 gdbserver localhost:555 ./hello Host: arm-cortexa8-linux-gnueabi-gdb hello (gdb) target remote :555 (gdb) b main (gdb) c (gdb) n sudo apt-get install ddd code.google.com/p/myboards . ./envsetup.sh make menuconfig Kernel Hacking -> Kernel Debugging Compile the Kernel with Debuginfo KGDB with remote gdb kgdb over serial compile kernel To run: Bootloader: setenv bootargs 'console=ttySAC0,115200 kdgb=ttySAC0,115200 kgdboc=ttySAC0,115200N8 kgdbwait' tftp uImage bootm uImage #it will stop at start_kernel $ ddd \96debugger arm-none-linux-gnueabi-gdb vmlinux Ram file systems procfs sysfs debugfs ----------------------------- Contact: Support: info@easyarm.com H/W : support@phytec.in "Enabling Embedded Learning in INDIA" ================================ web: www.easyarm.com || e-mail: info@easyarm.com || Ph: +91-8041307589 || Mob: +91-9731885420