Device Tree for Dummies! - Thomas Petazzoni, Free Electrons

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Thank you! I’ve been trying to understand the device tree since I finished that podcast!

👍︎︎ 2 👤︎︎ u/CriticismSad2715 📅︎︎ Nov 20 2020 🗫︎ replies
Captions
Hey hello good morning I guess it's time to get started so before I get started with the talk how many people have already written some device tree fragments yeah quite a few maybe like a third of the room okay not such as okay so in this talk at the title so exist I'm going to try to go from the basics and introduce what is the device tree what's the main idea beyond that and help you understand the syntax of the device tree and hopefully a little bit the spirit of the device tree as a disclaimer I'm by far not the device tree guru oh all the talk is better on what I've learned in the field doing some arm developments obviously it's all arm stuff it's not it should have been in the subtitle probably but it's all arm related I don't know how the device tree is used on other architectures but at the moment I guess it's most of the crowd it's probably going to be interested in arm specific things so it's really I'm really not the device tree guru I will try not to make too many inaccuracies but there might be some I will just try to share how I see the device tree today just a few words I'm Thomas work for free elections we do training and development and the reason why I've gained some device free experience over the last year and a half is because we've been involved in mainlining the support for the Armada 370 and Armada XP SOC is for Marvel so those association ass devices and we've pushed the the support for those SOC into the mainline channel and it's it was all based on device tree from day 0 so we've done a lot of device related work around that and I also happen to to work on unreal boot as a side project so today I first want to start with the user perspective so not the keynote developer but the user what the device tree is changing in terms of how you boot the cane oh so it's going to be a fairly short section then goes through the basic device tree syntax and see a simple example of a device tree then the overall organization so after looking at a very simple fragment look overall what's the organization of the different nodes and sub nodes that we have in the device tree and then we'll go through different examples of device tree and we'll talk about different bindings and mention like clogs and pin control and interrupts and things like that just to give you a feeling of how the device rate is being used today and then end up with some general consideration about device tree bindings design so before the device for you when you wanted to use a cane Alon arm the kale with completely containing the entire description of the hardware in terms of sea based structures describing all the platform devices the ice core C devices the SPI devices so the Kindle was I would say self-sufficient you had a single binary you image the image whatever image that you're using your bootlegger puts that into memory it starts its and before stunning it it gives it a few information the Machine number in register r1 and in a tags setup information so it's kind of a data structure the debugger bills with information such as the memory location and size they can all come in line and a bunch of other things and passes that to the kennel which finds it at some location pass in r2 parse is that but the most of the if not all of the hardware description was inside the kennel itself so it's pretty much what you add a new image just attacks information passed by the bootloader and that's it so what the device free changes is that the description of the hardware moves into a separate binary blob that's a new file an additional file next to your keynote image so in addition to your you image shows image you have one of those files that ends with a GTB extension which is the binary compiled version of the device tree describing the hardware platform and the bootloader will actually load two things into memory on one side the kindle image as it used to do and also the binary blob and will pass the address of this binary blob to the kano which will parse it to find out what's the hardware available on this particular platform so it replaces the Machine type idea it no longer exists and the kennel is really bases all its hardware discovery and strategy on on the device tree so that's that's the on the user perspective so yeah basically instead of attacks that were limited to describing a very limited set of information we now have much more complicated data structure with a lot more information and that being that is being passed by the to the Kano so that's nice but it requires a device tree capability at the bootloader level as you've noticed here below I've mentioned how to boot a device free capable channel from the bootloader bus from you boot and and bear box so the bootloader needs to be aware of that you need to be aware of this change in the protocol between the bootloader and the Kino and in it happens that not all good loggers that are available today on platforms and existing platforms do sleep on that so yes you're good and bear box in their main line version do support that but as most of you probably know many of the platforms around have some crazy vendor boot loaders that have been three ten years ago and they are not going to change really soon I mean for some vendors it's in the process of being done for others it's already done but you don't necessarily have a device tree capable boot loader so for to solve this problem the king of developers have added a compatibility mode which is called the appended dtb and the idea is that to make the is to make the boot layer believe that there is still only one single King on image file to load into memory but in fact this channel image is actually the cannot image itself to which you append the DTB which is the binary version of the device tree and the way you do that is just with scat or whatever tool you like to do this and then you give your boot loader this thing it doesn't know it as a device tree but since you've built the King on with this configuration option I can click arm opinion DTB the keynote will look after the kennel image find that there is a gdb and use that as the hardware description and from that point on it's exactly similar as if you add a device tree capable bootloader there is also an additional option a tag dtb compat which tells the can read the attacks information that are passed by the bootloader so normally if your bootloader is DT capable no longer attacks but since your bootloader is in that case no DT capable it's still passing some attacks including the cannot come online and the memory location and size and the candle is kept up capable of reading out dues information and patching the device tree so that from the KL point of view is just as if the burglar was device three capable so that's the idea from the user perspective that's to change now what what exactly is the device three so to help me introduce the device readjust copy pasted a bunch of fragments from the start for embedded poor architecture platform requirements which is actually the I guess the formal documents that describes what is the device tree the syntax and its meaning I found it quite hard to read originally I guess it takes a little bit of experience with the device tree to actually understand what this document is is saying but when you read it again and again and again its start to make sense after a while so what what this document specifies is the concept called the device tree which describes the system Hardware a boot program as I was saying Lodz net into memory and passes that to the client which in our case is 1x and this clients going to use that to know what the hardware available so device tree is a tree data structure as the name suggests with nodes that describe different elements in your system and it's actually being used to describe the hardware that cannot be dynamically detected so we are typically not going to describe USB devices or PCI devices in the device tree because you have mechanisms to enumerate them dynamically but we're going to describe all those platform devices i-square CSPI and that are not dynamically discoverable the basic syntax is actually I would save quite simple but maybe it's just because I became used to it so it's a tree of nodes each node as a name which is here and a unit address which is typically used to well uniquely identify different nodes having the same name and it's normally used for the memory address at which this device is mapped for memory map devices and then each node can have an umber of properties and can have a number of sub nodes and so the device tree syntax does not impose any specific name for the properties any specific value is just a very well simple language and you can use whatever property name you want whatever node name you want how many step nose you want and and so on so the language is actually pretty pretty simple each property can have different types of values there are integral values they are boolean properties they are string properties there are also properties that point to another node at what we call the P handle in the device field language so actually a device can reference another device and we're going to see example a practical example of that you can have child nodes to describe things that you are managing so one typical example is you have a nice crochet controller and then this ice-cream controller allows you to access an ice core C bus and the devices that sit on that bus are going to be child nodes of the I square C controller node I'm going to show such an example some nodes can have labels and labels are the name that's used for P handle so it's a shortcut for pointing to to a specific node so basically the the syntax of the device tree itself is it's a pretty simple the complexity comes from giving it a meaning how did you go from this source representation to binary so on are all the device tree source files at the moment are located in our charm boot GTS so this file is this directory sorry is growing in size quite quickly I made a graph that I could have included but it's it's really growing like like crazy did you in a number of platforms being converted and we basically have two to two files with two different extensions in there we have GTS IO files where DTS I stands for includes and final DTS files so the final DTS files are usually the one that describes board level information and that are the one compiled into DT B's and they generally include one or several DTS I that describe the information from the SOC or the time shared between multiple boards so the idea is that instead of duplicating information if you have one SOC used by twenty boards all the SOC level information is stored in the DTS I which can to be included in several DTS files then we have a tool the device tree compiler or did you see that is located in scripts DGC and that is used to take DTS file and then resolve all the included files and and and turn that into a packed binary format that your group letter and the kennel can actually understand and what it produces is the G GB or divide reblog that is actually what gets manipulated again by the bootloader on your channel and you don't let usually have to worry about building the TB yourself because in this very directory are chongu GTS there is a make file which tells four inch platform so for each arms of architecture in in that case here it's the Marvel platform I've been working on which lists all the GGBS that should be built so generally you have a list sometimes quite huge list of all the boards that are part of this platform and so whenever you're going to build the Kaenel for this platform it's going to build all the GPS for all those boards and it will be your job to select the correct dtb and put that into your bootloader and start your system so now a simple real example of one node of device dream so I've taken one from the amx 28 D GSI so it's SOC level information and here we have a bunch of things so we have a label aur 0 and then the node name it's serial at some address and you dress you need to address here just for well clarity is the same as the address where the registers of this device are available into memory but it's it actually doesn't it's not very important this part here you could have used 0 1 for 24 or anything what's really important is what we have in this property the first property compatible is probably the most important one and the most complex one to understand so I'm going to talk several times about it over this presentation what the EPA PR says is that it defines the programming model for the device well what that means so basically it allows the operating system to identify which driver should be responsible for driving this device so there will be a direct match between a direct connection between the compatible string being chosen and the driver that is going to be bound to this very device then we have the rank property which gives the four memory mapped devices where it's available in memory we have the interrupt number we can have potentially several of them here we have references to DMA channels and that's interesting because as you can see we have this property here as a list of two values and those values are P handles so they are pointing to some other node which actually is going to be the JMA online on this platform and in addition it's it's kind of passing an argument to this P and O in some ways so it's saying a ok for for DMA I'm going to use the MA in giant 8 okay don't know what that mean exactly at the moment and GaN giant 9 and in fact it's gonna be used by the dma engine API to know which GMA channel this specific hardware block is going to use so it's going to be using 8 & 9 and to make lookup easier in the driver it's also associating names to each entry in this list so it's saying Rx is this one and GX is this one so I know it's not necessarily well explicit but that's the way it works and this allows the the channel API is to allow you in the driver to say something like I want to get the RX GMA channel and it's going to find out yeah ok RX is the first one in the list so it's going to be this one and I'm going to give you a reference to this game a channel so it we're a bit weird but that's the way it works and here we have more or less the same thing but we have only one element and it's just saying okay the clock for this device is part of this all node and the argument I'm passing is 45 that's a way of identifying this clock and in this DTS ifile we're saying this device is disabled when status is disabled for a platform device it tells the channel not to probe that device and the reason is that in DTS I D TSI files usually describe all the internal SOC devices but not necessarily all of them are used on a specific board so in the DTS file for a specific board you're going to say this device I'm going to enable it so that it gets probed but if some other like you are is not wired on your specific board you're probably going to leave it disabled because there is no point in probing a device that's not being used on the driver side for this thing the driver know needs to say which devices it is capable of supporting and again that's done using this compatible string mechanism so a bit like in in the old world the platform devices at a name which was used to match with the name of the driver and when they matched the probe function of the platform driver was called here it's when the compatible string is matching with lists of IDs that's inside the driver that the driver prop function is going to be called so whenever you have a platform driver function with the old style we were using this driver name so it had to match between platform device and platform driver and know we have an of' match table which points here to a list of tuples that give a compatible string and some private data and so when the kaenel is going to go through the device tree find all the devices find which driver matches call your prop function if it matches it will find yeah there is a match and it will also allow you to retrieve this private data so this specific driver for example supports two variants of this UART so it supports two compatible strings but it has two different private data so that the driver can adapt to the small differences between these two variations of the hardware block does that make sense yeah and in the prob function which is here the driver can actually fetch that private data by using the Oh F match device so basically it's going to redo the matching for the platform device against the type of the table and give you a pointer to which entry has actually matched this device so you can retrieve the private data and then your driver can act differently depending on on the data that that's available so a sim single driver can handle as many compatible strings as you want and it allows the driver to hide small differences or larger differences between variations of the same or a similar hardware block that's that's the idea of course if the deuce differences are too important then maybe you need to two different drivers that's the usual the usual thing it doesn't change anything here but the single driver can expose and handle multiple compatible strings and act a little bit differently depending on the compatible string that's being passed on the C code point of view there isn't much changed compared to normal platform devices because all of the API s that were used or most of the api's that were used by platform drivers to retrieve resources clocks in our queues memory mapped regions or gaming channels or anything like that all those API is I've gained a device tree support so they are automatically going to do the right thing so for example you are doing platform get Eric you in your driver and in the old world it was going into your platform devised and resources and finding the the req resource no it's finding the in trucks property in the device tree and providing that geo transparently same thing for platform get resource for the memory resource same thing for the clock and same thing for the DMA channels and here you see we have the dues names Rx and TX and they will automatically be mapped to the right entry in the list of DMA channels for that device but of course there are some additional properties that you may add in your device tree that describe more precise the device is connected in your system or give some more specific information so there is an device tree specific API which usually is prefixed by Oh F and one example in this driver is that it's support an additional property called you art as RTS CTS which allows you to tell whether this you art as RTS CTS connected or not - that's abort specific information that you can add in this node here but not in the DTS I file because that's SOC level you would most likely add that in the DTS file which describes the board and the driver gets to know whether this property is set or not by calling Oh F get property and there is a lot of other things you can do with Oh F functions like go through child nodes and there's a bunch of API functions that you can you can use they are usually quite quite simple and so as I was saying and you'll know there is a mechanism that allows you to include device trees into other device trees so ttsi files are included files and J's files are final device trees and as I was saying usually the GSI contain SOC level information and J's files contain board level information but the inclusion is interesting and I think it's it's one of the probably the strongest point of the device tree in my opinion is that inclusion works by actually overlaying the different trees on top of each other so a DTS I file can set a property and it can be overridden by the GS file that is including that DTS on so I'm going to take an example here and that actually comes from the K know so the K know as an am 33 xx DTS I file to describe this G is OC so there's a bunch of nodes and I've taken again the UART example and then there is one d GS file for the the BeagleBone in that case it's a white BeagleBone the original one and as you can see there the gr key of the nodes is exactly the same and it will actually put the second tree overlaid on top of the first one so if there is a new property here which is the case for the pink control names and pink controls your property is going to add them and if a property is present in on boss which is the case for status here of course the including one is going to overwrite the included one so at the end the real GTV that the kennel is going to see is that one so of course the DG B's compile it's kind of the virtual textual representation of that DTD but it's going to have the DD Union of those properties with those one taking precedence over those ones if they are boss present and this works on several levels so for example on the SOC I've worked on we have a family of SOC s they have many things in common but something is different so instead of being just one two GSI and per SOC and then the GS files for the boards we have the tree of duty si files where where we have all the common things for all the SOC is in this GT Si and then progressively you refine the description of the hardware all the way to the board so this is maybe going to add okay this one is a four core variant it is for gigabit interfaces and and ten PCI Express interfaces for example this one is only a dual core with you know maybe two or three internet interfaces the device tree is is describing progressively all those details all the way to the bar which is going to describe how things are wired and the additional elements on the board so let's leave it's really the strong point describing the the hardware progressively with properties overlaying properties from the included device profile now there is the concept of the binding and basically the binding is out to make sense out of the properties as I was saying the device tree is just a language you can give right whatever property you want like foo bar equal blah blah and it's just going to compile fine there is absolutely no at the moment no tool no mechanism to check whether the property you're using actually makes sense and exists so you can write whatever you want in the device tree but of course to make it useful you have to make sense out of a set of properties names property values compatible strings and so on and that's what we call bindings so binding is essentially a specification that says if you want to describe I don't know such or such Ethernet interface you have to use this compatible string at this property with this value and these are the possible values at this other property with these other values and so on and so on so it's actually a binding is actually a specification it's not it's not code of course then it has to be implemented in one or several drivers that may follow the same binding so it has an implementation but the binding is really a specification and so as the EP APR says bindings are our specific types and classes of devices are represented in a device tree and the compatible string is the key to identify which binding applies to a given node in the device tree that's how it works and a binding should be designed to be able to allow the description of all the necessary hardware details that a driver will need to actually you make use of that device and connect it with the other devices around if if needed so the core part of the device tree bindings is actually documentation as a West saying and they are documented in documentation device tree bindings and there's a bunch of a growing set of files in there it's a bit messy the organization in there but it's well you can find your way grep is your friend and basically whenever you add a new driver that introduces a binding in the kennel you are required to write such a documentation usually it's pretty simple because for most devices it's quite simple for some other cases it gets really really crazy because the bindings are very complicated so you have and you have the entire range all between no adays all the new device tree bindings must be reviewed by the device tree maintainer so there is dedicated mailing list so if you're interested in device tree discussions and and and very very lengthy discussion on how to best represent some hardware in the GT and you like to read androids of emails just subscribe to that mailing list there's the team of maintainer that are supposed to review the bindings and and and act them when they are appropriate or give feedback this process is not working really really well at the moment because there are so much development going on an arm the device tree maintainer czar completely overflowed by bindings to review and it's it's too slow so there are ongoing discussion on how to make that process go better there were discussion yesterday in the arm canal mini summit and I think they are going to like relax a little bit the rules here and give bit more freedom to people so that development can go on but up to know the idea was that yeah a binding is something that's and what I'm going to mention that later that is design once and should stay forever which is a very very hard and strict rule and very difficult to have to work with so apparently they are going to relax that a little bit but usually when you yeah when you design it binding it should be a little bit future proof and allow for two to exist for a while so here is an example of device tree binding documentation I took the one of the the example I used before and so basically what it says is well for what type of device it is then what are the required on or optional properties so here it's a you need to have a compatible property you need to have a right property you have two new interrupts property a DNA property and so on for example it for gets clocks because clocks is a property that basically you can use in whatever device you want but it should probably mention it so the documentation is not completely accurate here and then usually gives an example and any other information that can be that can be useful so that's what we we have and that's wet and divide stream binding maintainer typically review that's what's important then if the implementation is somewhat broken we can fix Li let fix it later but the binding is normally an interface that is not supposed to change so we have to be able to careful on how its design now that we've looked at one single node let's try to have another look at the device tree in its entirety at the root of the device tree so which is supposed to describe the entire hardware platform we have a bunch of nodes that are either mandatory or optional but that are described in the EPA PR specification and then you can add more nodes and actually do more nodes that you're going to an ad are the most important ones so amongst the the one specified in the specification are the CPUs memory choose an analysis node and there are a bunch of others but those ones are the main demands most common ones so the cpu nodes is going to have sub nodes describing each CPU in a system like whether you have a cortex a8 or codecs a nine or some other thing and sometimes some additional properties of each CPU the memory node is mainly used to define where the memory is located the physical memory and what what's its size is the chosen node is according to the specification a place where a parameters chosen or defined by the system framer at due time can be stored at the moment it's mainly used to pass the cannot come online so if the bootloader is very capable it's good it's going to take your device three blog and it's going to patch it or I would say update it by inserting your cannot come online in to the GTB and the cam will find it at this place then we have analysis node which contains shortcuts to send in nodes that are needed for some specific binding bindings that I want to really dive into the details here and then the most important sections are going to be the description of the bases in the SOC and onboard devices so I've taken the example of the AMX 28 platform again and as you can see we have the root of the tree here then we have those common nodes specified by the EP a PR specification and then we have sub nodes other sub nodes here describing various classes on this platform so depending on our your SOC is organized and how the interconnects are connected together which device sits on which piece you can have as many nodes as you want sub nodes if these buses are are like sub buses on some other platforms it's much simpler than that you just have one single top-level node that call SOC and you have all the platform devices in there it all depends it's left to the the freedom of is left to the person like designing the the description of this particular platform so here it matches the hardware so without going into the details it has like two I would say like more or less slow paths and one high speed bus the high speed bus HB is here and as like to memory and so even add that kind of things and then the AP pH and a PBX are other buses that are like slower speed devices so that's just the way the SOC is organized but they model that into the device tree as we can see here and so with induced nodes they're going to be all the devices that you see over here so in aah be working AB for example the Ethernet devices and then in AP pH we're going to have I don't know the interrupt controller for example and then and then the SS b0ss p1 and so on and so on so it's really as I try to ensure that you could see the direct connection between the disk emetics the well the block diagram and the device tree representation here and then the ball at the board level in the ggs file basically since it's overlaid we have the same organization and so we can add more information about which you are going to enable which ssp device want to enable and and so on and so on and we can also add more nodes that describe board level information such as some complex or LEDs or backlight information that kind of things so that's the overall organization and of course depending on the SOC family you're using the the our key of path is going to be different so the exact hierarchy is going to be slightly different but the idea is always usually the same one thing that's important here is the top-level compatible string so just like you have compatible strings in nodes identifying devices you have one at the top of the device tree that's actually going to identify the platform and here as you can see we have two compatible strings and you can actually give as many compatible strings as you want and they should be given from the Mars most precise first to the least precise last and so that the match is done by trying to match first finding the driver or the keno element responsible for driving this element of the device tree that is the most specific possible so here we are having one compatible string that identifies the board it's the evaluation board for the IMX twenty eight so that's I mix twenty eight evk and then this platform is also compatible with IX twenty eight because it has this SOC and this top-level compatible property is the one that is going to be used to find which server architecture you're actually running so in the past we had use machine start the machine end section that we're identifying each board nowadays we have GT machine start and structures that basically have more or less the same thing but what they have in addition is a DT compact field which points to a list of compatible string that this platform is supporting so with the advent of multi-platform kernels you can have within the same channel image the support for OMAP s you see for marvel SOC is for free scale a Susie's and of course it's it's going to have to design which platform is going to be is being booted at the moment and the way it does that is it looks at this top level compatible string finds which machine description structure as this compatible string and if there is a match then it's going to use all the other hooks that are inside this structure to like start the timer the interrupt controller and and register all the devices then it's exactly as it was before but that's the way the connection is made this compatible string can also used within c code to test if the machine is the one you're interested in to do like some some quirks and then different changes that may be needed for example it was used a lot in the transition from no device tree to device tree because not all drivers at device tree bindings because they were in discussion so a lot of c code was being kept around and if the machine being booted was that one then we would continue to register manually using c some platform devices that could not yet be described in the device tree so it's progressively being less and less used on on most forms as we have more and more bindings but it's still one possibility so here we're for example matching and that the machine is compatible with IMX 28 evk which is going to be true because that platform is actually the one we're looking at does that make sense this matching so that's the way yeah matching with the sub architecture code is being made with the device tree inside the bus so inside of each of those elements we're going to have a compatible string that defines with what this bus is compatible what entity in the kennel is going to end all that that bus if it's a nice cursive bus then most likely the compatible string is going to identify and a squishy controller driver if it's an SPI bus then most likely the compatible string is going to refer to an SPI controller driver but there is a special value simple bus that's used to say okay that's just a memory mapped bus and the driver the kennel should actually go through the sub nodes of this bus and register each of them as platform devices so many of the associate are using just a simple bus because they don't need any special bus handling but some other SOC is for example including the marbella one they have a bust it has some crazy configuration possibilities and so we have a special compatible property and a special bus driver that goes through the sub nodes and does some thank-you things with them so it's possible to have some specific bus driver but most of the platform do simple bus basically go through the sub nodes register platform devices easy inside this bus you're also going to have other properties and the address cells and size cells they are going to say in the right property how many 32 bits values because a cell is a 32-bit value are going to be needed to encode addresses and size for the i/o memory region so if I take an example here and this APB bus is a simple bus so there's no special driver in the kennel except something that will register platform devices and it needs one cell to encode addresses and one cell to encode size and that's why we have only to say here because we have one cell for the address and one cell for the signs so there's a relation between how many values you put in whoops in rag and dues two informations there can also be a range property here which describes address translations between the this child bus and the parent bus so if they are not in the same address space you can describe okay all the addresses here should be transformed according to some range so some transformation you can set risible from address X to Y in the child bus it's in fact address a to be in the parent bus so for most buses you don't care about that because it's not necessarily useful but some buses have thank you things that require these translations some of the SOC s use that to make the addresses here a little bit simpler for example if all your devices are there register within a specific area of memory instead of a kind' encoding this base address over and over again in each device you can just put a translation here that says okay everything that's at a zero zero zero zero are actually my own devices so whenever an address zero is used in my child bus I can translate that into address eight zero zero zero in the parent bus so in the child nodes instead of writing this you could just write o X to 2000 and that would be translated automatically to Oh X eight zero zero two thousand so that's what we can do with ranges when the property is empty like it is there it just means its identity it's there is an identity mapping between the child bus and the parameters that are in the same address space so there's no translation going on and the Reg property in the bus is completely useless it's just here as an information of our like large is the address space covered by this bus but it's not use at all and there are other platforms where it's not available it's not it's not used because it's well just an information thing here is another example with a nice query bus so typically this is the the bus of the SOC and one of the nodes that could be here could be a nice square see controller so what you see here is actually here inside this node so it's one of the sub nodes of our SOC bus so one of the devices on our SOC bus and it's nice query controller and so if it's since it's a controller it's a device like any other so it has a compatible string it has some registers control a there's some interrupts maybe DMA channels many other clocks and other informations but this device being a controller it drives a bus and so it's you need to describe the devices that sit on that bus because it's not a dynamically enumerable bus and so it's in situ bus we're going to add again address cells size cells and in the I Square SeaWorld the the binding that has been chosen is that the reg property of I square C devices is used to give the slave address of the device on the ice core C bus and that's the only information needed so you don't need the size you just need one address so address cells is one size cells is zero and as you can see in the child nodes each of them describing one specific device on the I square C bus the rag property is used to give the child the solid di screw C slave address so depending on where you are ranked means either the memory location of the device or it might mean the I square C slave address or it might mean the chip select used on an SPI or it might mean complain is something else so the meaning of a given property can only be interpreted relatively to where it's located in in the device tree and which binding applies to this specific node generally they try to make to keep things that make sense I believe that makes sense because reg is kind of where the thing is so it makes sense to you to use that but it can be a little bit confusing at times to have the same property name being used to actually give a different type of value and so for each of those chain notes we again I have a compatible string that's going to identify the driver and then a bunch of other information that's are needed for this the description of this specific piece of hardware so here we have like pointers to regulators that are needed by this device here we have another property that probably gives a no page size of some I square C EEPROM or our flash or whatever that are going to be used by the corresponding driver so this is part so for this we have one binding for this we have one binding for this we have one binding so each device as its associated device three binding which is the specification giving the meaning of those properties entropy in Ling is interesting and we have a number of properties related to in trip handling one of them is in trip controller it's just a boolean property if it's there it means that the current node is an interrupt controller it can receive interrupt and interrupt cells is a property that indicates number of cells that are needed in the interrupt field to encode an interrupt number sometimes it's just one just in trip number sometimes it's more complicated and I'm going to show an example and we also have a property called in trip parent which is a PN bone so it's a pointer which tells for this specific device what is the interrupt controller that is receiving the in trips generated by this device so in addition to saying which interrupt number is being fired you also need to say which interrupt controller is receiving this because on some platforms you may have multiple and trip controllers and often there is a top-level inter parent definition for the main interrupt controller so that you don't have to repeat that over and over again in all the child all the device nodes so if you have like one main interrupt controller and you give intro parent at the top and it will consider that all devices are using that except if you explicitly override that with an interrupt parents property in the device node so to make that more realistic let's see an example again IMX 28 so the interrupt controller is just one device like any other so it's described in the verbs in the AP pH bus as device compatible string it has some registers but it has also these two additional properties which says I'm an interim controller and to describe in troop so I will be late but I guess it's lunch so it can probably extend all the bits it's very wise from the program community to always put me before lunch breaks because I always have like too many slides and so the intro this is saying we need one cell to encode interrupt numbers and here as we can see we have one interrupt number so we're it's matching the fact that we need only one cell and the reason why the kennel is going to understand that dudes in troops are going to this in trip controller is because we have this top-level interrupt parent so this top-level inter parent property could have been here as well and then duplicate it in all the other devices but just to make it shorter it was moved at the top of the device tree because the logic of this binding is that whenever you don't find an interrupt parent property you just go in the parent bus and if it's not there in the parent bus and then if it's not there in the parent birth parent but and so on and so on until you find what is the intro parent for this bus let's look at a more complicated example and that's a Tegra 20 platform just pick a random one so it has a nice query controller which triggers an interrupt to the main interrupt controller it has a GPIO block which triggers in trip to this interpreting corner and it has a on some specific board so that's the blue part is the SOC and the gray part is the board on the board you have an audio codec which sits on the I square C bus so it's controlled there and it also has an API o interrupt that EGP align that's used for signaling and interrupts so it goes to the GPIO controller here and the code to do that is actually a interesting and we're going to being a look at that so at the SOC level what do we have we have the interrupt controller the I square C controller and the GPIO controller the interrupt controller is just a normal device like any other it's marked as interrupt controller but that we can see here the number of cells is different it's it's a gig so it has a different way of expressing interrupts I'm not going into the details but instead of recording only one information it needs three informations and and that's something we can see here so the I squared C controller interrupts goes to the main interrupt controller because the intro parent here is pointing to this node using the P&L and therefore if it wants to describe an interrupt it should have three sales which it as here and as you can see some of the values are not just members because nowadays most of the device tree inclusion is resolved using the C preprocessor so we can use defines to replace magic values it's something fairly recent like maybe two or three key non-religious ago something like that before that we just add like magic numbers all over the place now we have this possibility of using macros which is quite nice and we have another device here the GPIO a block and it's triggering a number of in trips to the main interrupt controller and if we look now at the board the board level and what the board level is going to do is for the I Square C controller is just going to enable it and it's going to describe which devices are on this Chi square C bus so what we have on is I square C bus is an audio codec which is here we have a compatible string the I square C slave address and what's important in the discussion here is the interrupt parent and interest property so this the interrupt that is triggered by this audio codec is not going to the main interrupt controller so we are overriding the intro parent property saying the interrupt of this device is going to this other interrupt controller which is actually the GPIO Bank and this is possible because the GPIO bank is saying a I'm an interrupt controller actually and if you want to describe an interrupt that's pointing to me you need two cells in the intro property that's what we have here in trip sales and that's actually exactly what it is doing it's giving like one cell here and another cell so it's basically giving which GPIO is used and whether it's like level triggered F to trigger that kind of additional information so that's the way you can you read things in the device tree so I know it's quite weird at the beginning I'm you're standing that okay this needs to sales because this interrupt is going to this interrupt controller and this intro controller is saying that to express an intro that's pointing to me we need two cells but that's the way things are organized I have two main examples but so another example is clocks so here is a very partial view of the clock tree on some Marvel s ucs so we have core clocks and we have CPU clocks and we have gate able clocks for the various devices and therefore you if you want to end all that in the Kindle you have drivers for all these different clocks some of them can be changed some of them can be gated or can change there right whatever and therefore at the SOC level what we did is we created drivers for all of these clocks so we have one driver for the core clocks here and we have one driver for the CPU clocks and then we have a one driver for the gate able clocks so it's actually pointing to a bunch of registers that allow us to read the current rate maybe turn off the clock or Tanny done or do manipulation of the clocks and then we need to allow devices to reference those clocks and so here are a bunch of examples of devices that reference their clock for example a CPU can reference a clock so that there is a proper binding for clocks consumer that's valid for all devices you should use a clocks equal property and give one or several clocks that this device requires so this hour each CPU is using clock and here we have a P&L and then an argument and we're finding the same logic as before this is pointing to CPU CLK CPU CLK is here and it's saying clock sales equal one so whenever you want to specify a clock that's managed by the driver you shouldn't just point to this node but you should give an additional information and this information is zero and the binding defines what this zero or one or two means and in our binding it means which clock you're actually interested in so maybe on a november cpu clock zero is going to be that one core clock two is going to be that one gate a table clock 23 is going to be that one so that's a way of encoding information in the device tree of course that's just a choice of the binding some of their people do it differently but that's that's one of the possibility of representing clocks we have another example here the timer is actually using can use two different clocks either a fixed reference clock or a clock provided by the SOC and we're using just like DMAs channels we have this mechanism clock names which gives a name to the first entry and under the name to the second entry so that in the driver code you can say I want to get the NBC lk clock or I want to get the fixed lock and the driver doesn't know exactly which clock is that it just knows that it is like two clocks that and it knows their names but it doesn't know exactly to which clocks it's going to end up pointing to here we have another device it's the USB controller and it's pointing to a gate able clocks and because this K table clock driver also has clock cells equal one when you make clock specifier you need to pass an initial information and here we also have the description of the clock tree because do is gay table clock and cpu clock as you can see they also by themselves are a clock reference to a core clock core clock so that describing progressively the clock tree so there is really the end that's why I try to include like skin a block diagram of your hardware next to the device tree description is that there's really a one-to-one mapping between the two things and the final example that I have is the blink control binding and so the pin control subsystem allows to manage pin maxing and so whenever a device needs some pins to be configured in some way it needs to interact with the the pin control subsystem and just like clocks have a common binding that's used in all devices and on the consumer side the pin control subsystem as the consumer binding that can be used by all devices and this binding to make it short basically consists in two properties at pin control - and the number and so typically just zero except you have some more complex case and this is going to give a list of pin control configuration that you need for this device to operate properly and then it has a pin control names property which is a bit like clock names and Jamie names is going to give names to each of the state because the pin control 0 pin control one bit control to allows you to give different states of the device for example when it's active or which when it's idle or in suspend you may want to max the pins in a different different way to save power and so you can give different names to these different states but in the general case if you don't have to too crazy for management going on and you can just have one pin control 0 property that gives a list of pin configuration and name that default and without doing any change in your driver whenever your device is going to be probed it's part of the platform driver logic it's going to notice oh there is a default pin control configuration in there and it's going to ask the pin control subsystem please can figure whatever pins that are described induce configuration in the proper state and that's being done automatically so that's the consumer side binding and of course there is a provider side binding and the provider side binding just like the clock provider bindings are specific to each pin control driver so that can be some confusing at times that's our pin control drivers which actually control the configuration of pins described which configurations are available and some drivers have decided to give just register and basically values with this in these informations are identifying one pin and in which state it should be configured so it's kind of black magic values some other drivers I've decided to make things a little bit more explicit and by listing the name of the pins and the function they should be mixed in but what's important is that in bus cases there is a name given to this configuration and that's the name you find here as using the P Andals and so what this is going to do when this device is going to be probed since that's the default state it's going to ask do pin control subsystem to use this configuration so the pin control driver is going to look at that one and max do spins in juice configuration so again that's really closely tied to the hardware and describing all the different mixing possibilities and allowing board files to say ok on this specific board the way the MMC is wired it that way or the way I don't know that you are is wired it that way and so the final notes I have are more general information about the GT so it's what the first thing is that it's really a hardware description language so it should describe the hardware layout and how it works but it's not there to describe the hardware the configuration of the system so for example a very simple example I have is you can describe in the device tree whether a device supports DMA or not because that's a property of the hardware my device is DMA capable or it is not but you cannot describe or you should not in the describe whether you want to use DMA or not because whether you want to use DNA or not is not the property of the hardware it's just how you want the system to be configured but it's not a representative representation of what the hardware is and this is sometimes causing some issues because in the old world we had to use platform devices with platform data and people are just creating the device rebinding by each member of the platform data field is going to be a property in the device tree this is more or less true for some of the properties that are actually describing the hardware but for some of the other properties it's not necessarily correct to turn it into a device tree property because it's not describing hardware but just a choice on the usage of the hardware and that's normally not part of the device tree the big question being where do you encode it information and there isn't much of generic ends word with that question and fun Hadley that's the one of the issue that people are facing when moving to two device tree so it's it's really a pair case-by-case discussion on how to solve that particular problem out to express a specific configuration but normally the device tree is not here for exposing these configuration decisions and DT bindings as an API I guess most of the crowd is reading lwn or if you're if you don't you should and so the device tree idea is that its OS independent so normally or other operating system and then Linux should be able to use the device tree as a representation of the hardware which also explains why configuration choices should not be part of the device dream and the original idea is that hardware manufacturers could like write a device tree flash it into a device and then let the user install whatever operating system it wants and have it like discover what hardware is available that's the theory then there is real life going on if you want this to actually work it means that whenever you create a new binding one of those specification and you start shipping products that use this binding then you have to keep them around forever and keep the compatibility forever or otherwise some other project we no longer work with a more recent kaenel version and this is hard to achieve because the hardware the way of describing hardware is quite complicated the number of hardware platform is very large and the number of these platforms is enormous and going on at a crazy crazy rate and there's not enough manpower to review all those bindings and take good decisions in a timely fashion and but until now the the position of the device tree and we say gurus was that it should be a stable API and that maybe someday the device tree files would be taken out of the kennel and and really have the two things separated but at the arm in estimates yesterday there was discussion around that because the device tree bindings stability is really hard to achieve and it's cause it's slowing down development quite significantly because you have to make the perfect choice from the first time and that's not really the way I believe Linux has been developed over time usually like make a simple solution to solve the problem that you have right now and then later on when you have a better understanding of the problem like how your hardware is working or you're seeing the new SOC line or the new devices then you have a better view of what's going on then you can improve the solution to cover more cases and more cases and progressively iterate and make things better but with device tree bindings if you want stability then you have to be right on the first time and that's really hard and kind of breaking the idea that's well let's solve the problem we have right now and make you better later so it's it's it's it's been a hard I mean I've been involved in some device tree bindings discussions where you have to plan everything in advance like how things are going to end up and now things are going to work even though you don't really understand what the hardware really well yet and so that's that's complicated and so the discussions I'm not sure exactly what the conclusion was and what is being presented today at the Kaenel summit but my feeling is that we've reached an inflection points where even the duty gurus are starting to realize that it may not be so easy to make it a stable API and that at least for some time we may have to relax the rules a little bit and let some by some non stable bindings flow in and let people get better understanding of how it works and progressively get the the most important bindings in place and so probably the rules will change a little bit and know it's no longer going to be a completely street kaenel ABI so if it's not strict and it's not keen on API at all so I'm not sure what the final conclusion is going to be hopefully lwn is going to make a write-up about that after the keynote summit but that's that's an area that's still yeah in movement so some some guidelines some access to two things I have in mind when writing bindings this is designing and the compatible string is important it's really important to use a precise compatible string rather than vague one so what I'm mentioning is that a number of people are doing okay my device is being used like in the variant T 30 20 and T 30 30 of my I don't know SOC line for example so I'm going to call the compatible string through T 3 X X because it covers 320 and 330 but then T 33 40 comes out and in fact they changed the way they did Hardware block works and it's no longer compatible the programming model of the device is not the same the registers have changed in trips have changed some things have changed and it's no longer compatible so now you have a compatible string T 3 xx that no longer makes any sense because it doesn't reflect what T 340 is capable of so what you should instead do is use G 320 and potentially use 4320 and T 330 if they are exactly compatible and they're the same IP block and they have explodes a no difference then you can just use the same compatible string that's precise on the device three of bus of deuce platforms and then when T 340 comes out then you have maybe another driver or in the same driver you have another compatible string and some specific handling that allows you to amend all the differences so that's one thing and the other I believe recommendation I would have is to not incur too much hardware details in the device tree and some people add the vision that the device tree should allow you to adapt the Kinal to a new way so see without making any changes in the kennel code which I believe is completely crazy because there's no way of knowing how the next SOC is going to be different from the previous ones so instead I believe that but it's it's something that it's more or less a philosophical problem but I believe that it's probably best to have most of the hardware differences being handled in even by the driver and then have different compatible strings to identify different variants of the same IP block of the almost similar IP block between variants of your SOC family and the reason is that if you have too much hardware details in the device tree to try to make the driver more generic usually the generosity is in the wrong direction so when you actually have the next hardware oh whoops I didn't plan it properly and it doesn't work out properly and the other reason is that it makes the binding more complex and since normally binding are supposed to be stable the more properties you add into it the harder it is to keep something stable so keep the binding simple is I believe one of the way of making sure that you won't have to break them too many times some future directions more Duty bindings for various subsystems subsystems such as DRM or audio for examples are still lacking device because they are pretty complex of system that make various devices interact between each other so that's still ongoing a tool to validate device trees again bindings as I was saying the device tree compiler only makes syntax checks like if you have property equal and then codes and then a string and then make sure it's syntactically correct but if you wish or make a typo in the name of your property it's not going to notice if you make I know any other typos or wrong usage of a binding it's not going to notice so there's no type checking there's no no nothing so in some way it's all bit well strange because we had seen in the past that we're doing type checking and compile time checks and everything all nicely though we have a language that doesn't do that anymore but okay that's the way it is and so there are some tools that are being discussed to actually instead of writing like a document for the binding something that would be usable not only by humans but also programs and that we describe okay a binding expect this and that property with these values and so on and then a tool would allow to make validations on the device tree against the bindings and make sure you're not using a property that doesn't exist or a value that isn't possible and that kind of additional check so that's being discussed another thing that is being like being discussed for a long time is supposedly the device tree is huddled representation so it shouldn't be part of the candle but something outside but it's it's probably going to cause a huge number of compatibility issues like I don't know how would you synchronize the release schedules of these two entities and if you use all device tree with a new candle or the opposite what's going to happen and so on so it's all part of the stable API discussion and yeah I think things are moving in this this area and people are realizing it may not be as simple as they thought it would be originally some references the slides of course will be available on the unknown on the website but the most important references is the EP a PR document but again as I said it's pretty hard to get started with that document there is a divine street org wiki that hasn't been updated in years probably so it's not so useful and and then you have the device three documentation and the bindings in the keynote sources and in the device for emailing is that's probably the best starting points to continue looking to that I know I'm horribly late if there are questions before lunch I'll be happy to take some of them yes sir you can I think with DTC never used that myself but you can disassemble a device tree that is you can take the binary presentation and get more or less the textual representation I think some of the information are are kind of lost in the process like maybe the labels of the know of the nodes are lost because they're not useful at at runtime but you can disassemble a device trip maybe you can okay so attend a listen yeah so yeah you can you can you can do that hmm yeah of course if you have a macro it's lost like yeah another question maybe yep yeah the device tree as a magic number at the start and when it's you're using the appended DTB mechanism it's it's this it's looking at this magic number and same thing if you're using a duty capable bootloader it's looking at this magic which I don't remember what it is and to find out whether it's a tags or a device free blob yep please I don't know maybe so the question is is there any way of authenticating the device free blob like making sure it hasn't been corrupted I don't know I have no idea whether there's a CRC or anything like that in the device tree blob maybe someone else can comment on that but I don't know yep has there been any discussion well you have some inherent versioning capabilities because you can change the compatible string and if the kennel is still capable of handling the old compatible string and understand it as it was before and then understand a new compatible string and understand that the correct binding that corresponds to this new compatible string then you have some some kind of versioning capabilities in here because you have like two compatible strings that identifies two different bindings the issue is that at least I believe the compatible string normally tells which hardware you have but normally for a given piece of hardware you should have one compatible string or regardless of whether the binding is evolving but that's not something that has been like really discussed I believe and there's beyond that there's no versioning mechanism in place I think there was some discussion that we narrow connect about like having some properties with a version of the binding something like that but it didn't went further than just like random shots like that so at the moment at the moment the the answer of the device three people about that is just if the binding changes well first don't do it but it really needs to change then the way to change it is you change the compatible string and in your driver you keep the code to end all bus the old one and the new one which obviously means a lot of crap code in all the drivers everywhere but it's that's something they don't seem to really care about well last question I guess think that's a good question I have no idea whether does the proc is there a proc entry with the FD T or something yeah Antwerp on the audience yes it's a binary format that you get in don't get to think in the front I mean totally the text version not sure how it's working exactly but maybe it's just I don't see how it can be dissonant are you okay yeah true so the C workgroup of the Linux Foundation is intensely interested in fixing some of the problems particularly the lack of documentation and so hopefully we'll be able to announce some stuff shortly about some more resources to help device tree authors okay so on that I'm gonna thank you and we shall good lunch late certainly but in support
Info
Channel: The Linux Foundation
Views: 81,217
Rating: 4.8907561 out of 5
Keywords: Linux events, tech events, open source events, Linux conferences, open source conferences, tech conferences, Linux Embedded, ELCE
Id: m_NyYEBxfn8
Channel Id: undefined
Length: 72min 41sec (4361 seconds)
Published: Fri Nov 15 2013
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.