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

8/14/13

Write For Us Submit Tips

Device Drivers, Part 15: Disk on RAM -- Playing with Block Drivers - LINUX For You
Subscribe to Print Edition Search

HOME

REVIEWS

HOW-TOS

CODING

INTERVIEWS

FEATURES

OVERVIEW

BLOGS

SERIES

IT ADMIN

Device Drivers, Part 15: Disk on RAM Playing with Block Drivers
By Anil Kumar Pugalia on February 28, 2012 in Coding, Developers 1 Comment

Search for:

Search

Get Connected RSS Feed Twitter

This article, which is part of the series on Linux device drivers, experiments with a dummy hard disk on RAM to demonstrate how block drivers work.
After a delicious lunch, theory makes the audience sleepy. So, lets start with the code itself.

Disk On RAM source code


Lets us create a directory called DiskOnRAM which holds the following six files three C source files, two C headers, and one Makefile.

partition.h
1 2 3 4 5 6 7 # i f n d e fP A R T I T I O N _ H # d e f i n eP A R T I T I O N _ H # i n c l u d e< l i n u x / t y p e s . h > e x t e r nv o i dc o p y _ m b r _ n _ b r ( u 8* d i s k ) ; # e n d i f

LINUX For You on

Follow

partition.c
1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 # i n c l u d e< l i n u x / s t r i n g . h > # i n c l u d e" p a r t i t i o n . h " # d e f i n eA R R A Y _ S I Z E ( a )( s i z e o f ( a )/s i z e o f ( * a ) ) # d e f i n eS E C T O R _ S I Z E5 1 2 # d e f i n eM B R _ S I Z ES E C T O R _ S I Z E # d e f i n eM B R _ D I S K _ S I G N A T U R E _ O F F S E T4 4 0 # d e f i n eM B R _ D I S K _ S I G N A T U R E _ S I Z E4 # d e f i n eP A R T I T I O N _ T A B L E _ O F F S E T4 4 6 # d e f i n eP A R T I T I O N _ E N T R Y _ S I Z E1 6/ /s i z e o f ( P a r t E n t r y ) # d e f i n eP A R T I T I O N _ T A B L E _ S I Z E6 4/ /s i z e o f ( P a r t T a b l e ) # d e f i n eM B R _ S I G N A T U R E _ O F F S E T5 1 0 # d e f i n eM B R _ S I G N A T U R E _ S I Z E2 # d e f i n eM B R _ S I G N A T U R E0 x A A 5 5

+2,494

www.linuxforu.com/2012/02/device-drivers-disk-on-ram-block-drivers/

1/10

8/14/13
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 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

Device Drivers, Part 15: Disk on RAM -- Playing with Block Drivers - LINUX For You
# d e f i n eB R _ S I Z ES E C T O R _ S I Z E # d e f i n eB R _ S I G N A T U R E _ O F F S E T5 1 0 # d e f i n eB R _ S I G N A T U R E _ S I Z E2 # d e f i n eB R _ S I G N A T U R E0 x A A 5 5 t y p e d e fs t r u c t { u n s i g n e dc h a rb o o t _ t y p e ;/ /0 x 0 0-I n a c t i v e ;0 x 8 0-A c t i v e( B o o t a b l e ) u n s i g n e dc h a rs t a r t _ h e a d ; u n s i g n e dc h a rs t a r t _ s e c : 6 ; u n s i g n e dc h a rs t a r t _ c y l _ h i : 2 ; u n s i g n e dc h a rs t a r t _ c y l ; u n s i g n e dc h a rp a r t _ t y p e ; u n s i g n e dc h a re n d _ h e a d ; u n s i g n e dc h a re n d _ s e c : 6 ; u n s i g n e dc h a re n d _ c y l _ h i : 2 ; u n s i g n e dc h a re n d _ c y l ; u n s i g n e dl o n ga b s _ s t a r t _ s e c ; u n s i g n e dl o n gs e c _ i n _ p a r t ; }P a r t E n t r y ; t y p e d e fP a r t E n t r yP a r t T a b l e [ 4 ] ; s t a t i cP a r t T a b l ed e f _ p a r t _ t a b l e= { { b o o t _ t y p e :0 x 0 0 , s t a r t _ h e a d :0 x 0 0 , s t a r t _ s e c :0 x 2 , s t a r t _ c y l :0 x 0 0 , p a r t _ t y p e :0 x 8 3 , e n d _ h e a d :0 x 0 0 , e n d _ s e c :0 x 2 0 , e n d _ c y l :0 x 0 9 , a b s _ s t a r t _ s e c :0 x 0 0 0 0 0 0 0 1 , s e c _ i n _ p a r t :0 x 0 0 0 0 0 1 3 F } , { b o o t _ t y p e :0 x 0 0 , s t a r t _ h e a d :0 x 0 0 , s t a r t _ s e c :0 x 1 , s t a r t _ c y l :0 x 0 A ,/ /e x t e n d e dp a r t i t i o ns t a r tc y l i n d e r( B Rl o c a t i o n ) p a r t _ t y p e :0 x 0 5 , e n d _ h e a d :0 x 0 0 , e n d _ s e c :0 x 2 0 , e n d _ c y l :0 x 1 3 , a b s _ s t a r t _ s e c :0 x 0 0 0 0 0 1 4 0 , s e c _ i n _ p a r t :0 x 0 0 0 0 0 1 4 0 } , { b o o t _ t y p e :0 x 0 0 , s t a r t _ h e a d :0 x 0 0 , s t a r t _ s e c :0 x 1 , s t a r t _ c y l :0 x 1 4 , p a r t _ t y p e :0 x 8 3 , e n d _ h e a d :0 x 0 0 , e n d _ s e c :0 x 2 0 , e n d _ c y l :0 x 1 F , a b s _ s t a r t _ s e c :0 x 0 0 0 0 0 2 8 0 , s e c _ i n _ p a r t :0 x 0 0 0 0 0 1 8 0 } , { } } ; s t a t i cu n s i g n e di n td e f _ l o g _ p a r t _ b r _ c y l [ ]={ 0 x 0 A ,0 x 0 E ,0 x 1 2 } ; s t a t i cc o n s tP a r t T a b l ed e f _ l o g _ p a r t _ t a b l e [ ]= { { { b o o t _ t y p e :0 x 0 0 , s t a r t _ h e a d :0 x 0 0 , s t a r t _ s e c :0 x 2 , s t a r t _ c y l :0 x 0 A , p a r t _ t y p e :0 x 8 3 , e n d _ h e a d :0 x 0 0 , e n d _ s e c :0 x 2 0 , e n d _ c y l :0 x 0 D , a b s _ s t a r t _ s e c :0 x 0 0 0 0 0 0 0 1 , s e c _ i n _ p a r t :0 x 0 0 0 0 0 0 7 F } , { b o o t _ t y p e :0 x 0 0 , s t a r t _ h e a d :0 x 0 0 , s t a r t _ s e c :0 x 1 , s t a r t _ c y l :0 x 0 E , p a r t _ t y p e :0 x 0 5 , e n d _ h e a d :0 x 0 0 , e n d _ s e c :0 x 2 0 , e n d _ c y l :0 x 1 1 , a b s _ s t a r t _ s e c :0 x 0 0 0 0 0 0 8 0 , s e c _ i n _ p a r t :0 x 0 0 0 0 0 0 8 0 } , } , { { b o o t _ t y p e :0 x 0 0 , s t a r t _ h e a d :0 x 0 0 , s t a r t _ s e c :0 x 2 , s t a r t _ c y l :0 x 0 E , p a r t _ t y p e :0 x 8 3 , e n d _ h e a d :0 x 0 0 , e n d _ s e c :0 x 2 0 , e n d _ c y l :0 x 1 1 , a b s _ s t a r t _ s e c :0 x 0 0 0 0 0 0 0 1 , s e c _ i n _ p a r t :0 x 0 0 0 0 0 0 7 F } , { b o o t _ t y p e :0 x 0 0 , s t a r t _ h e a d :0 x 0 0 , Popular Comments Tag cloud
Find us on Facebook

Open Source For You


Like 252,616 people like Open Source For You.

F acebook social plugin

May 6, 2013 6 Comments Priyanka Sarkar

PHP Development: A Smart Career Move


August 13, 2013 4 Comments Diksha P Gupta

India has immense under-utilised talent in the cloud security space


June 20, 2013 3 Comments Priyanka Sarkar

What it Takes to be an Open Source Expert


June 20, 2013 2 Comments sophie-samuel

New and amazing features of Linux


May 6, 2013 1 Comments Deepti Sharma

A Simple guide to building your own Linux Kernel

www.linuxforu.com/2012/02/device-drivers-disk-on-ram-block-drivers/

2/10

8/14/13
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 1 3 7 1 3 8 1 3 9 1 4 0 1 4 1 1 4 2 1 4 3 1 4 4 1 4 5 1 4 6 1 4 7 1 4 8 1 4 9 1 5 0 1 5 1 1 5 2 1 5 3 1 5 4 1 5 5 1 5 6 1 5 7 1 5 8 1 5 9 1 6 0 1 6 1 1 6 2 1 6 3 1 6 4 1 6 5 1 6 6 1 6 7 1 6 8 1 6 9 1 7 0 1 7 1 1 7 2 1 7 3 1 7 4 1 7 5 1 7 6

Device Drivers, Part 15: Disk on RAM -- Playing with Block Drivers - LINUX For You
s t a r t _ s e c :0 x 1 , s t a r t _ c y l :0 x 1 2 , p a r t _ t y p e :0 x 0 5 , e n d _ h e a d :0 x 0 0 , e n d _ s e c :0 x 2 0 , e n d _ c y l :0 x 1 3 , a b s _ s t a r t _ s e c :0 x 0 0 0 0 0 1 0 0 , s e c _ i n _ p a r t :0 x 0 0 0 0 0 0 4 0

} , {

} , {

} ;

} ,

b o o t _ t y p e :0 x 0 0 , s t a r t _ h e a d :0 x 0 0 , s t a r t _ s e c :0 x 2 , s t a r t _ c y l :0 x 1 2 , p a r t _ t y p e :0 x 8 3 , e n d _ h e a d :0 x 0 0 , e n d _ s e c :0 x 2 0 , e n d _ c y l :0 x 1 3 , a b s _ s t a r t _ s e c :0 x 0 0 0 0 0 0 0 1 , s e c _ i n _ p a r t :0 x 0 0 0 0 0 0 3 F

s t a t i cv o i dc o p y _ m b r ( u 8* d i s k ) { m e m s e t ( d i s k ,0 x 0 ,M B R _ S I Z E ) ; * ( u n s i g n e dl o n g* ) ( d i s k+M B R _ D I S K _ S I G N A T U R E _ O F F S E T )=0 x 3 6 E 5 7 5 6 D ; m e m c p y ( d i s k+P A R T I T I O N _ T A B L E _ O F F S E T ,& d e f _ p a r t _ t a b l e ,P A R T I T I O N _ T A B L E _ S I Z E ) ; * ( u n s i g n e ds h o r t* ) ( d i s k+M B R _ S I G N A T U R E _ O F F S E T )=M B R _ S I G N A T U R E ; } s t a t i cv o i dc o p y _ b r ( u 8* d i s k ,i n ts t a r t _ c y l i n d e r ,c o n s tP a r t T a b l e* p a r t _ t a b l e ) { d i s k+ =( s t a r t _ c y l i n d e r*3 2/ *s e c t o r s/c y l* /*S E C T O R _ S I Z E ) ; m e m s e t ( d i s k ,0 x 0 ,B R _ S I Z E ) ; m e m c p y ( d i s k+P A R T I T I O N _ T A B L E _ O F F S E T ,p a r t _ t a b l e , P A R T I T I O N _ T A B L E _ S I Z E ) ; * ( u n s i g n e ds h o r t* ) ( d i s k+B R _ S I G N A T U R E _ O F F S E T )=B R _ S I G N A T U R E ; } v o i dc o p y _ m b r _ n _ b r ( u 8* d i s k ) { i n ti ; c o p y _ m b r ( d i s k ) ; f o r( i=0 ;i<A R R A Y _ S I Z E ( d e f _ l o g _ p a r t _ t a b l e ) ;i + + ) { c o p y _ b r ( d i s k ,d e f _ l o g _ p a r t _ b r _ c y l [ i ] ,& d e f _ l o g _ p a r t _ t a b l e [ i ] ) ; }

ram_device.h
1 2 3 4 5 6 7 8 9 1 0 # i f n d e fR A M D E V I C E _ H # d e f i n eR A M D E V I C E _ H # d e f i n eR B _ S E C T O R _ S I Z E5 1 2 e x t e r ni n tr a m d e v i c e _ i n i t ( v o i d ) ; e x t e r nv o i dr a m d e v i c e _ c l e a n u p ( v o i d ) ; e x t e r nv o i dr a m d e v i c e _ w r i t e ( s e c t o r _ ts e c t o r _ o f f ,u 8* b u f f e r ,u n s i g n e di n ts e c t o r s ) ; e x t e r nv o i dr a m d e v i c e _ r e a d ( s e c t o r _ ts e c t o r _ o f f ,u 8* b u f f e r ,u n s i g n e di n ts e c t o r s ) ; # e n d i f

ram_device.c
1 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 # i n c l u d e< l i n u x / t y p e s . h > # i n c l u d e< l i n u x / v m a l l o c . h > # i n c l u d e< l i n u x / s t r i n g . h > # i n c l u d e" r a m _ d e v i c e . h " # i n c l u d e" p a r t i t i o n . h " # d e f i n eR B _ D E V I C E _ S I Z E1 0 2 4/ *s e c t o r s* / / *S o ,t o t a ld e v i c es i z e=1 0 2 4*5 1 2b y t e s=5 1 2K i B* / / *A r r a yw h e r et h ed i s ks t o r e si t sd a t a* / s t a t i cu 8* d e v _ d a t a ; i n tr a m d e v i c e _ i n i t ( v o i d ) { d e v _ d a t a=v m a l l o c ( R B _ D E V I C E _ S I Z E*R B _ S E C T O R _ S I Z E ) ; i f( d e v _ d a t a= =N U L L ) r e t u r nE N O M E M ; / *S e t u pi t sp a r t i t i o nt a b l e* / c o p y _ m b r _ n _ b r ( d e v _ d a t a ) ; r e t u r nR B _ D E V I C E _ S I Z E ; } v o i dr a m d e v i c e _ c l e a n u p ( v o i d ) { v f r e e ( d e v _ d a t a ) ; } v o i dr a m d e v i c e _ w r i t e ( s e c t o r _ ts e c t o r _ o f f ,u 8* b u f f e r ,u n s i g n e di n ts e c t o r s ) { m e m c p y ( d e v _ d a t a+s e c t o r _ o f f*R B _ S E C T O R _ S I Z E ,b u f f e r , s e c t o r s*R B _ S E C T O R _ S I Z E ) ; } v o i dr a m d e v i c e _ r e a d ( s e c t o r _ ts e c t o r _ o f f ,u 8* b u f f e r ,u n s i g n e di n ts e c t o r s ) { m e m c p y ( b u f f e r ,d e v _ d a t a+s e c t o r _ o f f*R B _ S E C T O R _ S I Z E ,

www.linuxforu.com/2012/02/device-drivers-disk-on-ram-block-drivers/

3/10

8/14/13
3 7 3 8 }

Device Drivers, Part 15: Disk on RAM -- Playing with Block Drivers - LINUX For You
s e c t o r s*R B _ S E C T O R _ S I Z E ) ;

ram_block.c
1 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 / *D i s ko nR A MD r i v e r* / # i n c l u d e< l i n u x / m o d u l e . h > # i n c l u d e< l i n u x / k e r n e l . h > # i n c l u d e< l i n u x / f s . h > # i n c l u d e< l i n u x / t y p e s . h > # i n c l u d e< l i n u x / g e n h d . h > # i n c l u d e< l i n u x / b l k d e v . h > # i n c l u d e< l i n u x / e r r n o . h > # i n c l u d e" r a m _ d e v i c e . h " # d e f i n eR B _ F I R S T _ M I N O R0 # d e f i n eR B _ M I N O R _ C N T1 6 s t a t i cu _ i n tr b _ m a j o r=0 ; / * *T h ei n t e r n a ls t r u c t u r er e p r e s e n t a t i o no fo u rD e v i c e * / s t a t i cs t r u c tr b _ d e v i c e { / *S i z ei st h es i z eo ft h ed e v i c e( i ns e c t o r s )* / u n s i g n e di n ts i z e ; / *F o re x c l u s i v ea c c e s st oo u rr e q u e s tq u e u e* / s p i n l o c k _ tl o c k ; / *O u rr e q u e s tq u e u e* / s t r u c tr e q u e s t _ q u e u e* r b _ q u e u e ; / *T h i si sk e r n e l ' sr e p r e s e n t a t i o no fa ni n d i v i d u a ld i s kd e v i c e* / s t r u c tg e n d i s k* r b _ d i s k ; }r b _ d e v ; s t a t i ci n tr b _ o p e n ( s t r u c tb l o c k _ d e v i c e* b d e v ,f m o d e _ tm o d e ) { u n s i g n e du n i t=i m i n o r ( b d e v > b d _ i n o d e ) ; p r i n t k ( K E R N _ I N F O" r b :D e v i c ei so p e n e d \ n " ) ; p r i n t k ( K E R N _ I N F O" r b :I n o d en u m b e ri s% d \ n " ,u n i t ) ; i f( u n i t>R B _ M I N O R _ C N T ) r e t u r nE N O D E V ; r e t u r n0 ;

s t a t i ci n tr b _ c l o s e ( s t r u c tg e n d i s k* d i s k ,f m o d e _ tm o d e ) { p r i n t k ( K E R N _ I N F O" r b :D e v i c ei sc l o s e d \ n " ) ; r e t u r n0 ; } / * *A c t u a lD a t at r a n s f e r * / s t a t i ci n tr b _ t r a n s f e r ( s t r u c tr e q u e s t* r e q ) { / / s t r u c tr b _ d e v i c e* d e v=( s t r u c tr b _ d e v i c e* ) ( r e q > r q _ d i s k > p r i v a t e _ d a t a ) ; i n td i r=r q _ d a t a _ d i r ( r e q ) ; s e c t o r _ ts t a r t _ s e c t o r=b l k _ r q _ p o s ( r e q ) ; u n s i g n e di n ts e c t o r _ c n t=b l k _ r q _ s e c t o r s ( r e q ) ; s t r u c tb i o _ v e c* b v ; s t r u c tr e q _ i t e r a t o ri t e r ; s e c t o r _ ts e c t o r _ o f f s e t ; u n s i g n e di n ts e c t o r s ; u 8* b u f f e r ; i n tr e t=0 ; / / p r i n t k ( K E R N _ D E B U G" r b :D i r : % d ;S e c : % l l d ;C n t : % d \ n " ,d i r ,s t a r t _ s e c t o r ,s e c t o r _ c n t ) ; s e c t o r _ o f f s e t=0 ; r q _ f o r _ e a c h _ s e g m e n t ( b v ,r e q ,i t e r ) { b u f f e r=p a g e _ a d d r e s s ( b v > b v _ p a g e )+b v > b v _ o f f s e t ; i f( b v > b v _ l e n%R B _ S E C T O R _ S I Z E! =0 ) { p r i n t k ( K E R N _ E R R" r b :S h o u l dn e v e rh a p p e n :" " b i os i z e( % d )i sn o tam u l t i p l eo fR B _ S E C T O R _ S I Z E( % d ) . \ n " " T h i sm a yl e a dt od a t at r u n c a t i o n . \ n " , b v > b v _ l e n ,R B _ S E C T O R _ S I Z E ) ; r e t=E I O ; } s e c t o r s=b v > b v _ l e n/R B _ S E C T O R _ S I Z E ; p r i n t k ( K E R N _ D E B U G" r b :S e c t o rO f f s e t :% l l d ;B u f f e r :% p ;L e n g t h :% ds e c t o r s \ n " s e c t o r _ o f f s e t ,b u f f e r ,s e c t o r s ) ; i f( d i r= =W R I T E )/ *W r i t et ot h ed e v i c e* / { r a m d e v i c e _ w r i t e ( s t a r t _ s e c t o r+s e c t o r _ o f f s e t ,b u f f e r ,s e c t o r s ) ; } e l s e/ *R e a df r o mt h ed e v i c e* / { r a m d e v i c e _ r e a d ( s t a r t _ s e c t o r+s e c t o r _ o f f s e t ,b u f f e r ,s e c t o r s ) ; } s e c t o r _ o f f s e t+ =s e c t o r s ; } i f( s e c t o r _ o f f s e t! =s e c t o r _ c n t ) { p r i n t k ( K E R N _ E R R" r b :b i oi n f od o e s n ' tm a t c hw i t ht h er e q u e s ti n f o " ) ; r e t=E I O ; }

www.linuxforu.com/2012/02/device-drivers-disk-on-ram-block-drivers/

4/10

8/14/13
1 0 3 1 0 4 1 0 5 1 0 6 1 0 7 1 0 8 1 0 9 1 1 0 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 1 3 7 1 3 8 1 3 9 1 4 0 1 4 1 1 4 2 1 4 3 1 4 4 1 4 5 1 4 6 1 4 7 1 4 8 1 4 9 1 5 0 1 5 1 1 5 2 1 5 3 1 5 4 1 5 5 1 5 6 1 5 7 1 5 8 1 5 9 1 6 0 1 6 1 1 6 2 1 6 3 1 6 4 1 6 5 1 6 6 1 6 7 1 6 8 1 6 9 1 7 0 1 7 1 1 7 2 1 7 3 1 7 4 1 7 5 1 7 6 1 7 7 1 7 8 1 7 9 1 8 0 1 8 1 1 8 2 1 8 3 1 8 4 1 8 5 1 8 6 1 8 7 1 8 8 1 8 9 1 9 0 1 9 1 1 9 2 1 9 3 1 9 4 1 9 5 1 9 6 1 9 7 1 9 8 1 9 9 2 0 0 2 0 1 2 0 2 2 0 3 2 0 4 2 0 5 2 0 6 2 0 7 2 0 8 2 0 9 2 1 0 2 1 1 } r e t u r nr e t ;

Device Drivers, Part 15: Disk on RAM -- Playing with Block Drivers - LINUX For You

/ * *R e p r e s e n t sab l o c kI / Or e q u e s tf o ru st oe x e c u t e * / s t a t i cv o i dr b _ r e q u e s t ( s t r u c tr e q u e s t _ q u e u e* q ) { s t r u c tr e q u e s t* r e q ; i n tr e t ; / *G e t st h ec u r r e n tr e q u e s tf r o mt h ed i s p a t c hq u e u e* / w h i l e( ( r e q=b l k _ f e t c h _ r e q u e s t ( q ) )! =N U L L ) { # i f0 / * *T h i sf u n c t i o nt e l l su sw h e t h e rw ea r el o o k i n ga taf i l e s y s t e mr e q u e s t *-o n et h a tm o v e sb l o c ko fd a t a * / i f( ! b l k _ f s _ r e q u e s t ( r e q ) ) { p r i n t k ( K E R N _ N O T I C E" r b :S k i pn o n f sr e q u e s t \ n " ) ; / *W ep a s s0t oi n d i c a t et h a tw es u c c e s s f u l l yc o m p l e t e dt h er e q u e s t* / _ _ b l k _ e n d _ r e q u e s t _ a l l ( r e q ,0 ) ; / / _ _ b l k _ e n d _ r e q u e s t ( r e q ,0 ,b l k _ r q _ b y t e s ( r e q ) ) ; c o n t i n u e ; } # e n d i f r e t=r b _ t r a n s f e r ( r e q ) ; _ _ b l k _ e n d _ r e q u e s t _ a l l ( r e q ,r e t ) ; / / _ _ b l k _ e n d _ r e q u e s t ( r e q ,r e t ,b l k _ r q _ b y t e s ( r e q ) ) ; } } / * *T h e s ea r et h ef i l eo p e r a t i o n st h a tp e r f o r m e do nt h er a mb l o c kd e v i c e * / s t a t i cs t r u c tb l o c k _ d e v i c e _ o p e r a t i o n sr b _ f o p s= { . o w n e r=T H I S _ M O D U L E , . o p e n=r b _ o p e n , . r e l e a s e=r b _ c l o s e , } ; / * *T h i si st h er e g i s t r a t i o na n di n i t i a l i z a t i o ns e c t i o no ft h er a mb l o c kd e v i c e *d r i v e r * / s t a t i ci n t_ _ i n i tr b _ i n i t ( v o i d ) { i n tr e t ; / *S e tu po u rR A MD e v i c e* / i f( ( r e t=r a m d e v i c e _ i n i t ( ) )<0 ) { r e t u r nr e t ; } r b _ d e v . s i z e=r e t ; / *G e tR e g i s t e r e d* / r b _ m a j o r=r e g i s t e r _ b l k d e v ( r b _ m a j o r ," r b " ) ; i f( r b _ m a j o r< =0 ) { p r i n t k ( K E R N _ E R R" r b :U n a b l et og e tM a j o rN u m b e r \ n " ) ; r a m d e v i c e _ c l e a n u p ( ) ; r e t u r nE B U S Y ; } / *G e tar e q u e s tq u e u e( h e r eq u e u ei sc r e a t e d )* / s p i n _ l o c k _ i n i t ( & r b _ d e v . l o c k ) ; r b _ d e v . r b _ q u e u e=b l k _ i n i t _ q u e u e ( r b _ r e q u e s t ,& r b _ d e v . l o c k ) ; i f( r b _ d e v . r b _ q u e u e= =N U L L ) { p r i n t k ( K E R N _ E R R" r b :b l k _ i n i t _ q u e u ef a i l u r e \ n " ) ; u n r e g i s t e r _ b l k d e v ( r b _ m a j o r ," r b " ) ; r a m d e v i c e _ c l e a n u p ( ) ; r e t u r nE N O M E M ; } / * *A d dt h eg e n d i s ks t r u c t u r e *B yu s i n gt h i sm e m o r ya l l o c a t i o ni si n v o l v e d , *t h em i n o rn u m b e rw en e e dt op a s sb c zt h ed e v i c e *w i l ls u p p o r tt h i sm u c hp a r t i t i o n s * / r b _ d e v . r b _ d i s k=a l l o c _ d i s k ( R B _ M I N O R _ C N T ) ; i f( ! r b _ d e v . r b _ d i s k ) { p r i n t k ( K E R N _ E R R" r b :a l l o c _ d i s kf a i l u r e \ n " ) ; b l k _ c l e a n u p _ q u e u e ( r b _ d e v . r b _ q u e u e ) ; u n r e g i s t e r _ b l k d e v ( r b _ m a j o r ," r b " ) ; r a m d e v i c e _ c l e a n u p ( ) ; r e t u r nE N O M E M ; } / *S e t t i n gt h em a j o rn u m b e r* / r b _ d e v . r b _ d i s k > m a j o r=r b _ m a j o r ; / *S e t t i n gt h ef i r s tm i o rn u m b e r* / r b _ d e v . r b _ d i s k > f i r s t _ m i n o r=R B _ F I R S T _ M I N O R ; / *I n i t i a l i z i n gt h ed e v i c eo p e r a t i o n s* / r b _ d e v . r b _ d i s k > f o p s=& r b _ f o p s ; / *D r i v e r s p e c i f i co w ni n t e r n a ld a t a* / r b _ d e v . r b _ d i s k > p r i v a t e _ d a t a=& r b _ d e v ; r b _ d e v . r b _ d i s k > q u e u e=r b _ d e v . r b _ q u e u e ; / * *Y o ud on o tw a n tp a r t i t i o ni n f o r m a t i o nt os h o wu pi n *c a t/ p r o c / p a r t i t i o n ss e tt h i sf l a g s * / / / r b _ d e v . r b _ d i s k > f l a g s=G E N H D _ F L _ S U P P R E S S _ P A R T I T I O N _ I N F O ;

www.linuxforu.com/2012/02/device-drivers-disk-on-ram-block-drivers/

5/10

8/14/13
2 1 2 2 1 3 2 1 4 2 1 5 2 1 6 2 1 7 2 1 8 2 1 9 2 2 0 2 2 1 2 2 2 2 2 3 2 2 4 2 2 5 2 2 6 2 2 7 2 2 8 2 2 9 2 3 0 2 3 1 2 3 2 2 3 3 2 3 4 2 3 5 2 3 6 2 3 7 2 3 8 2 3 9 2 4 0 2 4 1 2 4 2 2 4 3

Device Drivers, Part 15: Disk on RAM -- Playing with Block Drivers - LINUX For You
s p r i n t f ( r b _ d e v . r b _ d i s k > d i s k _ n a m e ," r b " ) ; / *S e t t i n gt h ec a p a c i t yo ft h ed e v i c ei ni t sg e n d i s ks t r u c t u r e* / s e t _ c a p a c i t y ( r b _ d e v . r b _ d i s k ,r b _ d e v . s i z e ) ; / *A d d i n gt h ed i s kt ot h es y s t e m* / a d d _ d i s k ( r b _ d e v . r b _ d i s k ) ; / *N o wt h ed i s ki s" l i v e "* / p r i n t k ( K E R N _ I N F O" r b :R a mB l o c kd r i v e ri n i t i a l i s e d( % ds e c t o r s ;% db y t e s ) \ n " r b _ d e v . s i z e ,r b _ d e v . s i z e*R B _ S E C T O R _ S I Z E ) ; r e t u r n0 ; } / * *T h i si st h eu n r e g i s t r a t i o na n du n i n i t i a l i z a t i o ns e c t i o no ft h er a mb l o c k *d e v i c ed r i v e r * / s t a t i cv o i d_ _ e x i tr b _ c l e a n u p ( v o i d ) { d e l _ g e n d i s k ( r b _ d e v . r b _ d i s k ) ; p u t _ d i s k ( r b _ d e v . r b _ d i s k ) ; b l k _ c l e a n u p _ q u e u e ( r b _ d e v . r b _ q u e u e ) ; u n r e g i s t e r _ b l k d e v ( r b _ m a j o r ," r b " ) ; r a m d e v i c e _ c l e a n u p ( ) ; } m o d u l e _ i n i t ( r b _ i n i t ) ; m o d u l e _ e x i t ( r b _ c l e a n u p ) ; M O D U L E _ L I C E N S E ( " G P L " ) ; 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 @ s a r i k a p u g s . c o m > " ) ; M O D U L E _ D E S C R I P T I O N ( " R a mB l o c kD r i v e r " ) ; M O D U L E _ A L I A S _ B L O C K D E V _ M A J O R ( r b _ m a j o r ) ;

You can also download the code demonstrated from here. As usual, executing m a k ewill build the Disk on RAM driver (d o r . k o ), combining the three C files. Check out the Makefile to see how.

Makefile
1 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 #I fc a l l e dd i r e c t l yf r o mt h ec o m m a n dl i n e ,i n v o k et h ek e r n e lb u i l ds y s t e m . i f e q( $ ( K E R N E L R E L E A S E ) , ) K E R N E L _ S O U R C E: =/ u s r / s r c / l i n u x P W D: =$ ( s h e l lp w d ) d e f a u l t :m o d u l e m o d u l e : $ ( M A K E )C$ ( K E R N E L _ S O U R C E )S U B D I R S = $ ( P W D )m o d u l e s c l e a n : $ ( M A K E )C$ ( K E R N E L _ S O U R C E )S U B D I R S = $ ( P W D )c l e a n #O t h e r w i s eK E R N E L R E L E A S Ei sd e f i n e d ;w e ' v eb e e ni n v o k e df r o mt h e #k e r n e lb u i l ds y s t e ma n dc a nu s ei t sl a n g u a g e . e l s e o b j m: =d o r . o d o r y: =r a m _ b l o c k . or a m _ d e v i c e . op a r t i t i o n . o e n d i f

To clean the built files, run the usual m a k ec l e a n . Once built, the following are the experimental steps (refer to Figures 1 to 3).

Figure 1: Playing with the Disk on RAM driver

Figure 2: xxd showing the initial data on the first partition (/dev/rb1)

Figure 3: Formatting the third partition (/dev/rb3)

Please note that all these need to be executed with root privileges: Load the driver d o r . k ousing i n s m o d . This would create the block device files representing the disk on 512 KiB of RAM, with three primary and three logical partitions. Check out the automatically created block device files (/ d e v / r b * ). / d e v / r bis the entire disk, which is 512 KiB in size. r b 1 ,r b 2and r b 3are the primary partitions, with r b 2being the extended partition and containing three logical partitions r b 5 ,r b 6and r b 7 . Read the entire disk (/ d e v / r b ) using the disk dump utility d d . Zero out the first sector of the disks first partition (/ d e v / r b 1 ), again using d d . Write some text into the disks first partition (/ d e v / r b 1 ) using c a t .

www.linuxforu.com/2012/02/device-drivers-disk-on-ram-block-drivers/

6/10

8/14/13
for x x doutput.

Device Drivers, Part 15: Disk on RAM -- Playing with Block Drivers - LINUX For You

Display the initial contents of the first partition (/ d e v / r b 1 ) using the x x dutility. See Figure 2 Display the partition information for the disk using fdisk. See Figure 3 for f d i s koutput. Quick-format the third primary partition (/ d e v / r b 3 ) as a vfat filesystem (like your pen drive), using m k f s . v f a t(Figure 3). Mount the newly formatted partition using mount, say at / m n t(Figure 3). The disk usage utility df would now show this partition mounted at / m n t(Figure 3). You may go ahead and store files there, but remember that this is a disk on RAM, and so is nonpersistent. Unload the driver using r m m o dd o rafter unmounting the partition using u m o u n t/ m n t . All data on the disk will be lost.

Now lets learn the rules


We have just played around with the disk on RAM (DOR), but without actually knowing the rules, i.e., the internal details of the game. So, lets dig into the nitty-gritty to decode the rules. Each of the three . cfiles represent a specific part of the driver; r a m _ d e v i c e . cand r a m _ d e v i c e . h abstract the underlying RAM operations like v m a l l o c /v f r e e ,m e m c p y , etc., providing disk operation APIs like init/cleanup, read/write, etc.
p a r t i t i o n . cand p a r t i t i o n . hprovide the functionality to emulate the various partition tables

on the DOR. Recall the pre-lunch session (i.e., the previous article) to understand the details of partitioning. The code in this is responsible for the partition information like the number, type, size, etc., that is shown using f d i s k . The r a m _ b l o c k . cfile is the core block driver implementation, exposing the DOR as the block device files (/ d e v / r b * ) to user-space. In other words, four of the five files
r a m _ d e v i c e . *and p a r t i t i o n . *form the horizontal layer of the device driver, and r a m _ b l o c k . cforms the vertical (block) layer of the device driver. So, lets understand that in

detail.

The block driver basics


Conceptually, the block drivers are very similar to character drivers, especially with regards to the following: Usage of device files Major and minor numbers Device file operations Concept of device registration So, if you already know character driver implementation, it would be easy to understand block drivers. However, they are definitely not identical. The key differences are as follows: Abstraction for block-oriented versus byte-oriented devices. Block drivers are designed to be used by I/O schedulers, for optimal performance. Compare that with character drivers that are to be used by VFS. Block drivers are designed to be integrated with the Linux buffer cache mechanism for efficient data access. Character drivers are pass-through drivers, accessing the hardware directly. And these cause the implementation differences. Lets analyse the key code snippets from
r a m _ b l o c k . c , starting at the drivers constructor r b _ i n i t ( ) .

The first step is to register for an 8-bit (block) major number (which implicitly means registering for all 256 8-bit minor numbers associated with it). The function for that is as follows:
i n tr e g i s t e r _ b l k d e v ( u n s i g n e di n tm a j o r ,c o n s tc h a r* n a m e ) ;

Here, m a j o ris the major number to be registered, and name is a registration label displayed under the kernel window / p r o c / d e v i c e s . Interestingly, r e g i s t e r _ b l k d e v ( )tries to allocate and register a freely available major number, when 0 is passed for its first parameter m a j o r ; on success, the allocated major number is returned. The corresponding de-registration function is as follows:
v o i du n r e g i s t e r _ b l k d e v ( u n s i g n e di n tm a j o r ,c o n s tc h a r* n a m e ) ;

Both these are prototyped in < l i n u x / f s . h > . The second step is to provide the device file operations, through the struct

www.linuxforu.com/2012/02/device-drivers-disk-on-ram-block-drivers/

7/10

8/14/13
number device files.

Device Drivers, Part 15: Disk on RAM -- Playing with Block Drivers - LINUX For You

b l o c k _ d e v i c e _ o p e r a t i o n s(prototyped in < l i n u x / b l k d e v . h > ) for the registered major

However, these operations are too few compared to the character device file operations, and mostly insignificant. To elaborate, there are no operations even to read and write, which is surprising. But as we already know that block drivers need to integrate with the I/O schedulers, the read-write implementation is achieved through something called request queues. So, along with providing the device file operations, the following need to be provided: The request queue for queuing the read/write requests The spin lock associated with the request queue to protect its concurrent access The request function to process the requests in the request queue Also, there is no separate interface for block device file creations, so the following are also provided: The device file name prefix, commonly referred to as d i s k _ n a m e(r bin the d o rdriver) The starting minor number for the device files, commonly referred to as f i r s t _ m i n o r . Finally, two block-device-specific things are also provided, namely: The maximum number of partitions supported for this block device, by specifying the total minors. The underlying device size in units of 512-byte sectors, for the logical block access abstraction. All these are registered through the s t r u c tg e n d i s kusing the following function:
v o i da d d _ d i s k ( s t r u c tg e n d i s k* d i s k ) ;

The corresponding d e l e t efunction is as follows:


v o i dd e l _ g e n d i s k ( s t r u c tg e n d i s k* d i s k ) ;

Prior to a d d _ d i s k ( ) , the various fields of s t r u c tg e n d i s kneed to initialised, either directly or using various macros/functions like s e t _ c a p a c i t y ( ) .m a j o r ,f i r s t _ m i n o r ,f o p s ,q u e u e ,
d i s k _ n a m eare the minimal fields to be initialised directly. And even before the initialisation of

these fields, the s t r u c tg e n d i s kneeds to be allocated, using the function given below:
s t r u c tg e n d i s k* a l l o c _ d i s k ( i n tm i n o r s ) ;

Here, m i n o r sis the total number of partitions supported for this disk. And the corresponding inverse function would be:
v o i dp u t _ d i s k ( s t r u c tg e n d i s k* d i s k ) ;

All these are prototyped in < l i n u x / g e n h d . h > .

Request queue and the request function


The request queue also needs to be initialised and set up into the s t r u c tg e n d i s k , before a d d _ d i s k ( ) . The request queue is initialised by calling:
s t r u c tr e q u e s t _ q u e u e* b l k _ i n i t _ q u e u e ( r e q u e s t _ f n _ p r o c* ,s p i n l o c k _ t* ) ;

We provide the request-processing function and the initialised concurrency protection spin-lock as parameters. The corresponding queue clean-up function is given below:
v o i db l k _ c l e a n u p _ q u e u e ( s t r u c tr e q u e s t _ q u e u e* ) ;

The request (processing) function should be defined with the following prototype:
v o i dr e q u e s t _ f n ( s t r u c tr e q u e s t _ q u e u e* q ) ;

It should be coded to fetch a request from its parameter q , for instance, by using the following:
s t r u c tr e q u e s t* b l k _ f e t c h _ r e q u e s t ( s t r u c tr e q u e s t _ q u e u e* q ) ;

Then it should either process it, or initiate processing. Whatever it does should be non-blocking, as this request function is called from a non-process context, and also after taking the queues spin-lock. Moreover, only functions not releasing or taking the queues spin-lock should be used within the request function. A typical example of request processing, as demonstrated by the function r b _ r e q u e s t ( )in
r a m _ b l o c k . cis given below:
w h i l e( ( r e q=b l k _ f e t c h _ r e q u e s t ( q ) )! =N U L L )/ *F e t c h i n gar e q u e s t* / {

www.linuxforu.com/2012/02/device-drivers-disk-on-ram-block-drivers/

8/10

8/14/13

Device Drivers, Part 15: Disk on RAM -- Playing with Block Drivers - LINUX For You
/ *P r o c e s s i n gt h er e q u e s t :t h ea c t u a ld a t at r a n s f e r* / r e t=r b _ t r a n s f e r ( r e q ) ;/ *O u rc u s t o mf u n c t i o n* / / *I n f o r m i n gt h a tt h er e q u e s th a sb e e np r o c e s s e dw i t hr e t u r no fr e t* / _ _ b l k _ e n d _ r e q u e s t _ a l l ( r e q ,r e t ) ;

Requests and their processing


Our key function is r b _ t r a n s f e r ( ) , which parses a s t r u c tr e q u e s tand accordingly does the actual data transfer. The struct request primarily contains the direction of data transfer, the starting sector for the data transfer, the total number of sectors for the data transfer, and the scatter-gather buffer for the data transfer. The various macros to extract these from the s t r u c t
r e q u e s tare as follows:
r q _ d a t a _ d i r ( r e q ) ;/ *O p e r a t i o nt y p e :0-r e a df r o md e v i c e ;o t h e r w i s e-w r i t et od e v i c e* / b l k _ r e q _ p o s ( r e q ) ;/ *S t a r t i n gs e c t o rt op r o c e s s* / b l k _ r e q _ s e c t o r s ( r e q ) ;/ *T o t a ls e c t o r st op r o c e s s* / r q _ f o r _ e a c h _ s e g m e n t ( b v ,r e q ,i t e r )/ *I t e r a t o rt oe x t r a c ti n d i v i d u a lb u f f e r s* /

r q _ f o r _ e a c h _ s e g m e n t ( )is the special one which iterates over the s t r u c tr e q u e s t( r e q )

using i t e r , and extracting the individual buffer information into the s t r u c tb i o _ v e c( b v :


b a s i ci n p u t / o u t p u tv e c t o r )on each iteration. And then, on each extraction, the

appropriate data transfer is done, based on the operation type, invoking one of the following APIs from r a m _ d e v i c e . c :
v o i dr a m d e v i c e _ w r i t e ( s e c t o r _ ts e c t o r _ o f f ,u 8* b u f f e r ,u n s i g n e di n ts e c t o r s ) ; v o i dr a m d e v i c e _ r e a d ( s e c t o r _ ts e c t o r _ o f f ,u 8* b u f f e r ,u n s i g n e di n ts e c t o r s ) ;

Check out the complete code of r b _ t r a n s f e r ( )in r a m _ b l o c k . c .

Summing up
With that, we have actually learnt the beautiful block drivers by traversing through the design of a hard disk and playing around with partitioning, formatting and various other raw operations on a hard disk. Thanks for patiently listening. Now, the session is open for questions please feel free to leave your queries as comments.
Feature image courtesy: materod. Reused under the terms of CC-BY-NC-ND 2.0 License.

Related Posts:
Device Drivers, Part 14: A Dive Inside the Hard Disk for Understanding Partitions Device Drivers, Part 16: Kernel Window Peeping through /proc Working with MTD Devices Device Drivers, Part 6: Decoding Character Device File Operations Device Drivers, Part 13: Data Transfer to and from USB Devices
Tags: c headers, device drivers, disk management, fdisk, Hard disk drive, LFY February 2012, linux device drivers, Linux Device Drivers Series, Partition table, partitions, RAM, RAM disk, source code

Article written by:


Anil Kumar Pugalia
The author is a freelance trainer in Linux internals, Linux device drivers, embedded Linux and related topics. Prior to this, he had worked at Intel and Nvidia. He has been exploring Linux since 1994. A gold medallist from the Indian Institute of Science, Linux and knowledge-sharing are two of his many passions. Connect with him: Website - Twitter - Facebook - Google+

Previous Post

Next Post

Building Image Processing Embedded Systems using Python, Part 2

Function Pointers and Callbacks in C -- An Odyssey

www.linuxforu.com/2012/02/device-drivers-disk-on-ram-block-drivers/

9/10

8/14/13

Device Drivers, Part 15: Disk on RAM -- Playing with Block Drivers - LINUX For You

1 comment Leave a message...


Newest Community newbie

Share

a year ago

I'm new in linux, but I know C/C++ from Windows. I use Ubuntu 11.10. In "Part 2: Writing Your First Linux Driver in the Classroom" I get error. Where should I put ofd.c and Makefile? In which folder source go?

What about "apt-get install linux-source" in "Part 3: Kernel C Extras in a Linux Driver"?
Reply 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 , ubuntu, Java, MySQL, Google, python, Fedora, Android, PHP, C, html, w eb applications , India, Microsoft, unix , Window s , Red Hat, Oracle, Security , Apache, xml, LFY April 2012, FOSS, GNOME, http, JavaScript, LFY June 2011, open source, RAM, operating systems

For You & Me Developers Sysadmins Open Gurus CXOs Columns

All published articles are released under Creative Commons Attribution-NonCommercial 3.0 Unported License, unless otherw ise noted. LINUX For You is pow ered by WordPress, w hich gladly sits on top of a CentOS-based LEMP stack.

www.linuxforu.com/2012/02/device-drivers-disk-on-ram-block-drivers/

10/10

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