Wednesday, June 19, 2013

Relation between device registration and driver registration

Hi all,
Today I observe one interesting thing during calling platform_driver_register(). The normal thing is if you have a device, and also a driver, It will be linked. But suppose you want to do some different functionality with the device, like you want to do some initialization of few variables  before starting the real functionality of the device.  So a nice way to do this is create multiple device with the same name but different id and register those usingplatform_device_register() or platform_add_devices().
So now when you will call platform_driver_register(), it will check for all devices available with the same name and the same number of probe() function will be called. Here in probe function you can put your logic for initialization according to your id.
Hope it will help you.

Tuesday, June 18, 2013

An Overview of Surfaceflinger

Basic Terminology:

Surface: A Surface in Android corresponds to an off screen buffer into which application renders its content. From application point of view, each application may correspond to one or more graphical interfaces. Each interface can be regarded as surface. Each surface has its position, size, content and other elements.

Surfaceflinger : It is a system-wide surface composer function which resides in android framework. It takes data( which is surface) from different application which could be 2D or 3D and finally combine it to obtain a main surface which will be fed to memory( which is framebuffer).
Surfaceflinger synthesize all the surface according to their position, size and other parameters, although this synthesis is done by OpenGL(which is invoked by Surfaceflinger), but we need Surfaceflinger to calculate the relevant parameters like overlapping function.

HardwareComposer : This is part of HAL, it is used by surfaceflinger to composite surfaces to the screen. The hardware composer abstracts things like overlays and 2D blitters and helps offload some things that would normally be done by OpenGL. This is done by using 3D GPU or a 2D graphics engine.

Gralloc : this is also part of HAL. Gralloc stands for Graphics memory allocator. It has two parts
                1. First provide pmem interface, which is responsible for contiguous memory allocation.
                2. Other is responsible for framebuffer refresh where UI actually put framebuffer data.        
      
Display: it is the physical display device. Current version of surfaceflinger supports only one display device which corresponds to display hardware.

Surfaceflinger, it does 3 main tasks:
                1. It creates a new displayHardware, which is used to establish a FramebufferNativeWindow to determine the data output device interface
                2. Initialize OpenGL, as this is the one which synthesize.
                3. Create main surface, on which all surfaces will be merged.     

How Surfaceflinger starts:

Step 1. SystemServer.main [Defined in SystemServer.java]
         It loads library named android_servers, and then call init1(args) function.

Step 2. SystemServer.init1 [Defined in com_android_server_SystemServer.cpp]
         It further calls system_init() funcion. Now in system_init.cpp it calls like property_get("system_init.startsurfaceflinger", propBuf, "1");  and finally  SurfaceFlinger::instantiate() After this, function checks whether system supports Binder inter-process communication mechanism. It it supports, it will call startThreadPool Binder to start a thread pool, and call the current thread IPCThreadState to be added in front of the Binder thread pool.

Step 3. BinderService.instantiate [Defined in BinderService.h]
        This function is inherited in Surfaceflinger by parent class BinderService.

Step 4. BinderService.publish [Defined in BinderService.h]
        BinderService publish static member function of class action is performed to create a SurfaceFlinger instance which will be used as a system SurfaceFlinger service. And this service will be registered with ServiceManager, so that in future after it starts anyone can use it in the system.  
 
Step 5. New SurfaceFlinger [Defined in SurfaceFlinger.cpp]
        This cunstructor will call init to perform initialization operations.
                
Step 6. SurfaceFlinger.init [Defined in SurfaceFlinger.cpp]
        Here we do some debugging stuff, and as surfaceflinger is Binder proxy object, we passs a pointer of type IBinder strong reference as a parameter. And this will call onFirstRef() function. 
              
Step 7. SurfaceFlinger.onFirstRef [Defined in SurfaceFlinger.cpp]
        First it calls a thread name Surfaceflinger and then it is used to perform UI rendering operations. There is a member class variable in Surfaceflinger, it is used to described as a barrier.It is a thread synchronization tool that blocks the current thread untill the surfaceflinger service UI rendering thread completes initialization operation. It will ultimately will call readyToRun.     
                
Step 8. SurfaceFlinger.readyToRun [Defined in SurfaceFlinger.cpp]
         This code first creates a Display Hardware object, used to describe the device display. And then use this object to initialize Surfaceflinger class member variable mGraphicPlanes which is described as GraphicsPlane. 
This function further allocate 4KB shared memory, it is used to hold the device display attribute information such as width, height, density and no of frames per second. Other process can access this block using getcblk.
Now it initialize dpy(display)'s element like width, length, pixel format and finally make it as primary display. Next we initialize OpenGL Library, as it will be OpenGL which will be rendering.Further, LayerDim:initDimmer() function is called. LayerDim is udes to describe surface with a color gradient function. Then it allows system UI rendering as initialization is complete. Finally we will call boot animation.      
                     
How Framebuffer is opened from SurfaceFlinger:
                      If you remember I mentioned earlier that we create FramebufferNativeWindow. Here it calls framebuffer_open and gralloc_open. First lets take about framebuffer_open. Call goes like : framebuffer_open() -> fb_device_open() -> gralloc_open() -> gralloc_device_open()         
                                                               -> mapFramebuffer() -> mapFramebufferLocked() -> It opens the device as /dev/graphics/fbX or /dev/fbX. Further we pass all other info using IOCTL FBIOPUT_VSCREENINFO depending on Pixel format which we get using property_get() function.
             At the same time we call grDev->alloc which calls gralloc_alloc  which ultimately calls gralloc_alloc_buffer, it allocates ashmem memory for graphics buffer.              
   
How framebuffer is updated:
As we saw Surfaceflinger initialization part, once it is done, surfaceflinger service waits for any event to occur. Event could be anything like new application launched, orientation changed or any other app came in foreground. So after initialization Surfaceflinger is stuck at waitForEvent(). When event occurs, onMessageRecieved() is called. It calls
        -> handleTransaction(), it takes care of shifting layers and adjusting layers according to the size or orientation of window.
         -> handlePageFlip(), it will traverse through each layer and calculate the dirty region(which needs to update). During this time lock is held on frontBuffer.
         -> handleRepaint(), it composes surfacesAs Overlay is present so composer assume framebuffer as transparent and finally draw layer by layer using OpenGL calls.
         -> postFrameBuffers(), This is final call to swap the buffer. call flow goes like this                                              -> flip()[DisplayHardware]->eglSwapBuffers[OpenGL] -> queueBuffer(libui) -> fb_post(gralloc).

How GraphicsBuffer is associated with user application:

In gralloc.h there is a member structure as gralloc_module_t which defines all the method associated with this HAL module. Here we have register_buffer()/unregister_buffer() [Defined in mapper.cpp].                                These methods link the graphics buffer allocated by gralloc_alloc_buffer() to the application address space using native_handle_t(this is one more data structure).

MISC about HAL:
   - For display system, gralloc is provided as a HAL module. Its job is to encapsulates all access to the framebuffer operations.
   - With gralloc device, the user space application can allocate a graphics buffer.
   - Each HAL module has an ID value which will be used to open the module using hw_get_module(). Here it is GRALLOC_HARDWARE_MODULE_ID "gralloc"
   - hw_get_module will load following so file : gralloc..so, gralloc..so, gralloc..so, gralloc..so.[Here in paranthesis these are properties ]
   - you can check private_module_t for a lot of details.

References: 

Saturday, July 28, 2012

Infix to postfix conversion algorithm


This blog has been moved to android.rahulblogs.com
For this post please go to 


http://algo.rahulblogs.com/2012/07/infix-to-postfix-conversion-algorithm/

Tuesday, June 26, 2012

Trek to Thirumaleguppi

Its been a long time since I have been writing a travel blog, and the reason was pretty much because of laziness. So here I am with a new travel blog about my 3rd trekking experience, a place called Thirumaleguppi(apparently it means three peaks) . Although it took me a complete day to remember this name and a whole night, full of bumpy night to reach there, this place worth this trouble.
As you will find Karnataka full of Tourist places specially Natural beauty, sometimes I doubt why people doesn't consider it as a must go travel destination rather than just a IT Hub. Anyways here is my journey details.

Distance : This place is around 300 Kms from Bangalore City Near to Mangalore.

How To reach : you can hire a travel company to arrange the cabs according to your need, or you can take train till Mangalore and can hire cab from there. Once you reach the place, you have to take a Jeep to reach the base camp, as it is around 40 mins ride from the village to base camp.And I must say it is one of the most difficult part of journey, as you will every part of your body shaking specially stomach.


When to Go : I will suggest to go there before heavy rainy season starts which almost be there around July. As this place is surrounded by thick forest too. And slippery place can make your trekking difficult.

What to do : Its a pretty straight forward answer, "do Trekking" :).

How's the trek : Trek is nice and if it is not raining i guess you won't find much problem.  The distance is around 7 Kms one way. And apart from one particular place between peak two and three, it is decent trek.

What to Carry : As water falls is there in between, you may find leeches few places. so I would suggest carry all the necessary items accordingly like knife, salt and specially any spray, it will help you to remove leeches as well as it can be used if you get any strain in your muscles. Apart from these carry raincoat, water bottles and some snacks, as the whole trek will take around 8 hours to complete. Also take care of your shoes, as at the time of getting down, the place is slippery.And yeah if you are planning to stay overnight there please carry the sleeping bag too. Also pack your medicine box with first-aid as well as motion-sickness tablets as road is very bumpy.

Fee : To trek there you have to take the permission of Forest department, they charge around 275 Rs per person. Although as you will take some local guide for trekking, he will arrange it for you, so you don't need to bother. For your reference I am sharing a guide number and name where we stayed, he arrange our breakfast-lunch-dinner as well as the passes and night stay. His name is Satish, and number is 08263-249595 / 9481074530 / 8722847688)

What else : Apart from this, if you want to trek more, you can also go to Kudremukh, it is just adjacent to Thirumaleguppi. One fall is also there which is called as Somavathi Falls, and I must say the water is cold man.

If you are interested to go for other places to trek, I guess you can contact Bangalore Mountaineering Club, those guys organize trekking almost every weekend. I hope this blog will help your preparation for Trekking to Thirumaleguppi.

Keep Enjoying.

Friday, June 15, 2012

OpenGrok : Installation Guide

Hi Guys,
Here is one more useful post for Linux users who use grep to search strings or references in huge code-base.So here it is
Prerequisites :
1. jdk 1.6 + version
2.  tomcat 6 + version
3. exuberant-ctags
I will suggest that become root user (using sudo -s) so that you don’t need to give sudo prefix and then type the password every time you want to run any command. One line command to install all of these :
apt-get install sun-java6-jdk tomcat6 tomcat6-admin exuberant-ctags
4. Download the opengrok-0.8.1 from the site.
Steps:
1. Extract the downloaded package.
2. Create a directory structure like follows
  • mkdir /opengrok
  • mkdir /opengrok/bin(this will contain all lib file and jar file)
  • mkdir /opengrok/data ( this will contain the index data).
3. Go to extracted opengrok directory and run following commnad
  • cp -r run.sh opengrok.jar lib /opengrok/bin
4. Go to /opengrok/bin, open the run.sh file and Edit it in the following way
  • modify SRC_ROOT = /path/to/your/project/directory
  • modify DATA_ROOT = /opengrok/data
  • modify EXUB_CTAGS = /usr/bin/ctags (this is default location for ctags, you can verify with ur system if it doesn’t exist there)
5.  Go to extracted opengrok directory, and create one folder called source
  • mkdir source
  • cd source
  • unzip ../source.war
6. open WEB_INF/web.xml file and add the following code and save it
DATA_ROOT/opengrok/dataREQUIRED: Full path of the directory where data files generated by OpenGrok are stored
SRC_ROOT
//path/to/your/source/directory
REQUIRED: Full path to source tree
SCAN_REPOS
false
Set this variable to true if you would like the web application to scan for external repositories (Mercurial)
Here one more thing you do check for CONFIGURATION tab and in that please check the path of opengrok configuration file. The path should be same as the correct location of that configuration file.
7. Again zip the code
  • cd source
  • zip -r source.war ./
8. Now finally we need to start indexing, so just go to /opengrok/bin folder and give the following command
  • java -Xmx1524m -jar opengrok.jar -W /opengrok/configuration.xml -P -S -v -s  /path/to/your/source/directory  -d /opengrok/data
9.  After indexing completes, you have to modify the admin rights for apache so that you can manage it, So open /etc/tomcat6/tomcat-users.xml and add the following line


10. Now your setup is ready, you just need to deploy the source.war you created earlier. for that follow these steps
  • http://localhost:8080
  • click on manager webapp or directly open the link [http://localhost:8080/manager/html]
  • give username “admin” and password “admin”
  • There is a option in that page called Select War File to upload, there click Browse button and give the path for your source.war file.
  • And finally click on Deploy.
  • After Deploy is complete in List of Application on the same page, you can see /source click on it. And you have just completed the installation. you can see the opengrok home page.
11. If you are getting the permission denied error then add the following code in /etc/tomcat6/policy.d/50local.policy
grant codeBase "file:${catalina.base}/webapps/opengrok/" {
     permission java.security.AllPermission;
}; grant codeBase "file:${catalina.base}/webapps/opengrok/WEB-INF/lib/"; {    permission java.security.AllPermission; };
Thanks for Vincent Liu for his wonderful post which helped me a lot.

Tuesday, March 6, 2012

When to use the workqueue in driver code / What is workqueue

Hey guys,
Here is one more post about kernel, As I am going through Kernel code, I feel this doubt. Theoretically it is assumed that workqueue increased the performance. As you are allowing the interrupt to be enabled. So it means you are ready to handle another interrupt while putting the previous interrupt handler code in workqueue.
But is it a good way to put all the interrupt handler code in the workqueue function, The Answer is NO. Why ? To be part of my belief first you have to understand the basic functionality of workqueue. Linux Kernel developer came with this concept, because they want to reduce the overhead of unnecessary execution of code at the cost of performance(As no other interrupt will be allowed during that time). So what they do is, they divided the functionality in two parts, crucial part and the normal part. With this approach they decided which code should be executed before enabling the interrupt and which part should be executed later.
In summary,what developer should do is, decide the importance of the code in terms of functionality and performance and accordingly put the rest of the Not-so-Crucial part in the work function.
Hope it will help.

Thursday, March 1, 2012

Difference between schedule_work() and queue_work()

Hi Guys,
If you are newbie in Linus Kernel, you may have this doubt that what is the difference between these two methods,basically it is related to the choice that whether you want a dedicated workqueue(which in turn will need dedicated kernel thread) for your driver or you just want to use the default workqueue provided by kernel.
So if you want to control the workfunction in terms of scheduling independently,
you should go for create_workqueue method to create a workqueue. This function will create a workqueue and which in turn will create a seperate Kernel Thread on each and every processor available. Here I would also like to introduce a different version of same method which iscreate_singlethread_workqueue(), you should use this function only when you want to create only a single thread for all the processor.