You are on page 1of 8

8/5/13

Write For Us Submit Tips

Device Drivers, Part 7: Generic Hardware Access in Linux - LINUX For You
Subscribe to Print Edition Search

HOME

REVIEWS

HOW-TOS

CODING

INTERVIEWS

FEATURES

OVERVIEW

BLOGS

SERIES

IT ADMIN

Device Drivers, Part 7: Generic Hardware Access in Linux
By Anil Kumar Pugalia on June 1, 2011 in Coding, Developers · 23 Comments and 0 Reactions

Search for:

Search

This article, which is part of the series on Linux device drivers, talks about accessing hardware in Linux.
Shweta was all jubilant about her character driver achievements, as she entered the Linux device drivers laboratory on the second floor of her college. Many of her classmates had already read her blog and commented on her expertise. And today was a chance to show off at another level. Till now, it was all software — but today’s lab was on accessing hardware in Linux. In the lab, students are expected to learn “by experiment” how to access different kinds of hardware in Linux, on various architectures, over multiple lab sessions. Members of the lab staff are usually reluctant to let students work on the hardware straight away without any experience — so they had prepared some presentations for the students (available here).

Get Connected RSS Feed Twitter

Generic hardware interfacing
As every one settled down in the laboratory, lab expert Priti started with an introduction to hardware interfacing in Linux. Skipping the theoretical details, the first interesting slide was about generic architecture-transparent hardware interfacing (see Figure 1).

LINUX For You on

Follow

+2,474

Figure 1: Hardw are mapping

The basic assumption is that the architecture is 32-bit. For others, the memory map would change accordingly. For a 32-bit address bus, the address/memory map ranges from 0 (0 x 0 0 0 0 0 0 0 0 ) to “232 – 1″ (0 x F F F F F F F F ). An architecture-independent layout of this memory map would be like what’s shown in Figure 1 — memory (RAM) and device regions (registers and

www.linuxforu.com/2011/06/generic-hardware-access-in-linux/

1/8

linuxforu. into the constructor and destructor of her existing “null” driver.8/5/13 Device Drivers.. h > ): u n s i g n e di n ti o r e a d 8 ( v o i d* v i r t _ a d d r ) . and the later 1GB (0 x C 0 0 0 0 0 0 0to 0 x F F F F F F F F ) for device maps. Part 7: Generic Hardware Access in Linux . 2013 · 3 Comments · Priyanka Sarkar What it Takes to be an Open Source Expert June 20. Open Source For You Like 251. She added the above APIs. Shweta got onto the system and went through / p r o c / i o m e m(as in Figure 2) and got the video RAM address. or are to be obtained from the data-sheets (i. to convert it into a “vram” driver. 2013 · 5 Comments · Priyanka Sarkar PHP Development: A Smart Career Move June 20. u n s i g n e di n ti o w r i t e 1 6 ( u 1 6v a l u e .e. However. The corresponding APIs (prototyped in < a s m / i o . the addresses referring to RAM are termed as physical addresses. 2013 · 2 Comments · sophie-samuel New and amazing features of Linux May 6. For that.u n s i g n e dl o n gd e v i c e _ r e g i o n _ s i z e ) . but are to be mapped to virtual addresses and then accessed through them — thus making the RAM and device accesses generic enough.v o i d* v i r t _ a d d r ) . Run c a t/ p r o c / i o m e mto list the memory map on your system.com/2011/06/generic-hardware-access-in-linux/ 2/8 . etc. the SuperHyway bus in SuperH architectures. The suggested initial experiment was with the video RAM of “DOS” days. with appropriate parameters. the initial 3 GB (0 x 0 0 0 0 0 0 0 0to 0 x B F F F F F F F ) is typically for RAM. u n s i g n e di n ti o r e a d 1 6 ( v o i d* v i r t _ a d d r ) . the following are the APIs (also prototyped in < a s m / i o . u n s i g n e di n ti o r e a d 3 2 ( v o i d* v i r t _ a d d r ) . students were directed for the live experiments. v o i di o u n m a p ( v o i d* v i r t _ a d d r ) . it depends on the device datasheet as to which set of device registers and/or device memory to read from or write into. Once mapped to virtual addresses. These addresses actually are architecture-dependent. here’s her new file — v i d e o _ r a m .v o i d* v i r t _ a d d r ) . none of these are directly accessible. u n s i g n e di n ti o w r i t e 3 2 ( u 3 2v a l u e . 2013 · 1 Comments · Prashant Phatak Cyber Attacks Explained: Cryptographic Attacks Figure 2: Physical and bus addresses on an x86 system Irrespective of the actual values. h > www. ranging from 0 x 0 0 0 A 0 0 0 0to 0 x 0 0 0 B F F F F . to understand the usage of the above APIs.503 people like Open Source For You. h > ) for mapping and unmapping the device bus addresses to virtual addresses are: v o i d* i o r e m a p ( u n s i g n e dl o n gd e v i c e _ b u s _ a d d r e s s .v o i d* v i r t _ a d d r ) . if the RAM is less. 2013 · 1 Comments · Deepti Sharma A Simple guide to building your own Linux Kernel May 6. Accessing the video RAM of ‘DOS’ days After this first set of information. since these devices are always mapped through some architecture-specific bus — for example. in an x86 architecture. by adding their offsets to the virtual address returned by i o r e m a p ( ) . u n s i g n e di n ti o w r i t e 8 ( u 8v a l u e . c : 1 # i n c l u d e< l i n u x / m o d u l e . the AMBA bus in ARM architectures. The interesting part is that in Linux. and those referring to device maps as bus addresses. Then she added the user access to the video RAM through read and write calls of the “vram” driver. say 2GB. the PCI bus in the x86 architecture.LINUX For You Find us on Facebook memories of devices) mapped in an interleaved fashion. hardware manuals) of the corresponding architecture processors/controllers. Run c a t/ p r o c / m e m i n f oto get the approximate RAM size on your system. device maps could start from 2GB (0 x 8 0 0 0 0 0 0 0 ). All the architecture-dependent values of these physical and bus addresses are either dynamically configurable. Refer to Figure 2 for a snapshot. For example. F acebook social plugin Popular Comments Tag cloud May 6.

i f( c o p y _ t o _ u s e r ( b u f+i .b u f+i .i<l e n .1 .s i z e _ tl e n . . } s t a t i cs s i z e _ tm y _ r e a d ( s t r u c tf i l e* f . } f o r( i=0 . s t a t i cs t r u c tf i l e _ o p e r a t i o n sv r a m _ f o p s= { ." v r a m " )<0 ) { r e t u r n1 .( u 8* ) v r a m+* o f f+i ) . Device Drivers. r e l e a s e=m y _ c l o s e . s t a t i ci n t_ _ i n i tv r a m _ i n i t ( v o i d )/ *C o n s t r u c t o r* / { i f( ( v r a m=i o r e m a p ( V R A M _ B A S E . .1 ) . } i f( * o f f+l e n>V R A M _ S I Z E ) { l e n=V R A M _ S I Z E-* o f f . h > # i n c l u d e< l i n u x / d e v i c e .s i z e _ tl e n . } f o r( i=0 . } s t a t i ci n tm y _ c l o s e ( s t r u c ti n o d e* i . i f( * o f f> =V R A M _ S I Z E ) { r e t u r n0 . i f( * o f f> =V R A M _ S I Z E ) { r e t u r n0 . h > # i n c l u d e< l i n u x / c d e v . w r i t e=m y _ w r i t e } . } } * o f f+ =l e n .1 ) ) { r e t u r nE F A U L T . } i o w r i t e 8 ( b y t e . r e a d=m y _ r e a d . h > # i n c l u d e< a s m / i o . r e t u r nl e n . h > # i n c l u d e< l i n u x / t y p e s .V R A M _ S I Z E ) )= =N U L L ) { p r i n t k ( K E R N _ E R R" M a p p i n gv i d e oR A Mf a i l e d \ n " ) . s t a t i cd e v _ tf i r s t . u 8b y t e .i + + ) { i f( c o p y _ f r o m _ u s e r ( & b y t e . .N U L L . u 8b y t e . h > # i n c l u d e< l i n u x / k e r n e l . s t a t i cs t r u c tc d e vc _ d e v . } i f( ( c l=c l a s s _ c r e a t e ( T H I S _ M O D U L E .N U L L . } * o f f+ =l e n .1 ) . r e t u r n1 .s t r u c tf i l e* f ) { r e t u r n0 .l o f f _ t* o f f ) { i n ti . } i f( * o f f+l e n>V R A M _ S I Z E ) { l e n=V R A M _ S I Z E-* o f f .LINUX For You s t a t i ci n tm y _ o p e n ( s t r u c ti n o d e* i .8/5/13 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 3 3 3 4 3 5 3 6 3 7 3 8 3 9 4 0 4 1 4 2 4 3 4 4 4 5 4 6 4 7 4 8 4 9 5 0 5 1 5 2 5 3 5 4 5 5 5 6 5 7 5 8 5 9 6 0 6 1 6 2 6 3 6 4 6 5 6 6 6 7 6 8 6 9 7 0 7 1 7 2 7 3 7 4 7 5 7 6 7 7 7 8 7 9 8 0 8 1 8 2 8 3 8 4 8 5 8 6 8 7 8 8 8 9 9 0 9 1 9 2 9 3 9 4 9 5 9 6 9 7 9 8 9 9 1 0 0 1 0 1 1 0 2 1 0 3 1 0 4 1 0 5 1 0 6 1 0 7 1 0 8 1 0 9 1 1 0 # i n c l u d e< l i n u x / v e r s i o n .& b y t e . r e t u r n1 .l o f f _ t* o f f ) { i n ti . s t a t i cs t r u c tc l a s s* c l .c o n s tc h a r_ _ u s e r* b u f . o w n e r=T H I S _ M O D U L E .0 . o p e n=m y _ o p e n .i + + ) { b y t e=i o r e a d 8 ( ( u 8* ) v r a m+* o f f+i ) .linuxforu. . u n r e g i s t e r _ c h r d e v _ r e g i o n ( f i r s t ." c h a r d r v " ) )= =N U L L ) { u n r e g i s t e r _ c h r d e v _ r e g i o n ( f i r s t . h > # d e f i n eV R A M _ B A S E0 x 0 0 0 A 0 0 0 0 # d e f i n eV R A M _ S I Z E0 x 0 0 0 2 0 0 0 0 s t a t i cv o i d_ _ i o m e m* v r a m .c h a r_ _ u s e r* b u f . r e t u r n1 . } r e t u r nl e n .s t r u c tf i l e* f ) { r e t u r n0 .1 ) ) { r e t u r nE F A U L T . } www. h > # i n c l u d e< l i n u x / k d e v _ t . h > # i n c l u d e< l i n u x / f s . } i f( a l l o c _ c h r d e v _ r e g i o n ( & f i r s t . h > # i n c l u d e< l i n u x / u a c c e s s . } s t a t i cs s i z e _ tm y _ w r i t e ( s t r u c tf i l e* f . } i f( d e v i c e _ c r e a t e ( c l .com/2011/06/generic-hardware-access-in-linux/ 3/8 .i<l e n ." v r a m " )= =N U L L ) { c l a s s _ d e s t r o y ( c l ) . Part 7: Generic Hardware Access in Linux .f i r s t .

Build the “vram” driver (v i d e o _ r a m . device drivers.1 )= =1 ) { d e v i c e _ d e s t r o y ( c l . o dtx 1shows it as hexadecimal.Twitter .. M O D U L E _ A U T H O R ( " A n i lK u m a rP u g a l i a< e m a i l _ a t _ s a r i k a p u g s _ d o t _ c o m > " ) . Shweta decided to walk around and possibly help somebody else with their experiments. d e v i c e _ d e s t r o y ( c l . but that would give all the binary content. 3. he had worked at Intel and Nvidia. c l a s s _ d e s t r o y ( c l ) . run m a no d . Load the driver using i n s m o dv i d e o _ r a m .f i r s t ) . Read the / d e v / v r a mcontents using o dtx 1v/ d e v / v r a m|l e s s . M O D U L E _ L I C E N S E ( " G P L " ) . using e c h on" 0 1 2 3 4 5 6 7 8 9 ">/ d e v / v r a m . } s t a t i cv o i d_ _ e x i tv r a m _ e x i t ( v o i d )/ *D e s t r u c t o r* / { c d e v _ d e l ( & c _ d e v ) . say. With half an hour still left for the end of the practical class. M O D U L E _ D E S C R I P T I O N ( " V i d e oR A MD r i v e r " ) . Part 9: I/O Control in Linux Tags: architectures. drivers. For more details. Part 7: Generic Hardware Access in Linux . LFY June 2011. registers. u n r e g i s t e r _ c h r d e v _ r e g i o n ( f i r s t .f i r s t ) . i f( c d e v _ a d d ( & c _ d e v . Write into / d e v / v r a m . Unload the driver using r m m o dv i d e o _ r a m . Linux and knowledge-sharing are two of his many passions. (The usual c a t / d e v / v r a mcan also be used. Summing up Shweta then repeated the usual steps: 1.1 ) . k o . u n r e g i s t e r _ c h r d e v _ r e g i o n ( f i r s t . m o d u l e _ e x i t ( v r a m _ e x i t ) . Part 8: Accessing x86-Specific I/O-Mapped Hardware Device Drivers.Facebook .1 ) . 2. Video RAM Drivers. linux device drivers..& v r a m _ f o p s ) . } m o d u l e _ i n i t ( v r a m _ i n i t ) . k ofile) by running m a k ewith a changed M a k e f i l e . hardware interfacing. Part 6: Decoding Character Device File Operations Device Drivers. c l a s s _ d e s t r o y ( c l ) . video RAM.com/2011/06/generic-hardware-access-in-linux/ 4/8 . Related Posts: Device Drivers. Part 5: Character Device Files — Creation & Operations Device Drivers. DOS.f i r s t . ARM architecture. Prior to this. Connect with him: Website . RAM. Linux device drivers. Linux Device Drivers Series. 4. generic architecture. He has been exploring Linux since 1994.) 5. Part 4: Linux Character Drivers Device Drivers.linuxforu. x86 architecture Article written by: Anil Kumar Pugalia The author is a freelance trainer in Linux internals. Newest Community s ant os h y adav • Share 3 months ago hello everyone! www.LINUX For You c d e v _ i n i t ( & c _ d e v . r e t u r n1 . embedded Linux and related topics. VRAM.8/5/13 1 1 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 2 0 1 2 1 1 2 2 1 2 3 1 2 4 1 2 5 1 2 6 1 2 7 1 2 8 1 2 9 1 3 0 1 3 1 1 3 2 1 3 3 1 3 4 1 3 5 1 3 6 Device Drivers. i o u n m a p ( v r a m ) . } r e t u r n0 . A gold medallist from the Indian Institute of Science. Part 2: Data Structures and Operators Code Profiling in Linux Using Gprof 23 comments Leave a message.Google+ Previous Post Next Post Sed Explained.

"0123456789" to driver and I read from driver using the command. Output goes like this. 0000000: 0100 0000 3435 3637 3839 0000 0000 0000 . ssize_t my_read(struct file *f. so to overcome it i will have to map the physical address to logical and for that i made use of ioremap().com/2011/06/generic-hardware-access-in-linux/ 5/8 . what is __iomem ? I understood that vram is void pointer. but while i am using it the kernel is unable to locate the 'asm/io. So whatever we write to this device driver is written to memory of the device [bus address]. relevant for I/O mapped memory. have you configured the kernel? Which architecture is it for? Reply s rik ant h • Share › 3 months ago static void __iomem *vram. How could I interpret the pattern "0123456789" from above read input ? Thanks.456789.linuxforu. Reply Share › santosh yadav • 2 months ago anil_pugalia I assume that you have set up the kernel headers path appropriately. and we calculate as follows (A0001 .A0000) + 1 = 2. but __iomem signifies what? Reply Share › srikanth • 2 months ago anil_pugalia When tagged with __iomem. Part 7: Generic Hardware Access in Linux . and right is the characters. it enables that pointer for compiler checks &/or optimizations. xxd.. If yes. I could not understand the data when I read from video driver. I wrote . so how would the visual display unit interprets it and shows in the screen ? One more thing is.0x000A0000 = 1ffff Reply Share › linux_bot • 6 months ago anil_pugalia You need to add 1 to the result of subtraction.. About the output.. centre is the ASCII values in hex. I had a doubt regarding the read function .. size_t len. when subtracted from 0x000BFFFF .. then they are 2 addresses and hence the size is 2.8/5/13 Device Drivers. Reply plr • Share › 11 months ago Hi Anil . If not. char __user *buf. Why? Here's the logic: If an address starts from A0000 and ends at A0001... you may not see any characters on the screen.LINUX For You i am trying to do gpio access and encounter segmentation fault. 2 S A THE E S A RA N Reply • Share › 7 months ago Hi Anil.. Reply linux _bot • Share › 7 months ago how is VRAM_SIZE = 0x00020000 is calculated. www. Satheesaran Reply Share › SATHEESARAN • 7 months ago anil_pugalia As this video RAM is no longer used. do it.h' header file so what should i do to include the header so that it may work. loff_t *off) here len tells the number of bytes to be read .

com/2011/06/generic-hardware-access-in-linux/ 6/8 .. Reply mrr • Share › a year ago Worth to mention that if you couldn't find "Video RAM" in /proc/iomem. } gives a different meaning . non-prefetchable) [size=4K] Expansion ROM at e2010000 [disabled] [size=64K] Kernel modules: cirrusfb and with device number '00:02. and what is loff_t *off field meant for ? I thot it is the offset from which the byte has to be read ..0 e2000000-e2000fff : 0000:00:02.linuxforu.. Inc.. Device 1100 Flags: fast devsel Memory at e0000000 (32-bit..0' you can find it now in /proc/iomem: bash# grep 00:02.(off_from_base_address >= VRAM_SIZE) will go beyond the VRAM mapping. Reply s andeep • Share › 11 months ago excellent work sir please try to upload the same with linux internals also Reply Share › sandeep • 11 months ago A nil P ugalia Reply B uk • Thanks. I understood it myself. Please clarify regarding this. İ am not sure if i did any mistake because there isn' t much difference between writing echo 0123456789 and echo 55 Reply Share › Buk • a year ago A nil P ugalia If there is no change .that's very much possible.LINUX For You here len tells the number of bytes to be read . But if (*off >= VRAM_SIZE) { return 0... try to run `lspci v` and find video device info: bash# lspci -v 00:02.8/5/13 Device Drivers. Reply plr Share › plr • 11 months ago hi sir.0 /proc/iomem e0000000-e1ffffff : 0000:00:02.0 VGA compatible controller: Cirrus Logic GD 5446 Subsystem: Qumranet.0 Memory at 0xe0000000 is good enough for the article example. Reply Share › plr • 8 months ago anil_pugalia Yes.0 e2010000-e201ffff : 0000:00:02.. (off > base address) means its going beyond the mapping for vram . Here off is the offset from the base address .. I kno its a very small thing but Im stuck right at this point. Part 7: Generic Hardware Access in Linux . prefetchable) [size=32M] Memory at e2000000 (32-bit. Reply Share › mrr • a year ago anil_pugalia www. you understood correct ... And what do you mean by upload same with linux internals? Share › a year ago Great tutorials but it would be better if you could give the output screen after od -t x1 -v /dev/vram | less command. if the underlying system doesn't have that Video RAM physically. present. here it refers to number of bytes to be read if Im not wrong.

V . in more readable ways. But we do not want to play & goof up with the ram of the currently being used video card. • Share › a year ago I believe the meaning of the output of "od -t x1 -v /dev/vram | less" should be explained so as to how it relates with the "0123456789" that we wrote into our driver. I am reading your article from the beginning . Virtual addresses are only conceptual. A. Regards.8/5/13 anil_pugalia Device Drivers. I have some queries please clarify. 1 Reply Share › www. So the part of the processes that are needed for execution are in the RAM while those parts that are not currently needed will be in their corresponding virtual addresses ready to be mapped onto the RAM.. Where as 'virtual address' refers to the address space the processes have within the virtual memory. even I m not understanding what the o/p should be. on PCI Bus for x86 architecture. • a year ago anil_pugalia Bus Addresses are the addresses coming on the bus .com/2011/06/generic-hardware-access-in-linux/ 7/8 .LINUX For You mrr • a year ago What you pointed out is correct. http://tldp. Just do the following: xxd /dev/vram | less What exactly we are doing with all these.org/LDP/khg/HyperN. • a year ago Lok es h W alas eP at il Yes. Hi Yuva. Please discuss and let us reach at the correct answer.g.linuxforu. V. which is at the location as mentioned in the article. I'm a bit confused regarding the 'bus address' terminology. Your article is really good . Pls someone explain it !! :) Reply Share › Lokesh WalasePatil • a year ago anil_pugalia Easier way for understanding the same would be to try xxd. which could be bus addresses or physical RAM addresses. Reply Share › Haris Ibrahim K. I am happy with your sharing. They are the real hardware addresses. looking for the unused video ram from the "DOS days". V. They only exist in the page tables used by the MMU for ultimately getting translated into hardware addresses.. My answer is not accurate and can be wrong too. in ASCII. The concept of virtual memory can be viewed as 'enlarging the capacity of RAM'. etc Reply y uva • Share › 2 years ago Hi Anil . There are 'address buses' that carry addresses between different devices. V .e. Part 7: Generic Hardware Access in Linux . Basically a 16-bit system having 16 parallel wires to carry this. like in hex. Reply Share › Haris Ibrahim K. is reading & display the vide ram content. I believe this tech has been improved by multiplexing the addresses and hence using lesser number of wires in parallel. From the following link i came to know that there are three ways for addressing memory . And that's why. I want to understand what is "virtual address" and "bus address" clearly .Yuvaraj Reply Share › yuva • a year ago Haris Ibrahim K . Reply Haris Ibrahim K .

Fedora.8/5/13 Reply Device Drivers. www. India. python. xml. Microsoft. unless otherw ise noted. http. PHP. . html. w eb applications . LINUX For You is pow ered by WordPress.0 Unported License. Oracle. C. RAM.com/2011/06/generic-hardware-access-in-linux/ 8/8 . FOSS. ubuntu. JavaScript. Window s . Red Hat. Java.LINUX For You Share › C o m m e n t fe e d Su b s cri b e vi a e m a i l Reviews How-Tos Coding Interviews Features Overview Blogs Search Popular tags Linux .linuxforu. open source. unix . Apache. Part 7: Generic Hardware Access in Linux . Security . operating systems For You & Me Developers Sysadmins Open Gurus CXOs Columns All published articles are released under Creative Commons Attribution-NonCommercial 3. MySQL. GNOME. Google. Android. LFY June 2011. w hich gladly sits on top of a CentOS-based LEMP stack. LFY April 2012.