Вы находитесь на странице: 1из 42

MakIng AndroId DrIvers Work

UsIng OpenOCD ]TAC


In AndroId KerneI
DebuggIng
Mike Anderson
Chief Scientist
The PTR Group, nc.
http://www.theptrgroup.com
O-A8-]TAC-2 CopyrIght 2012, The PTR Croup, nc.
What We WIII TaIk About
DevIce drIvers In AndroId
The ]TAC InterIace
Types oI ]TAC InterIaces
How to use a ]TAC to debug the kerneI
OpenOCD project
CettIng and InstaIIIng OpenOCD
tartIng OpenOCD
ConnectIng CD8
DebuggIng KerneI Code w] OpenOCD
O-A8-]TAC-3 CopyrIght 2012, The PTR Croup, nc.
DevIce DrIvers In AndroId
Thanks to the use oI the LInux kerneI,
AndroId has severaI drIver types
Character, bIock, network, etc.
AndroId uses a IormaI drIver modeI
DrIvers present a common AP such as
open(), reIease(), read(), wrIte(), etc.
User-mode devIce drIvers are aIso
possIbIe
VIa ]dev]mem, etc.
EasIer to debug usIng standard CD8
O-A8-]TAC-4 CopyrIght 2012, The PTR Croup, nc.
8asIc DrIver DebuggIng RequIrements
n order to be abIe to debug a drIver
under AndroId, you'II need to add some
support to your pIatIorm
You must have It rooted
You have to be abIe to Ioad]unIoad the drIvers
Can be done vIa adb
You'II need to have busybox InstaIIed
You need severaI utIIItIes provIded by busybox
You'II need to compIIe the kerneI wIth
debuggIng enabIed
O-A8-]TAC-5 CopyrIght 2012, The PTR Croup, nc.
ConIIgure KerneI Ior DebuggIng
EnabIe debuggIng InIo and rebuIId the kerneI
O-A8-]TAC-6 CopyrIght 2012, The PTR Croup, nc.
The KerneI 8oot equence
LIke the boot IIrmware, the kerneI starts In assembIy
Ianguage
ets up the caches, InItIaIIzes some MMU page tabIe entrIes,
conIIgures a "C" stack and jumps to a C entry poInt caIIed
startkerneI() (InIt]maIn.c)
startkerneI() Is then responsIbIe Ior:
ArchItecture and machIne-specIIIc hardware InItIaIIzatIon
nItIaIIzIng vIrtuaI memory
tartIng the system cIock tIck
nItIaIIzIng kerneI subsystems and devIce drIvers
InaIIy, a system consoIe Is started and the InIt process
Is created
The InIt process (PD 1) Is then the start oI aII user-space
processIng
KerneI moduIes can now be dynamIcaIIy Ioaded
O-A8-]TAC-7 CopyrIght 2012, The PTR Croup, nc.
DrIver nItIaIIzatIon equence
DrIvers must regIster themseIves wIth the
kerneI
regIsterchrdev(), regIsterbIkdev(),
regIsternetdev(), etc.
or bIock and character drIvers you'II
need to assIgn major]mInor numbers
Can be done statIcaIIy or dynamIcaIIy
CoordInate wIth
<IInux>]DocumentatIon]devIces.txt
You'II need to create devIce nodes as weII
O-A8-]TAC-8 CopyrIght 2012, The PTR Croup, nc.
ExampIe LoadabIe ModuIe
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL and additional rights");
MODULE_AUTHOR( "Driver_Author@someplace.org" );
MODULE_DESCRIPTION( "My first driver!" );
int __init mymodule_init_module(void) {
printk(KERN_DEBUG "mymodule_init_module() called, ");
return 0;
}
void __exit mymodule_cleanup_module(void) {
printk(KERN_DEBUG "mymodule_cleanup_module() called\n");
}
module_init(mymodule_init_module);
module_exit(mymodule_cleanup_module);
O-A8-]TAC-9 CopyrIght 2012, The PTR Croup, nc.
CIvIng Your DrIver omethIng to do
Character devIce drIver exports servIces
In IIIeoperatIons structure
There are 25 supported operatIons In the
2.6]3.x kerneI
The IunctIon IIst has changed sInce earIy 2.6
kerneIs
You onIy suppIy those caIIs that make
sense Ior your devIce
You can expIIcItIy return error codes Ior
unsupported IunctIons or have the
system return the deIauIt ENOTUPP
error
TypIcaIIy, the IIIeoperatIons structure Is
statIcaIIy InItIaIIzed
UsIng C99 tagged InItIaIIzer Iormat
ource: tIgger.uIc.edu
O-A8-]TAC-10 CopyrIght 2012, The PTR Croup, nc.
struct IIIeoperatIons #1 oI 2
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *,
size_t, loff_t *);
ssize_t (*aio_read) (struct kiocb *, const struct iovec *,
unsigned long, loff_t);
ssize_t (*aio_write) (struct kiocb *, const struct iovec *,
unsigned long, loff_t);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
long (*unlocked_ioctl) (struct file *, unsigned int,
unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *, fl_owner_t id);
O-A8-]TAC-11 CopyrIght 2012, The PTR Croup, nc.
struct IIIeoperatIons #2 oI 2
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, loff_t, loff_t, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*sendpage) (struct file *, struct page *, int,
size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *,
unsigned long, unsigned long, unsigned long,
unsigned long);
int (*check_flags)(int);
int (*flock) (struct file *, int, struct file_lock *);
ssize_t (*splice_write)(struct pipe_inode_info *,
struct file *, loff_t *, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, loff_t *,
struct pipe_inode_info *, size_t, unsigned int);
int (*setlease)(struct file *, long, struct file_lock **);
long (*fallocate)(struct file *file, int mode, loff_t offset,
loff_t len);
};
O-A8-]TAC-12 CopyrIght 2012, The PTR Croup, nc.
nItIaIIzIng the IIIeoperatIons
C99 tagged InItIaIIzatIon oI the structures
aIIows you to InItIaIIze the IIeIds by name
No worry about the structure Iayout (whIch may
change between kerneI revIsIons)
Un-InItIaIIzed IunctIon entrIes In the structure
shown beIow wIII be InItIaIIzed to NULL
struct file_operations fops = {
.read = my_read,
.write = my_write,
.compat_ioctl = my_ioctl,
.open = my_open,
.release = my_release
};
O-A8-]TAC-13 CopyrIght 2012, The PTR Croup, nc.
OId chooI DrIver RegIstratIon
KerneI Is made aware oI a character
devIce drIver when the drIver
regIsters ItseII
TypIcaIIy In the InIt IunctIon
RegIstratIon makes the assocIatIon
between the major number and devIce drIver
int register_chrdev(unsigned int major,
const char *name, struct file_operations *fops)
ource: tecbd.asu.edu
O-A8-]TAC-14 CopyrIght 2012, The PTR Croup, nc.
OId chooI DrIver RegIstratIon #2
LIkewIse, when a devIce
drIver removes ItseII Irom
the system, It shouId
unregIster ItseII Irom the
kerneI to Iree up that major
number
TypIcaIIy In the exIt
IunctIon:
int unregister_chrdev(unsigned
int major, const char *name);
ource: mIdnIght-rIde.com
O-A8-]TAC-15 CopyrIght 2012, The PTR Croup, nc.
New-chooI DrIver RegIstratIon
I you need to get beyond
the 256 major IImIt, you'II
need to use a dIIIerent
approach
ThIs uses a dIIIerent AP,
devt, cdev structures and a
much more InvoIved
regIstratIon approach
AII oI thIs Is beyond scope
Ior the current dIscussIon,
however
ource: IIIckr.com
O-A8-]TAC-16 CopyrIght 2012, The PTR Croup, nc.
tatIcaIIy LInked - DynamIcaIIy Loaded
The typIcaI kerneI-mode drIver can be
statIcaIIy IInked Into the kerneI at kerneI
buIId tIme
Must be IIcensed under CPL
nItIaIIzed In startkerneI() sequence
DynamIcaIIy-Ioaded drIvers, a.k.a. kerneI
moduIes, are Ioaded aIter the kerneI Is
booted
TypIcaIIy durIng the InIt.rc scrIpt
Can have proprIetary IIcenses
O-A8-]TAC-17 CopyrIght 2012, The PTR Croup, nc.
DebuggIng DevIce DrIvers
tatIcaIIy-IInked devIce drIvers are notorIousIy
dIIIIcuIt to debug
An error can cause a panIc or oops beIore you can
even get prIntk() to work
These wIII typIcaIIy requIre a ]TAC to debug them
easIIy
DynamIcaIIy-IInked drIvers are margInaIIy easIer
because you can get more debuggIng
InIrastructure Into pIace beIore IoadIng them
The use oI readproc()]wrIteproc() IunctIons and
prIntk() are typIcaI
]TACs can heIp here too
O-A8-]TAC-18 CopyrIght 2012, The PTR Croup, nc.
Enter the ]TAC Port
The ]oInt Test ActIon Croup
(]TAC) Is the name
assocIated wIth the EEE
1149.1 standard entItIed
tandard Test Access Port
and 8oundary-can
ArchItecture
OrIgInaIIy Introduced In 1990
as a means to test prInted
cIrcuIt boards
An aIternatIve to the bed oI
naIIs
Source: Test EIectronIcs
O-A8-]TAC-19 CopyrIght 2012, The PTR Croup, nc.
How ]TAC Works
]TAC Is a boundary-scan devIce that
aIIows the deveIoper to sampIe the vaIues
oI IInes on the devIce
AIIows you to change those vaIues as weII
]TAC Is buIIt to aIIow chaInIng oI muItIpIe
devIces
Works Ior muItI-core processors, too
O-A8-]TAC-20 CopyrIght 2012, The PTR Croup, nc.
]TAC DetaIIs
]TAC Is a sImpIe serIaI protocoI
EnabIes the use oI "wIggIer"-styIe InterIaces
ConIIguratIon Is done by manIpuIatIng the
state machIne oI the devIce vIa the TM
IIne
O-A8-]TAC-21 CopyrIght 2012, The PTR Croup, nc.
]TAC-Aware Processors
Most embedded processors today support ]TAC
or one oI Its reIatIves IIke 8DM
E.g., ARM]XcaIe, PPC, MP
Even the x86 has a ]TAC port
nteI Atom-based processors typIcaIIy support the
XD8 port
Other x86-based processors may need TP-700
connectors or Interposer boards
ome processors IIke MP come In dIIIerent
versIons
ome wIth ]TAC ports Ior deveIopment, some wIthout
In order to save $$$
O-A8-]TAC-22 CopyrIght 2012, The PTR Croup, nc.
]TAC ConnectIons
The maxImum speed oI ]TAC Is 100 MHz
A rIbbon cabIe Is usuaIIy suIIIcIent to connect
to the target
ConnectIon to the deveIopment host Is
accompIIshed vIa
ParaIIeI port
U8
erIaI port
Ethernet
Source: Abatron
Source: WInd RIver
Source: MacraIgor
O-A8-]TAC-23 CopyrIght 2012, The PTR Croup, nc.
]TAC User nterIace
ome ]TAC InterIaces use
a CD8-styIe soItware
InterIace
Any CD8-aware Iront end
wIII work
Others have EcIIpse pIug-
Ins to access the ]TAC vIa
an DE
ome stIII use a
command IIne InterIace
Source: WIndRIver.com
Source: Ibm.com
O-A8-]TAC-24 CopyrIght 2012, The PTR Croup, nc.
What can you do wIth a ]TACZ
TypIcaI ]TAC usage IncIudes reIIashIng boot
IIrmware
Even the reaIIy cheap ]TAC unIts can do thIs
However, It Is In the use as a debuggIng aId that
]TAC comes Into Its own
You can set hardware or soItware breakpoInts and
debug In source code
ophIstIcated breakpoInt strategIes and muItI-core
debuggIng usuaIIy requIre the more expensIve unIts
]TAC unIts can aIso be used to exercIse the
address bus and perIpheraIs
ThIs Is what ]TAC was orIgInaIIy desIgned Ior
O-A8-]TAC-25 CopyrIght 2012, The PTR Croup, nc.
Hardware ConIIguratIon IIes
Most ]TAC unIts requIre you to descrIbe the
hardware regIsters In a conIIguratIon IIIe
ThIs Is aIso how you descrIbe what processor
archItecture you are usIng
AII oI that InIormatIon about regIster maps that
you coIIected earIIer now goes Into the
conIIguratIon IIIe
UnIortunateIy, there Is no standard Iormat Ior
these conIIguratIon IIIes
Each ]TAC vendor uses dIIIerent syntax
O-A8-]TAC-26 CopyrIght 2012, The PTR Croup, nc.
ExampIe ConIIguratIon IIes
Many ]TAC unIts spIIt the conIIguratIon
IIIes Into a CPU regIster IIIe and a board
conIIguratIon IIIe
O-A8-]TAC-27 CopyrIght 2012, The PTR Croup, nc.
AndroId-Aware ]TACs
There are severaI rather trIcky transItIons
durIng the AndroId bootIng process
TransItIonIng Irom IIash to RAM
TransItIonIng Irom physIcaI addresses to kerneI
vIrtuaI addresses
These transItIons requIre the use oI hardware
breakpoInts
8oth your processor and the ]TAC unIt need to
support hardware breakpoInts to debug these
transItIons
Make sure that your ]TAC Is "MMU aware"
t must understand AndroId]LInux's use oI the
MMU to be oI much use Ior drIver debuggIng
O-A8-]TAC-28 CopyrIght 2012, The PTR Croup, nc.
OpenOCD Project
ThIs project was started In 2008 to create a
soItware InterIace Ior the InexpensIve
wIggIer-styIe InterIaces
8ased on a graduate thesIs paper
OrIgInaI targets where Iower-end ARM MCUs
ARM7TDM]ARM9TDM
Now supports many hIgh-end ARM
processors such as T DavIncI and Cortex A8
No workIng muItI-core yet
CurrentIy hosted as a CT reposItory at
http:]]sourceIorge.net]projects]openocd
O-A8-]TAC-29 CopyrIght 2012, The PTR Croup, nc.
upported OperatIng ystems
OpenOCD Is avaIIabIe Ior the three major O]
pIatIorms
LInux, WIndows, O]X
O]X InstaIIatIon can be Iound here:
http:]]www.ethernut.de]eIektor]tooIs]unIx]
openocdosx.htmI
WIndows InstaIIatIon can be Iound here:
http:]]www.ethernut.de]eIektor]tooIs]wIn]
openocdwIn.htmI
8ased on the YACARTO project
WIndows ARM tooI chaIn
http:]]www.yagarto.de]
ncIudes EcIIpse support
We'II show you the basIcs oI LInux InstaIIatIon
next
O-A8-]TAC-30 CopyrIght 2012, The PTR Croup, nc.
CettIng]nstaIIIng OpenOCD - LInux
OpenOCD Is avaIIabIe as an anonymous
gIt cIone request:
git clone git://openocd.git.sourceforge.net/gitroot/openocd/openocd
Once retrIeved, conIIgure and buIId
(OpenOCD 5.0)
cd openocd
./bootstrap
./configure -enable-maintainer-mode
make
sudo make install
You'II need to enabIe the InterIace that
your ]TAC uses
O-A8-]TAC-31 CopyrIght 2012, The PTR Croup, nc.
ExampIe upported nterIaces
OpenOCD supports over 50 dIIIerent ]TAC
InterIaces
O-A8-]TAC-32 CopyrIght 2012, The PTR Croup, nc.
The ARM CPU support Is aIso quIte good
upported Target CPUs
O-A8-]TAC-33 CopyrIght 2012, The PTR Croup, nc.
What can OpenOCD doZ
n spIte oI the Iact that It's Iree, OpenOCD
Is reaIIy quIte IuII Ieatured
t supports erasIng]programmIng
NOR]NAND IIash segments
LoadIng and debuggIng code on the
supported targets
AccessIng regIsters on the target
processor
WorkIng wIth PLD]PCA devIces
AddIng extensIons vIa TcI InterIace
O-A8-]TAC-34 CopyrIght 2012, The PTR Croup, nc.
RunnIng OpenOCD
OpenOCD uses a strIpped versIon oI TcI
(]M-TcI) at Its core
KnowIng TcI Isn't requIred, but It sure heIps
OpenOCD uses a daemon to Iront end the
]TAC hardware InterIace
You can access It vIa teInet at port 4444
The OpenOCD command IIne aIIows you
to pass conIIguratIon IIIes
E.g., openocd -f interface/flyswatter.cfg \
-f board/ti_beagleboard_xm.cfg
O-A8-]TAC-35 CopyrIght 2012, The PTR Croup, nc.
The TeInet nterIace
rom the teInet sessIon you can exercIse
a Iot oI controI over the target
reset, haIt, Ioad code, access regIsters,
dump]change memory, set
breakpoInts]watchpoInts, sIngIe-step
InstructIons and much more
The teInet sessIon aIso supports IIIe ]O
Ior IoadIng and dumpIng memory and TcI
commands Ior scrIptIng
O-A8-]TAC-36 CopyrIght 2012, The PTR Croup, nc.
CD8 and OpenOCD
CD8 can connect to OpenOCD daemon vIa
"target remote" command to port 3333
Another optIon Is to use LInux pIpes
upports the use oI varIous CD8 Iront-
ends such as DDD, EcIIpse, IIckEdIt,
NemIver and others
Use the CD8 "mon" command to pass a
command to the OpenOCD daemon
E.g., mon mdw 0x2100000 to dump memory
at 0x2100000
O-A8-]TAC-37 CopyrIght 2012, The PTR Croup, nc.
DDD CU ront-End ExampIe
nvoked Irom command
IIne wIth kerneI compIIed
Ior debuggIng
Use the -debugger
command IIne optIon to
Ioad the cross debugger
back end:
ddd -debugger
arm-linux-gdb vmlinux
Then attach to ]TAC
usIng "target remote"
command:
(gdb) target remote 127.0.0.1:3333
O-A8-]TAC-38 CopyrIght 2012, The PTR Croup, nc.
AddIng DevIce DrIver ymboIs
tatIcaIIy IInked drIver symboIs are
aIready buIIt Into the kerneI's symboI
tabIe
ImpIy set break poInts on the drIver
methods themseIves
DynamIcaIIy Ioaded drIvers requIre
addItIonaI steps
We need to IInd the addresses used by the
drIver
The next Iew charts assume you're usIng
OpenOCD
O-A8-]TAC-39 CopyrIght 2012, The PTR Croup, nc.
DebuggIng LoadabIe ModuIes
n order to debug a Ioaded moduIe, we need to
teII the debugger where the moduIe Is In memory
The moduIe's InIormatIon Is not In the kerneI Image
because that shows onIy statIcaIIy-IInked drIvers
ThIs InIormatIon can typIcaIIy be Iound In
/proc/modules or
/sys/module/<modulename>/sections/.text
We then use the add-symbol-file CD8 command
to add the debug symboIs Ior the drIver at the
address Ior the Ioaded moduIe
(gdb)add-symbol-file ./mydriver.o 0x<addr>
How we proceed depends on where we need to
debug
O-A8-]TAC-40 CopyrIght 2012, The PTR Croup, nc.
DebuggIng LoadabIe ModuIes #2
I we need to debug the InIt code, we need to
set a breakpoInt In the IoadmoduIe() IunctIon
We'II need to breakpoInt just beIore the controI
Is transIerred to the moduIe's InIt
omewhere around IIne 2981 oI moduIe.c:
/* Start the module */
if (mod->init != NULL)
ret = do_one_initcall(mod->init);
Once the breakpoInt Is encountered, we can
waIk the moduIe address IIst to IInd the
assIgned address Ior the moduIe
O-A8-]TAC-41 CopyrIght 2012, The PTR Croup, nc.
AddIng AddItIonaI 8reakpoInts
Once you've added the moduIe's symboIs,
you can set breakpoInts at the varIous
entry poInts oI the drIver
(gdb) b mydriver_read
Other good breakpoInt IocatIons IncIude:
sys_sync
panic
oops_enter
When you hIt the breakpoInt, the
debugger wIII drop to the source code
and you can start sIngIe steppIng code
O-A8-]TAC-42 CopyrIght 2012, The PTR Croup, nc.
ummary
DespIte Its Iow cost, OpenOCD and sImpIe
wIggIer-styIe ]TAC InterIaces make a
powerIuI combInatIon
upport Ior a wIde-varIety oI processors
upport Ior Iash erasIng]programmIng
upports debuggIng LInux kerneI code usIng
standard CD8 InterIace and technIques
UnIortunateIy, there Is no muItI-core
support In OpenOCD yet
However, Ior the deveIoper on a budget,
OpenOCD Is a great optIon

Вам также может понравиться