 So, good morning. Today we are going to discuss something of much greater significance that mentioned last time briefly. Writing device drivers has not been an integral part of our coursework in the digital colleges. It is sadly so even in IIT. So, whenever people have to write device drivers, typically when they are doing their final year project or master's research of IIT, then they figure it out themselves. Now, increasingly in the embedded system where much of the functionality will depend upon the peripherals that you can attach to your basic design board, it becomes mandatory that you are able to write good device drivers and good is important because device drivers often define issues like performance, issues like stability, so on. So, I am very happy to once again welcome Nitin. Nitin has come all the way from Pune as you know last time. He has now two of his new colleagues are not rather new for him, but new for us. One is Anshul. He did his master's from IIT Kanpur and has worked on the operating system for smart cars with Mr. Rajat Munna who is currently the director general of SEALAC. He works with them and we have Devesh who did his compressions from VHU IIT. They both work closely in the Nitin's team on issues related to device drivers and of course related stuff. By the way, when I say device drivers, I must make one point here. I think I had mentioned it earlier. This separation of expertise that person is hardware, this is software, that fellow writes device drivers, that fellow works on something else, etc., etc., is extremely artificial and very dangerous. That is something we emphasize very strongly in IIT system. I would like you to carry that. You would have understood it but would not have imbibed it into you. In the sense that since you study specific syllabus and give exams for specific subjects, you tend to believe that that is all you ought to know, which is completely incorrect. As you would have felt in the internship itself, there is no problem which is bounded by this discipline of that discipline. So whatever is required to solve a problem, you have to study. It so happens that device drivers, good device drivers have to be written. You all have to learn to write device drivers. Attending lectures is merely the beginning of any learning. So you should figure out some assignment for actually writing some device drivers, specific device drivers for interfacing devices. It does not matter whether you take a device to be interfaced through a USB to a micro control. It does not matter what you interface with. But writing device drivers, you have to dirty your hands. By reading somebody's code, you cannot become an expert program. Similarly, by listening to how to write device drivers and reading somebody else's code, you do not become an expert device driver. So I will stop here with it all your simple things. I am working, like I have a work except around 11 years. I have worked on file systems and Linux block layers and device drivers and then like we are with the Einsteiner technologies for couple of years, I am working on a different kind of block, different kind of device drivers, mainly on the embedded systems. So first part, what we are going to cover is that before going into the how to write a device drivers and we are basically will introduce you to the environment, that what kind of environment basically you need before for a embedded like on this board, like this is the board. So on this board, this is the board. So for this board, if you want to write up some particular device driver for, so here you have a lot of, lot many connectors like you can see that you have a ethernet board and then we have serial connectors. So if you connect any device, any new hardware to this particular board, so operating system running on this board should have that particular device driver. So we are going to first cover that how to basically create the environment in which you can develop the device drivers. Then we will come to the part that how we can through the kernel and interaction of the hardware device drivers. So this is the Beagle board. So first you need a hardware board and then what you need is that some kind of operating environment, like some operating system that need to be ported on that particular board. So operating system has one part and you must be knowing that it is a software part and then there is a architecture part. So like if you are porting any operating system on any new hardware, so you have to basically port, change its architecture part to as per the new hardware specification and then you can basically run your operating system on the any given board or any given new hardware. So the first part is that you have to basically create a, you port your operating system on a new board and then you, if you want to write any new drivers, so then you have to write new drivers as per the hardware and hardware specifications and then and before that you have to basically then there is a as you comes that how to compile the drivers and then at last you want to test your drivers. So you have to run your operating system and then load your modules and test it. So nowadays like almost every operating system does provide a mechanism that you have a loadable kernel modules. So you do not have to basically build your kernel every time. You have a loadable kernel modules, run time you can load it and then you can unload it as well. Only thing is that you have to be a little bit careful about releasing the resources of the operating system which you use because generally the kernel drivers runs into the privilege mode. So this is basically the Beagle board. Beagle board is basically a open source hardware. It is mainly for the students and they can use it for their experimental purposes and it was basically introduced by Texas Instrument and Diziki. It has ARM architecture because I have heard about ARM. So it is ARM architecture and mainly for learning purposes it is being used and so this is about the Beagle board. Do you have any questions about the Beagle board or something? We are good. So on a board you initially any company which provides you a platform like a board. So it will burn some initial images into the ROM. So now that will basically use for your initial boot up. After that whatever kernel, Linux, Bit, Android or any kernel or any operating system you want. So you have to basically write your loader and then so you have a loader which loads U-boot. So we have like we are coming as a boot loader MLO. So this is basically loads your U-boot. U-boot is and then U-boot is for operating system. So loading the operating system you need some kind of environment or you need to some kind of pass some argument to the kernel that load with let us assume that you have like you want to set board rates or you want to set board rate you are aware of board rate. So like kernel you want to set that what is the board rate of kernel should use basically to communicate. So through U-boot you can do that and then U image is basically the micro image of the kernel. Any kernel it can be Linux, Android, previous D or anything and then there is a root FS. Root FS is basically the operating system requires this root FS where you have all your bindries placed. So like on Linux machine if you type some any command right LS. So that binary is in the root FS. Similarly so root FS is basically required for kernel to kernel per se does not require the root FS but for user to use that particular kernel or particular operating system then you require root FS. So these are basically for Android for Beagle board you can take this U image and root FS from the free electron side and then for basically if you go back so it is so MLO and U boot you take it from the Beagle board side itself and U image and root FS you can take it from the free electron side. So they have like documented variable it is there that how to build your kernel and then how to basically build your root FS then how to build basically your and on Beagle board they provide basic MLO and U-boot. So some U-boot settings you require to change. Right now unfortunately it is we do not have a connector so I cannot show you right now. Nothing is working on that probably at the end we will have a demo that how to basically load the kernel and compile it like we have a compiled kernel but we want to load it and show you that what is the U-boot prompts look like and then what is the kernel prompt look like what it is. Nothing is working on that hopefully we will at the end of the session hopefully we will. So yeah the compilation requires like you have a operating system x86 which is x86 machine and you have a Linux box Linux running on top of that machine now you have another board which is ARM basically this architecture is ARM ARM base and it does not have anything right now no kernel no operating environment. So you want to build your initial kernel and everything for this particular board. So what you require? So you require a toolchain the compile toolchain heard about like cross compilation and all okay. So then you build your tool chains and then using those tool chains so that particular like your GCC will create a binary for ARM specific. Still it is running on the x86 box but if you build any binary it will create a binary for ARM ARM hardware. So that is this is why we require toolchain and then using this toolchain you can if you have ported your kernel you have changed the architecture part of the kernel then you can compile your kernel and this will give you the U image. Then similarly like you need to build all your user utilities and that is root of S and then this board basically you have SD card so and this card basically this is the card here you burn your bootloader MLO then you burn your U image and then you burn your you boot sorry just a minute. So this is the order basically this is you need to burn the MLO. So this is the order basically you burn on this particular SD card. So there should be MLO first. So the built in loader on this card will look at the first sector of the this SD card and it assumes that there is a loader over there. If loader is there it will load that particular it will start running load that MLO. So MLO is supposed to be on the first sector of the SD card. Then MLO is programs as that it will load U boot. U boot is something where you can set your parameters that kernel you want to set board rate you want to set consoles like pass the argument to the console. So anything you can use U boot for that then U boot is program to load your kernel. So your kernel can starting point of the kernel is let's assume that 8000 or any memory address x. So your U boot will load your kernel and then make CPU to jump on that particular address and it will kernel will start booting up. And finally the kernel when kernel initial part is when it started then it looks for root of s so that you can user can get a prompt. Is that part clear right? That how basically the on this particular SD card how it is the images get loaded. Then this is the setting up till now you have kernel image loaded. Now you want to write a particular driver and you want to cross compile it the driver for ARM and then you want to basically load that driver. So what you do is that you have created the tool chain. So on your machine where you are compiling your kernel and creating root of s there itself you basically include that particular tool chain in your path. So the first expression is export path and this is your cross compile it compilation tool chain it will come into the path then there is a cross compile flag. If you look at into the Linux Android is basically Linux based operating system. So if you look at the main make file of the Linux there you will see that there is a cross it has been used for the cross compile flag is used. So and then you say that you want to compile it for or equal to ARM. So like when you cross compile so generally if you compile your program on x86 ball so you do like GCC and then your program. But your cross here will be your like anything main dot c or something. But if you are compiling same program for ARM so it will be something ARM and some prefix. So you basically set this part as a cross compile cross compile in the flag. So whatever prefix you have created your tool chain if you look at the list down the tool chain you will see that this is the before GCC before assembler before loader everything this prefix will be there. So this is the this prefix you want to set it into your cross compile flag and then you export and say that you want to compile it for ARM and then you want to so this is your basically environment setup for the compiling a module and then you this is the make file. So you you are aware about make utility right. So in on the command prompt you can write this GCC something like GCC and then you can give your this files name your program. But for a larger when you are you have hundreds of files you do not want to write or you do not want to compile every file by yourself manually and so you write a make files for that make file is basically utility to make your executable. So in make file like those are typical example of a make file how to you have extra c flags where you can say that the kernel always defines some of the c flags against which the kernel module will be compiled. But you can add your own extra c flag so this is the extra c flags this is the standard keyword and then you can pass that minus g option you want to include symbols in your binary. Then you want to use optimization level two for compiling your program then any any your program needs if any other variable you can define minus d and then your flag. Then you write this obj minus obj-m so this is the keyword basically those are how it assumes that and there whatever name you give name dot o so if you run this make file it will create a module name dot k o k o is basically kernel object so kernel object will be created and this name dot o can be less make of made of lot of files. So how do you specify that which files this particular you need to compile so there you say that name and obj's and then you provide a list of like space separated list of files. Then against which kernel you want to compile your module this you provide that might use this particular kernel source to compile this program and then this p w d like present working directory where you want to basically create your object files this make will create lot of objects files if you want to create it on some temporary space or anywhere you can use this variable. And then then you provide default default is the action basically and then you say that run it it will create your object files you can provide a clean option like you want to just delete all the dot o files you can provide a clean option for that. So now you have created your module you have compiled your module now you want to burn like the order in which I told you earlier that you need to burn first m l o then you need to burn u boot then and you have compiled your own kernel module you want to put that particular kernel module in root of s in some directory and then you burn your u image burn your root of s load load and then put this particular sd card into the beagle board this will boot your kernel and you can you can load then your kernel module that is in smart is a utility which loads the kernel module into the kernel and r m mod is a utility using that you can basically remove your kernel module. So I just coming up that what whatever I told you that we need to basically first like create a cross compiler cross compilation tool chain then you require kernel source downloaded from the sites which I told you then there is a steps mentioned clearly on those on that side you can basically build your kernel then you build kernel third step is basically it create a root of s and fourth is like if you are writing any new device driver which is not there already in the kernel Linux provides lot of device driver in build device drivers are there but if you have written any new particular device driver you basically need to build your kernel module against this particular kernel source and then you need to copy this came on kernel module into root of s some directory in the root of s then you you have this is all is your kernel image and kernel module is ready now if there is a MLO is available on the beagle board side that is the MLO burn it on the SD card this MLO will is using this MLO you can load your load your basically U boot U boot is again being used to load your kernel image on U boot prompt it gives you a prompt basically there you can there is a lot of environment variables if you type print env it will show you that what all parameters you can set so there is print env and you can set any environment variable using set env and then you can basically save env but this is all three commands are there so but the save env writes be very careful well saving particular any environment variable that may that may basically cause your board not to boot so take a copy whatever default parameters are there you save it into some other parameters like if you do the print env you will see that there is a some it will show you that there is a boot arc this is the kernel boot argument it will have console something then you have board rate some like set 2115200 or something like that stop bit and so if you want to change this the recommended way is that you do that set env and name any boot arc old and you save it whatever your boot arc your current boot arc so you take a backup of your this current boot arc and then set your new one if you change directly this it will change your basically the it what I was saying is that there is this there is print env then you have set env and you have save env these are the three commands using which you can change the u boot parameters yeah u boot parameters print env will list down whole lot of whatever parameters are there in the u boot so it will show you the print env set env you can use to change a given parameter or set your create your own new u boot parameter and save env will save that particular on the nand flash of this card so once that is saved the older one is gone so that what I was saying is that you need to take a backup whatever current so like you can write something like boot arc old old is your new new argument and whatever the current value is you can save it into the boot arc old and then you can change then you change boot arc this is this way you basically set up your environment after that you if you type on the u boot prompt boot it will start loading your kernel the kernel which you have burned into the SD card then like it will give whatever you have saved in your root FS you can go and see using like you do CD basically go wherever on the root FS you have saved your kernel module you change to that particular directory and then you can list and then you can do something like in smart and this will load your kernel module and to remove the kernel module you can use module basically you have a routine that is you tell kernel that whenever you load the module you have a init function so kernel is going to run your init function first the minute you load the module there is a init function that will be executed and when you unload the module so there is a exit function so there is a format of writing a kernel modules and then you can specify tell kernel that this is my init function this is my exit function and after that whatever logic you want to implement in the kernel module as per so during so there will be a init function and there will be a exit function in your module in exit basically you do all the cleanup in init you do the initialization whatever initialization is there required you do the initialization the init part our goal is to develop a driver you want to write a device driver but these device drivers I mean they you cannot you know develop them independently you require some kernel some OS say you are on Linux or you are on Windows so Windows it has upper layer of OS and it has a layer I mean the which accesses the hardware so the layer which accesses the hardware we call them hardware driver or the device driver for device so initial goal is to set up the you know this environment prepare this kernel so that I mean we can write the device driver so as you mentioned you know it has nothing the few things are in this it expects it expects you know so when you want to boot a kernel it expects that you keep a boot loader at the first sector of SD card and if you give it to him then it has a program in its ROM it can boot that thing automatically okay so first thing you require MLO because it will not understand anything else what it then okay so what you write in MLO so thing which loads MLO is pre-return into this okay that's not our worry but you provide MLO and it comes with this when you buy this legal board you can download them online but these MLOs are very specific to the board version of the board you know this is a C3 board so rather this is C1 board MLO will be specific to C1 because whatever is program into this that should understand that MLO right so that's very much specific to the version of the board now so okay we have got MLO now what now we want to load the kernel but kernel requires certain parameters so what is its load address you know all those things and then terminal settings what rate as they wish mentioned all these things it requires but these things you know so there should be something which will allow us to set up these parameters so that thing is you would you see the second thing so then MLO expects MLO is written in such a way that it will load this I mean you boot so when you load you would you will come you will see a prompt like you know dollar or hash you should see in shell prompt of Linux so there you have certain commands those commands are very standard you know so I want to set the boot arguments I want to set the terminal settings those are command those all commands are very standard and you can I mean change those commands depending on your need so you want to I want to change my boot my kernel load address from say 8000 to 9000 for whatever reasons so change those addresses okay then once you have you know decided these boot parameters have set these boot parameters so we save them as he mentioned you know we do print these these all commands are for you boot print and we will list down all the commands all the options set set ENVs for setting it so now you want to set the load address load addresses say suppose it's 8000 I want to set it to 9000 but be careful as he said because these things are not saved in your SD card anyway it will be saved in this right so on NAND flash so once you save it you cannot get it back either preserve whatever the previous values were and then you know basically change it so that you can always revert back and then you do save ENV save ENV will save it into the flash and then again now you want to so now you have set the boot parameter I want to load the kernel how will load the so what is the kernel it's like simple OS you know so as you mentioned Android Android is Android is mainly based on Linux only so most of the part is taken from Linux kernel but because they wanted it to port for mobile platforms so they have pushed in the changes which are required for mobile platforms so such as you know because power consumption is very important for mobiles so that part is you know change heavily Bluetooth component and this flash file system because general desktop systems your hard disks right but mobiles you have flash disks so you require a very you know specific file system which is very well performing so all those changes have gone into Android so that's why we have now we want to develop something for mobile we've chosen to you know port Android on this I will port Android so Android is our kernel it's OS but when so kernel is a micro you know it's so you know you are aware what is kernel you know yes you know it's minimal set of operations provided by the OS you know so OS could be segregated into say user level programs applications but kernel is you know whatever is privileged so that part is it's called kernel it's like you know kernel of some fruit it's very essential very minimal you know so these things are so that kernel we I mean so Android we have compiled Android so why do you require compilation I mean first arm compile it was compiled to compile it for some other architecture that's why you require cross compilation so by doing this cross compilation we have got our Android for arm okay now we will so steps are clear right first we'll put MLO and this order is very important I mean how do you copy first we have to copy MLO in SD card we require MLO you boot U image and root FF why do we require MLO at first right as I explained because it this card expects MLO to be at the first sector of SD card so if you copy say U image first it will treat your U image as MLO it will not work so that's why you copy MLO so MLO will be loaded by pre-written thing then MLO will load U boot U boot will load U image and U image will use root FF so that's why this order is maintained you know and once you have this U image ready U image you have cross compiled everything by cross compilation you'll get this okay and so after you know basically execute a steps properly and these sites are you know very much explanatory you go to them and they'll explain you I mean why they are doing it and so here in this block I mean in general with this site is very good for you know for embedded resources free electrons you'll get a lot of good resources and Beagle board I mean about Beagle if you want to read on I mean there is a Beagle board.org so this board is you know it's quite heavily extensively used and in university and you know generally so whenever they develop it they generally whenever they come up with a new board they'll go to the Stanford or somewhere and they'll demonstrate that we have come up with a new board so you can expect I mean why this board is so much popular because low cost and you know it's very resources are very much available initially if you see now you know we call it Beagle board is open source hardware must have noticed you know when open source software you have heard why this open source hardware because you know to access any hardware board you require you know it's a specification so suppose I want to access the NAND flash so what is the register in which I write then it will pass on that value to this NAND flash so all those register is specification I require right I need to know I mean how this hardware is organized I need to know the specification for it data sheet of it so if you buy a proprietary hardware I mean you can only you'll not get I mean so if I said tomorrow I go to market and I but I buy say LSI controller LSI hard disk controller so I cannot get it's specific specification for free that's why those hardware becomes very costly but for this Beagle board I mean they have made all these specification all these data sheets free you can go to and you can download data sheets for this that's why they are called open source hardware so you have got this board you have prepared this right prepared this means I mean if you do these all these steps you'll get your kernel loaded into this and now why do we require this loadable kernel module I aware man what is what are kernel modules when you compile a kernel you know it offers certain facilities or certain services right but now compilation is a long process like you compile a kind of like one hour one and half hour depending on the kernel now if you want to say build a driver for whatever NAND flash then imagine your development process will become very huge every time you'll have to compile a kernel right because while decoding you keep facing bugs right okay oh I miss this I'll change this but every time if you have to compile and test it'll take one and half hour right this is so loadable kernel modules are you know you compile a separate entity we call it a module and that module interacts with the kernel so kernel provides a method so by which you can insert that module in kernel so it makes your development easy you know there are certain other sides to it also but I'll stick to this thing only why do we require this kernel module so to make our development easy we are we require these loadable kernel module now these loadable kernel modules are so how do you load as you mentioned using this in small utility in small it's provided by kernel only when you say in small module .co load your module and whatever your module is expect to do it'll do so there is a certain format when how do you write a module very popular I mean you can search for any how do you write simple hello world module suppose my intended module just prints hello world when I load it and when I clean it so when I remove it it says goodbye that's it's you know designated job so when I do in small my module .co it will just print hello world when I'll say RM mod my module .co it will print goodbye so these so this is simple module but suppose I mean I have written my you know this USB driver module for this particular card as a loadable kernel module so if I say in small USB driver .co after I have you know loaded my Android and everything so you'll see the you'll see the hash prompt like you have seen in this the next shell compile your module separately and in small USB driver .co if everything is fine you have written your driver correctly you'll I mean you'll see that you can access your USB devices so it you know it shortens your process otherwise every time you have to compile the whole kernel you might not be able to appreciate right now but just try to compile a kernel once and it will like one and one or two hours and if you have to compile tool change another four hours one so I mean compile in morning come in evening it's like that so that's why I require these modules we haven't really gone into writing drivers you know how to write a driver that's next session but preparing this environment is very much necessary otherwise you cannot these are all you know just understand them like concepts don't try to remember like steps you know if you try to go on remembering like a steps you'll forget just every time you go and search let's try thinking why these why we are doing these things and same is for writing device driver professor mentioned I mean we don't really you know write device driver when we are colleges I didn't do it also didn't manage my company but it's you think logically steps what we are doing you know I mean next presentation also we have kept like this only I haven't really touched you know he's when you know I take a disk driver or anything but if you understand those steps you will be able to write any driver for any OS OS could be you know whether be it 3BSD or say Linux or you know Android whatever and for any architecture also architecture is a x86 because general concepts are same with the environment with the requirement they you know you can how to apply them that thing changes but once you understand those things so I mean you should be initially it looks like I mean it's scary I mean why are they doing I mean so many things but just try to understand I mean each step once at a time and why do you require it it's very easy to you know figure out when what's happening and you will easily easy to debug also suppose okay I might give it but my kernel is not getting loaded so okay so till this point everything is correct you know how do you debug logically right till this point okay this thing is working now it's not working if you just try to you know cram them as a set of steps will tend to you know get overcome by it so just try to understand you know why are we doing these steps these commands and all these things will easily you can easily find anyway just Google it and you'll get it these are standard let's try to understand why are we doing these things and same is you know for hardware writing also before that I mean how comfortable with OS operating system concepts like synchronization locking lock you know so these things I require you know I'll cover in brief detail I mean why do we require these things