Device Tree 101 5:00 PM UTC+1 session

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and good morning good afternoon and good evening depending on where you live on earth and thanks a lot for being on board for this divine street 101 webinar my name is thomas and i'm i'm very happy to have you for the next hour and a half or two hours talking about this history i'd like to first introduce myself i am thomas pettazzoni the cto at woodland which i joined in 2008 as bootleg in addition to being the cto i am also one of the members of the engineering team acting as an embedded linux and linux kernel engineer in this position i have been the author of the device tree for dummies talk in 2013 2014 and in fact this webinar today is an update on this talk in an extended version it's like twice longer with more up-to-date information and more detailed information i am also one of the co-maintainers of build root an embedded linux build system and i have contributed over 900 patches to the official linux kernel and it is based on this knowledge of linux kindle contribution that i've learned a number of things about the device 3 which i will be sharing with you today i am also a member of the program committee for the embedded linux conference both us and europe finally i am based in toulouse in the south west of france today we will be talking about different topics around the device stream i'll start by introducing bootleg then the stm32mp1 family of processors which we will be using as uh illustrations for the different device three examples we'll talk about why we have the device tree what is the base syntax of the device tree the concept of device tree inheritance device respects and bindings the interaction between device trees and linux kernel drivers and we'll have a significant discussion around the device three properties and a number of examples as well and finally we'll close with a q a section and you'll be able to ask questions on the chat and i'll answer as many questions as i can so first let me introduce briefly brooklyn we have been in business since 2004 and we are an emba consulting company specialized in embedded linux engineering our team is based in france but we have customers worldwide we make less of 20 of our revenue in france everything else is in the european union or even elsewhere us canada and other parts of the world as well our expertise is highly focused and recognized as our focus is exclusively on embedded linux low-level development so we do linux kindle development boot layer development and embedded linux system integration mainly with build systems such as yokto or build root our activities are training services which are approximately 20 of our revenue and everything else our engineering projects where we help our customers bring embedded linux to their platforms which is the rest of our revenue approximately eighty percent so first let's talk briefly about our training offering as of today we have six different training courses that are available uh first course that introduces to embitter linux system development to understand the different components in an embedded linux system and how they work together a second course about linux kindle development how to write device drivers in the kennel a third course about yokto how to use yokto to build an embedded linux system and integrate the different components together a fourth course about build root which is following the same idea as the yocto project course but applied to an alternative tool bill root for building an embedded linux system we have a course dedicated to the linux graphics tag to understand from the hardware all the way up to user space the different components that make up the graphics stack of a linux system and finally we have a new course that we announced last week on embedded linux boot time optimization to learn tips and tricks to optimize and reduce the boot time of embedded linux systems all of those courses are available on site when the travel conditions make that possible or currently also online so that we can continue deliver those courses to the companies and engineers who need that so why would you choose the training courses from bootleg we have a few things that make them quite unique the first and probably most important thing that makes them quite unique is the fact that all our training materials are fully available we deliver them and distribute them under an open source license the creative commons by sa license which allows everybody to read and use and reuse those training materials freely it allows everybody to verify in detail the contents of the course before maybe purchasing our course but it also allows everybody without purchasing our course to access all this knowledge so it shows our commitment at brooklyn to knowledge sharing and again this is quite unique in the training industry second our course are delivered by experienced trainers contribute to a number of training companies where the trainers are only trainers at brooklyn the trainers are all also engineers they spend the vast majority of their time at our offices working for our customers on real engineering projects and only from time to time they deliver training courses to our customers which ensure that they have an up-to-date and in-field experience finally our courses are recognized worldwide we have delivered hundreds of sessions to many customers all around the world to thousands of engineers for the past 15 years in addition to those training services we also have engineering services where our main activities are around the development and delivery of complete board support packages for our customers our customers come up with some kind of custom hardware platform we port a bootloader we port the linux keynote we write canelon drivers when necessary we do the system integration with yokto and build root we might work on boot time optimization integration of secure boot mechanisms and and others in addition to doing this linux board support package um development and delivery we are also able to work on upstreaming the appropriate changes to the relevant open source communities the linux kernel u-boot yokto bilbrut and others and this allows to offer our customers a long-term maintenance of their bsps in addition to that we offer consulting and technical support on this really low level part of the software stack bootloader kennel and build systems our customers are mainly silicon vendors who contract us to develop hardware support in ubuds or linux for their hardware products and usually also as contractors to upstream that support so that it is available directly in the official versions of linux and ubud for everyone to use and the second category of our customers are embedded system makers who produce embedded systems that go in the wild in the healthcare industry transportation industry in the home automation industry and many others and for those customers we deliver complete bsps we develop custom drivers debug optimize and provide our consulting services brooklyn is not only a company delivering services to its customers it is also a very strong open source contributor we are actually the 20th contributing company worldwide to the linux kernel and you can see on the right of that slide the list of companies who contribute to linux by number of comments since linux kennel the linux keynote started using git to manage the the the changes in the source code and with over 7600 patches we are indeed the 20th contributing company in the world not only we contribute patches but we also participate in having some of our engineers be maintainers of several subsystems of the kennel we are maintainers of the i3c subsystem the rtc subsystem the mtd subsystem and several platform support code as well we are a key contributor to build roots i am myself the co-maintainer of this project and collectively at bootleg we have contributed over 5000 patches to this project over the past 10-12 years we contribute also to yocto to bear blocks to the next test project to uboot and a few other open source projects as well as mentioned earlier our training materials are all freely available and we also give numerous talks or webinars like this one freely at different conferences to share technical knowledge technical content so without this with this introduction of bootlendon we'd like not to move to the introduction of the stm32mp1 platform the reason why we're taking this as an example is because this webinar is organized today in partnership with st so thanks a lot st for supporting this this event and that's the reason why we will use this specific platform to illustrate the different uh concepts of the device tree that we will cover throughout this discussion st originally has a very strong background in mcu microcontrollers they have a wide portfolio of products they are very popular but in 2019 they decided to extend their offering of microcontrollers with microprocessors what they call mpus and the first family that they have they started in in 2019 is called the stm32mp1 family of processors it is a family of system-on-chip based on arm of course that provides a wide range of functionality the one that you see for renault on the slide the stm32mp157f is kind of the higher end variant of that family you can see on the block diagram it is a dual a7 core at 800 megahertz it also has a cortex m4 at 200 megahertz so that you can run real-time applications side-by-side with the linux system running on the dual a7 it has a gpu it has a wide range of ip blocks for connectivity for display over rgb interface or dsi a camera interface gigabit ethernet hdmi can spi i square c mmc and audio interfaces adcs dacs pwm and security features so plenty of functionality available in this in this soc this system on ship as i mentioned is part of a wider family the stm32mp1 series and having an understanding of this family is quite important to understand later in our discussion the organization of device tree files so we have three different variants of the soc the 151 the 153 and the 157 um so the 151 is the the lowest end in the series it has only a single a7 it has no gpu no can interface and no dsi display interface then the 153 on top of that brings two cores to a7 and brings two can interfaces on top of that the 157 brings the gpu and the dsi display interface then within each variant you have the a and the c which the a as doesn't have any security mechanism so it doesn't have hardware crypto support or secure boot support while the c has the security mechanisms so that's true for the 51 53 and 57 and then as you can see again on the table there for the variants d and f which are the ones clocked at eight hundred megahertz so there there's a burned at 650 megahertz for the uh clock frequency of the cortex a7 and an 800 megahertz variant for the clock frequency of the cortex a7 so that really gives a range of choices depending on the applications and the performance level and the features that you need for your project based on this soc st has put together a number of different evaluation kits and especially two discovery kits the discovery kit 1 and discovery kit 2 which are relatively inexpensive evaluation boards for these socs so let's start with the dk1 on the left side of the slide this dk1 is using the 157a soc which is almost the highest n1 it's just that it doesn't have the security aspect it has half a gigabyte of ddr it has a microsd slot gigabit ethernet usbc usb a leds buttons hdmi audio a dsi connector for a display and on the back side it has arduino raspberry pi shield compatible gpio connector so you can plug extra expansion boards that are widely available for other families of evaluation boards like arduinos and raspberry pi's on the right side you have the discovery kit 2 which is based on the same soc just the secure variant of it so it has the the crypto engines and secure boot capabilities overall it has the same capabilities as the dk1 but it adds a wi-fi bluetooth chip and it adds a display and touchscreen as you can see on the picture so if we put that on a block diagram uh of course the partial block diagram it definitely doesn't show all of the features but i think it's important to to keep in mind this this view of block diagrams that this is important to understand then the concept of device tree we have at the center of the picture the system-on-chip itself the stm32mp157c which includes a number of hardware blocks gpio controllers ethernet mags mmc controllers iscsi controllers and many other hardware blocks all around the cpu cores of course then this soc is put on a board which has a number of components such as ddr memory a display panel a poor management ic a wi-fi bluetooth chip micro sd slot an internet file a touchscreen controller and others which are represented in green on that picture so that is important to keep this view in mind for the rest of our discussion some hardware buses provide discoverability mechanisms if you have already used or worked with usb or pci perhaps you have realized that when you plug a usb webcam into your system you don't need to tell your system anything about that webcam it is it is able to automatically detect that a new device has been plugged into the system and then enumerate that device and discover what this device is and therefore identify a driver that would make sense to manage that device this is possible because usb and pci both include discoverability and enumerability mechanisms so the cpu that has a usb controller or a pci controller can use the capabilities of the pci and usb buses to query which devices are connected on the bus and what their identifiers are so typically in the usb and pci world each device that is produced has a unique vendor id and product id which allows to uniquely identify okay this is this specific model of that webcam and therefore find a corresponding driver for it so that's very nice and on intel x86 platforms a significant amount of the peripherals on the system are indeed connected over pci and usb but there are also many hardware buses that do not provide such dynamic discoverability mechanisms for example ice core c spi one wire or memory mapped buses and devices typically don't offer such discovery mechanism so one needs to know ahead of time what are connected to those buses if you have a nice course bus with two or three components connected to it you cannot ask on the bus who is there and who you are you have to know that by design and how those components are connected to the rest of the system and it turns out embedded systems make extensive use of such buses that don't support dynamic enumeration so the description of non-discover hardware is what will allow the operating system or bootloader to know things like okay my system is composed of a system-on-chip which itself contains two cortex a7 cpu cars it also contains maybe two uart controllers which are memory mapped and the first one as it's registered at that specific address and it is using this interrupt line of that interrupt controller and it has another ui controller at this other address and using this other interrupt line of that interrupt controller but it also has a three i square c controllers and maybe i don't know spi controllers mmc controllers display controllers and so on and in addition to knowing what is inside the system on chip we also need to test the operating system or bootloader what is on our board around the system on chip maybe i have an audio codec that is on some ice cream c bus so it is connected on a given bus at the given ice core syslive address it is connected to a given audio interface of the system on chip maybe it has a reset signal that is connected to some gpio of our system on chip and all this uh connection and integration of our audio codec with the rest of the system needs to be described somewhere so that the operating system or bootloader knows the topology of our hardware all those details simply cannot be guessed or figured out at runtime at boot time by the operating system or bootloader so how do we provide this information about non-discovery hardware to our operating system or bootloader the first possibility is to simply hard code it and code it directly into the operating system or bootloader code using compiled data structures typically in c and that is how it was done typically in the linux kernel for arm platforms we were writing c data structure each describing one device after the other so when you add for example four ui controllers you would write four c data structures that would each describe one of these ui controllers with their characteristics such as addresses of registers interrupt blind dna channels and any other thing that describes them and allows the linux scanner to use those uart controllers but with the the expansion of the number of arm associates then the expansion of the number of arm boards and this the size of those files describing all those devices became a bit overwhelming and difficult to maintain and so the arm community in in the linux scale try to find different approaches to solve this hardware description um problem so another solution that exists is using acpi tables this is widely used on x86 systems where your bios or uefi vmware passes to the operating system a set of tables acpi tables that give the operating system knowledge about the hardware that cannot be discovered this is also now being used on some arm 64 systems that are oriented towards the server market it is somewhat less used for the more embedded markets that being said an issue with acpi is that on x86 as i mentioned earlier the vast majority of the hardware being on pci or usb buses it can be discoverable discovered dynamically and only very few aspects of the system had to be described in these acpi tables therefore there the capability of acpi tables to describe complex pieces of hardware was kind of limited and it has been extended and improved since then but when we started using the device tree in in the kennel it was not that advanced so obviously the the last um possibility and the one we'll be discussing at length today is to use the divine stream it's something that originates from open firmware which was defined by sun micro systems used on the spark architecture and then on poor pc so it is not the technology that comes from the linux community it is really something that that has been used before and this name open firmware is sometimes reduced to just of and that's why there are many linux or ubud functions that are related to device 3 that have this of prefix which is sometimes confusing when you don't know that relates to open firmware this device stream mechanism for describing non-discovery hardware is no use on the vast majority of embedded oriented cpu architecture that run linux from arm 32 to arm 64 but also risk 5 poor pc extenza meeps arc and pretty much all the other cpu architecture that you can imagine and indeed it is in fact no mandatory to use the device tree if you want to contribute support for a new cpu architecture in linux so writing modifying tweaking a device tree has now become something that is necessary whenever you want to port linux to a new board or simply connect additional peripherals to an existing board and that is precisely what we're going to cover in this talk so the device stream at the beginning is a piece of source code it is a tree data structure that describes the topology of the hardware written in a source file called a device resource dts and the extension used is simply.dts the source file that is written by a developer who knows the hardware who knows the topology of the hardware is not directly used by the operating system instead it gets compiled into a more efficient representation so the compiler is called dtc for device 3 compiler and it produces that more efficient representation that we call device street blob dtb which ends up being stored in files with dtb extensions there is an extra c preprocessor pass in fact that is done before dtc in most projects so that we can use sharp defined macros and and use such macros to make the device stream more readable than using hard-coded values all over the place and then this dtb that we get d minus three blob is meant to accurately describe the hardware platform in an operating system agnostic way so that is another key design principle of the device tree it is not tied to a particular operating system the device tree blob describes the topology of your hardware what your soc is what it contains what are the different hardware blocks how they interact with each other and what is on your board around the system on chip to give you an idea a typical dtb describing a board is around a few dozen of kilobytes so it's a fairly small representation it's not it's not huge this dtb is also sometimes called fdt for flattened device tree once it is loaded into memory so you will find um in different places like in ubud there are some commons named fdt for flattened device three to manipulate the device tree there are apis named fdt underscore something and that also exists so that's why i insist on off down on that terminology as well so let's take a quick example of a very basic devisery that doesn't even represent any hardware platform right the device 3 compiler doesn't care about what is inside your dts it does only syntax checking on it it doesn't know the semantic of the device three language so my very simple dts here starts with a mandatory statement dts v1 giving the version of the device three language we're using and i think vm1 is the only one that exists and then our tree starts with a root node that starts with slash and this root node has a number of things inside which are properties and sub nodes and we'll get into the details of the syntax of the divisor later on but let's assume for now i have this device stream i can then use dtc the device 3 compiler to compile it so i invoke dtc specifying that my input is a dts idts that my output is a dtb odtb and i build my device through this way so you can see the size of my device tree the source was 102 bytes the dtb is a little bit larger 169 bytes but it's still a fairly compact representation then once i have this dtb i can in fact kind of decompile it again with dtc specifying that my input is a dtb and my output is a dts so it's i know decompiling food.dtb and getting back pretty much the same representation as i injected in dtc at the beginning so kind of almost a two-way conversion process is possible it's not exactly the same case but for the most part you can decompile the dtb like show like is shown here so now that we have this dtb um how it gets used by bootloaders or opening systems so bootloaders can use it or firmwares can use it to just like linux get an understanding of the topology of the hardware which serial parts do you have which mmc controllers do you have which one do you use to access an sd card or an emmc all this information needs to be known even by something as as simple as a bootloader um typically bootloaders such as ubud or bearbox will directly link a dtb inside their code because they don't have access to a file system to load the device tree so what they typically do is simply bundle up the the device tree into their code for linux it's a bit different for linux dtb is typically passed separately from the kindle image itself so if you take the case of ubud booting linux which is probably a very common situation and what happens is that you will have to load a canal image which is the the image containing the code and the data of the candle separately you will have to load a device tree block that describes the particular hardware platform you want to boot on so load both of these information in memory so in the example here we have known hddr for the knl code and and data and dtb adddr and we pass those two addresses to boot z and which is the common in ubud to boot a linux scanner on arm32 platforms the dash in the middle is just to tell ubut that we are not using any init ram fs for booting we're just using a canal and a device three blob and when you enter this comment a duplicate is going to jump to the entry point of the kano but before doing that it is going to store in a specific register which is r2 on on arm32 and the address at which the gtb is located thanks to that when the keynote starts it receives the address of the dtb in ram and it can access the dtb and parse it to discover the topology of the hardware the bootloader has the ability to adjust the gtb before passing it to the kindle and we'll see a few examples later on but basically this means that the dtb that the knob sees may be slightly different than the gtb you have stored on your file system as the bootloader can do on the fly a few changes to that gtb before hanging it over to the kano then the parsing of the dtb can be done using a library called libfdt which is provided as part of the device three compiler project and you can include it in into your bootloader or opening system kindle or using add-on code as is done in linux because the dtb representation in memory is pretty simple and it's not very complicated to parse so these device three files for sure um you could write your own but there is plenty of existing hardware platforms that are supported in linux and in other projects so where do you find those existing device 3 files and as i mentioned the device 3 is supposed to be an operating system agnostic representation of the hardware so ideally there should be some kind of reference place where you can find the device 3 representing various hardware platforms sadly that doesn't exist there is no such central and u.s neutral project or location that was created to collect all the those divine street files so in this was discussed many many times but never done for for various reasons so in practice it is actually the linux kernel sources that kind of serve as the canonical location reference for device 3 files so in in linux if you look in arch name of the architecture boot dts for various cpu architecture you can find many many many device profiles describing a lot of different system on chips and boards they are approximately 4 700 device 3 source files in linux as of linux 5.10 and because those device trees are also used in other project they are typically duplicated sometimes tweaked a little bit and synced from time to time into other projects and that's what you boots bear box tfa which is the new name of armed trusted firmware and perhaps a few other projects are doing so this is not optimal obviously like in general in open source we don't really like duplication but at the moment this is pretty much what is happening with two device resource files so let's take specifically the example of one of these stm32mp1 platform which i think nicely illustrates what is going on so if we take the the example of this discovery kit one board and look at the how the divisor gets used in the different stages of boot it's it's interesting so we have a several stage in the boot process the first stage is tfa so arm trusted firmware as a second stage we have u-boot and then we boot a linux scanner and each of those stages need to have some amount of details on the hardware probably linux is the one that needs the highest amount of details because it is the place where all the peripherals will have to be supported from the basic uart all the way to your camera and display most likely tfa and new boots require less support for devices but still they need to understand the hardware they run on so if we take the example of tfa to start in tfa the device trees are stored in fdt's and we have one named stm32mp157a dk1 for the platform we are interested in so when we want to build tfa for this board we need to build it with plat equal stm32 mp1 and then dtb file name and the name of the dtp we are interested in so what this tells you is that if you look at the name of the platform it only contains the the name of the family of the system-on-chip it doesn't even contain the specific system on chip we're using and not even the name of the board we're using so the code of tfa is relatively independent from the board and the exact system on ship we're using in this family it is going to get the relevant details about the board and the specific system on trip we're using thanks to the gtb that will be bundled into the tfa binary and indeed the resulting file tf a stm32 mp157a dk1.stm32 is going to contain the code of tfa but also will bundle that dtb in newport things are pretty pretty similar we have a device tree it's located in a slightly different place but the idea is the same we have a fairly generic configuration called stm32 mp15 trusted def config which is a generic configuration that works for all stm32 mp15 platforms regardless of the associate you're using in that family regardless of the bar you're using and when you build your boot you have to give a device tree environment variable that tells will which specific device tree you would like to bundle inside the u-boot binary so again in the resulting u-boot.stm32 binary you'll get the yearbook code and a bundle dtb describing your specific board in linux um the dt are located in arch armboot dts as i mentioned earlier and the pre-existing configuration that exists for stm32mp1 is multi v7 devconfig as the name of this configuration suggests it is a configuration that builds a relatively big channel image because it supports all arm v7 processors that the kindle can support not only from st but also from many other silicon vendors that have support in the official linux scanner so you get a fairly sizable channel image with plenty of drivers and this knob doesn't know a priory on which platform it is going to be booted on but because you will load this kindle image the image in memory next to a device tree blob that describes precisely the platform you're booting on the canon will be able to identify which devices are available and instantiate the appropriate drivers so booting on stm32mp1 that's a short bootlog just to illustrate kind of in practice how that what that means so here i have just ubud starting up on that board this u-boot by default comes with a two environment variable that gives two physical memory addresses which you can use to load the kennel image and the device three blob so known addr and fdt addr are at different positions in memory i can load the image the kindle image itself and you can see it's like 4.2 megabytes so this is really the code of the kernel and and the data of the camera then at a different location i load the device tree blur you can see the device three blob is just 53k um so it's it's quite small and quite compact representation and then if i want to start up the kano i simply invoke boozy passing the address of the kindle image dash because we don't use any in it from a fence and the address of the device triplob and then when i boot um blueboot tells me okay i have found a canal image at c2000 i have found a flattened device three blob so f d t at c four zero zero zero it is going to boot with that device three block and then it starts up the kennel the candle announces that yeah this is linux version five eight thirteen and it's telling us which arm core is is we're running on but also very shortly after the build it tells us of open firmware fdt flattened device tree that's why i insist on the terminology and acronyms and then machine model and it gives us a long string describing the platform and this long string comes from the device tree there is one place one particular property of the device tree that you can use to tell the human renail name of the platform we are running on once you have booted linux all the way to a prompt sometimes it is quite nice to be able to see the device tree that linux is seeing because you have your dts you have your dtb but as i told you the bootloader can make some changes or maybe you're not really sure you updated your dtb correctly so you want to really check what device three the candle is seeing and you can do that by going into the csfs file system if you go and slash this firmware device three bays there is a directory file representation of the device tree currently seen by the kernel and in this representation every node of the device tree is going to be a directory you can cd into and every property of the device tree is going to be a file that you can cut to see the actual value so you can do that by just using cd and cad to navigate in the nodes and properties but if you have dtc the demonstrate compiler available on your target hardware you can also ask it to decompile or unpack that device free representation by doing dtc-i fs where fs stands i have a file system representation of the device tree and i would like to have the corresponding dts so it can give you that dts representation of all these files and directories that's quite handy for debugging so know that this overall introduction of the device tree is in place um let's dive more precisely into the syntax of the device stream in device three you have three and indeed the device three is a tree of nodes that are included into each other on the right side you can see that we have a root node that starts with slash and it encloses encloses two child nodes node at zero and node at one node at zero happens to have itself two child nodes tile node at zero and child node at one so we can enclose as many child nodes as we need depending on the hardware we need to represent inside those nodes we have properties which can take which are basically key equal value pairs um each property has a name and it has a value and these values can be strings can be list of strings can be integers can be a list of integers and and they can also be boolean properties such as the the first child property that you see it doesn't have any value it's because it is the existence of the property that makes it a true property well if it's not present in the division it will be considered as false and more or less you can see a mapping between a device tree node representing a device or an ip block into your system and a property inside that node providing the characteristics of that device and this is quite important to keep in mind because if you remember the the block diagram that i gave of the soc and the peripherals around it pretty much every square of that diagram is going to be a node in that device string because these are the hardware blocks that you have on your system on chip and on your board around the system on chip there is the notion of cells in the property values which i'm going to cover in more details later the notion i want to cover now in more detail is the concept of p handle if you look at the second node node at one it has a name node at one but it also has a label in front of it before the colon node one and this label is important because it can then be used by other properties to refer to that node and this is done in the a reference to something property which has as value ampersand node one this is what we call a p handle you can think of it uh as a pointer it is a reference to something else in the device tree and this will be very important to describe the relationship between hardware blocks in our system for example i am using um a channel from a given dma controller um and i am i don't know some kind of spi controller for example then i will need in my device to say okay i am an spi controller but i am using some resources from this other ip block in the system on chip so we are going to use uh p handles this kind of pointers to other nodes in the device tree to um to represent these connections between hardware devices again dtc only does syntax checking no semantic validation so dtc has no idea what properties are correct and what properties make sense or what nodes make sense it can only validate that the syntax overall is correct but if you make a typo in the name of a property or in the name of a value it will simply not notice at all so now that we have this basic syntax in place let's have an overall look at the contents of a device stream so on the right hand side i have taken a very very simplified view of a system on chip so it stands the sdm 32 mp1 giving away all the many of the ip blocks i'm just focusing on a few of these and then on the left side we are going to see i would say aspect by aspect how this particular hardware platform gets represented in the device tree so on the left side you have the root node and then i have folded all the the child nodes to make it possible to have this overall view of what we have in the device tree so we've got these address cells and size sales properties which i'm gonna you can leave on the side for now because i have a separate discussion later on in this this webinar i have the model and compatible properties at the top level the model property is the human readable string that we just saw in the boot log of the know remember it shows of fdt and then machine model and then a string it comes right from there then we have the compatible string which are identifiers for the platform as a whole so here we have a unique identifier that says i am booting on the dk2 board from st and also this board contains an stm32 mp157soc and then the next nodes some of them are specified by the device tree specification itself and we're going to discover that later and some of them are less described by the device respect itself but by other documents and it starts with defining the cpus then the memory and then a node called chosen and then we have a number of nodes describing hardware blocks so i'm going to go step by step in all of those top level nodes the first top novel node is cpus and i guess it will be pretty obvious what it contains it contains a description of the cpu cores we have so here we have simply two a7 cores and it describes okay each cpu cpu at zero cpu at one and both are arm cortex a7 they operate at 650 megahertz there are cpus and we have a reg property that kind of gives an identifier there's the cpu number zero and there's the cpu number one the next node is the memory node which is an example of a node that gets updated by the bootloader so this node simply tells the linux scanner what is the base address of your ram and what is the size of your run so that the canon knows how much physical memory you have and where it is located so that it can set up the page tables and the memory management units and do all its physical memory management basically and this entry is going to be updated by uboot depending on the memory that ubud has really detected the next node chosen is a bit special because it kind of violates the rule that the device tree contains a hardware representation indeed chosen is there to allow the firmware or your bootloader to communicate information to your operating system i'm going to start with the second property std outpath which tells the kennel what kind of standard output it can use to to display its messages like the keynote messages you see at boot time very often in embedded we like to have this on on serial port so that says okay please use that particular serial device at that particular speed to show your messages the other property boot args is used by the bootloader to pass to the kennel the linux key will come online so the kindle command line is this line of instructions where you specify root equal dev mmc blk 0 p3 to indicate the location of your route file system or many other kindle arguments and so the way the bootloader uses to pass that information all the way down to the candle is using this property so your bootloader updates the dtb um and specifically this slash chosen slash boot rx property so that it passes that kindle command line to to linux then we have our first actual i would say not first because we already talked about the a7s but another hardware block the interrupt controller which for some reason is not within the soc node but that doesn't really matter much and so this node describes the intrigue controller it says i have an interpret controller it has some kind of compatible string which we will discuss later in details it has some reg properties with some addresses suppose there will be the addresses of the registers and we'll talk about that later on as well but that is one node describing this interrupt controller then we have a node called soc which itself has sub nodes for each of the individual ip blocks that we have in the in the hardware so the first one that we're going to describe is the ice crossing controller so we have a node named it's corsi at four zero zero one two zero zero zero which has plenty of properties describing some details about this ice crc controller what is important at this point to understand is the fact that the audio codec that is connected to this ice cream controller is represented as a sub node of that accuracy controller so this is what we call the topology of the hardware we have a main system it has some controllers those controllers allow us to connect to devices that are sitting on buses controlled by those controllers and this is all represented in the hierarchy of device three nodes so an spi device connected to an spi controller will be represented as a child node of the spi controller and same here for the i square c so our audio codec is represented by that node which again has a number of properties describing various aspects of that of that specific device and we'll get into the details of those properties as we move forward in that discussion moving on and the next hardware block that we have was the ethernet mac so we have another node that i've unfolded here which describes this ethernet controller which has different properties describing various aspects of this ip block and connected to it outside of the system-on-chip we have the ethernet file and this is represented in a slightly more complex fashion here in the sense that we as a sub node we first have an mdio node mdio is the um kind of protocol bus and used for a mac to control and communicate an internet file so this is not the the data pass where the actual ethernet frames are going through but it is really the control pass that allows the uh internet mac to talk and control to define for example detect if there is a link what is the speed of the link and things like that so this is represented as sub node and again as a sub node of that mdio controller we have the file itself and its address reg equals zero indicates that the address of the file on the mdio pass so as you can see there is really and i i really like this approach of showing on one side the device tree and on the other side the block diagram because there's really kind of a one-to-one mapping between a block diagram of your hardware and the device representation of it um so now that we have understood this concept of um hierarchy of nodes representing the hardware and and matching closely the top the actual topology of the hardware um how do we write those device three files we say there is going to be a dts for each platform and you compile it to a dtb which you uh give to the kennel to for it to understand the topology of the hardware so far so good but it turns out that if you write a dts for two boards that use the same system on chip well they're going to contain very much the same thing right because they have the same processor all the description of the hardware blocks inside the system on chip will be exactly the same for those two boards so it doesn't make a lot of sense to duplicate that in multiple dts files so we want some some kind of way of sharing that description and obviously this exists we have this concept of inclusion of device prefile so in addition to writing dts we can write dtsi files for device resource includes and it we typically use dtsi to store the description of an soc or description of hardware that is common between several boards of the same family and then we can include those dtsis into our dts to describe completely the hardware platform that we have in front of us so the final dts is the only one that can actually get built by dtc if you feed in a dtsi by dtc i think it doesn't even build it but or at least it doesn't make a lot of sense as by convention only a dts stores board level information that you can build into a dtb and feed into your linux scanner this inclusion mechanism works by overlaying the tree of the including file over the tree of the included file so in practice this is just a sharp include directive so once the c preprocessor has made it pass you will have all the trees of the different gtsi that you include and the final dts like one after the other but what happens is that if one tree overrides um the property defined by a tree before it it will really take precedence over the one that comes before so that allows to override details that were provided by other dtsi let's make that more concrete on a real example so on this slide we have um on to the left we have a dtsi file that describes a system on chip of course it's just a very small part of it um but it describes an ice creasy controller of our system on chip with a number of properties the one property that is interesting here is status disabled because yeah this other block is not enabled then in the middle we have the dts that includes the dtsi we just talked about and in addition to including that file it is also defining its own tree which as you can see is very similar to the one before right the drk is the same with a root node then an soc sub node then an ice core c at four zero zero one two zero zero um note that is really the same as the one on the um on the left side but it's adding other properties it's adding pin control names pin control zero pin control one oh and it's also adding a status equal ok and this status equal ok is actually going to win over the status equal disable that we add on the left in addition to adding these properties it's also adding another sub node such as the audio codec that we have on our board so the idea here is that in a dtsi we describe what is inside the system on chip regardless of which board it is put on and on the dts we define how our board are is using the different hardware blocks of the system on chip and in practice on that particular board we are using the ice core sea bus number one and we connect it to an audio codec series cs42l51 so if you look at the compiled dtb it is what you see on the top the right of the picture where we are basically the combination of of bus trees and what you have on the right is really what the linux scale will see so this inheritance and overriding of values from a syntax point of view can be done in in two slightly different ways they end up doing exactly the same result but just the syntax is slightly different so the first way of overriding properties or nodes is by replicating the hierarchy this is what was done in the previous example and it's shown here again so you have hierarchy slash soc serial at 5c000 so that's the hierarchy of nodes in the dtsi in a dts specific to your board if you want to override a property from that node well you can simply replicate that hierarchy slash soc serial at 5c0000 and then you override the status property that's one way of doing it the other way of doing it which is exactly equivalent in the resulting dtb is that at the dtsi level not only you have a name for the node but you also have a label useart1 which is before the colon and when you have that label you can use it in the dts to extend or override that node with extra properties just by using that label you do am percent use art one and then you overwrite whichever property you want so you don't have to replicate that er key you can simply say for this specific node i would like to inject more properties because i need to specify additional things and this solution is no usually preferred in the linux keynote i think originally when we started doing device 3 in linux the solution on the left was more common but it became pretty clear over time that the solution to on the right was a bit lighter and easier to maintain and so it is the solution that is that is preferred today and that you will find in most dts file and dtsi files and so now that we have looked at this concept of device 3 inheritance let's see how it applies to the stm32mp1 world of course this is specific to um to the mp1 world but in practice if you look at other system-on-chip families you will find more or less the same ideas of course the implementation details will be different but conceptually it will be very similar so on this diagram i have really split the things in in two parts the top which is the files that describe the soc so everything that is above the dashed line describe the soc level information and everything that is below the dashed line uh describes the board level information um so let's start with the the purple boxes on on the left on the top left we have the base device 3 stm32mp if you remember the 151 is the lowest end of the processor in that family the one with the smallest amount of feature it has a single cortex ava a7 and kind of the base set of peripherals which is already plenty but the base set of peripherals so this is kind of the base of that device three organization this is where we will describe the a7 the interrupt controller all the iscsi controller uart spi controller mmc and all those base peripherals and this file doesn't include any other device it's really kind of the the root of the description based on that there is a stm32mp153 dtsi which includes the 151 because indeed the 153 is a super set of the 151 functionality it is the same as the 151 but it adds a second a7 and two can interfaces so this file is much shorter as it only includes the 151 plus describes an extra cpu and two can interfaces the 157 is a superset of the 153 so it includes the description of the 153 and extends it with a description of the gpu and the dsi display interface right then in the in the towards the middle we have a yellow box this called stm32mp15xc.dtsi if you remember every variant uh is available in in well every variant 51 5357 is are themselves available in two variants with security without security features if you have the security features the the ones named c then you have a crypto engine and so this yellow box which represents a dtsi file only contains the description of a single hardware block the crypto engine then in green and in blue we have description of pin maxing configurations and we'll get to pin maxing later on and how they interact with with the rest the reason why we have so many blue variants is because the in addition to the different variants of the socs that we have discussed the socs are also available in different packages that have more or less pins and that expose more or less functionality to the outside world changing a bit the set of gpios and pins that you you can actually use on your board and this a a a b a c a d names are actually named after the type of packages that you can get and when i'm talking packages and talking like bga packages or things like that really the the the type of package for the ics so that's for the soc level representation and then for the board level representation how does it work um it is quite smart how they did it they have at the center we have this stm32mp15xx dkx that's a lot of x all over the place which obviously serves as a wildcard dot dtsi this file describes all the features of the board that are common to the discovery kit 1 and discovery kit 2. if you remember the audio codec the pimic the hdmi transceiver and all these features were common to both the dk1 and dk2 so we would find these into this common dtsi files and finally we have the dts files themselves and we've got two one for the discovery kit one one for the discovery kit two and these dts files they start by including all the gtsi that they need so let's start with the dk1 the dk1 is based on the 157 soc so it includes the dtsi it includes the dtsi for the pinmux configuration as well as the gpio definitions for the appropriate package so the package is ac in the case of that board and it also includes the common definitions between dk1 and dk2 and in addition to that it can also add extra definition specific to the dk1 the dk2 on the the right side of the picture does pretty much the same but not quite exactly the same indeed the variant of the soc used on the dk2 as security features so it's going to also include in addition to the 157 it's going to include this 15xc.dtsi which describes the crypto engine it's going to include the pink and pink configurations and gpio definitions specific to the package and the common definition for boss dk1 dk2 but the dk2 that dts is going to be also a bit bigger because the dk2 is kind of a super set of the dk1 it has if you remember the bluetooth wi-fi chip it has a display panel it has a touchscreen so it has quite a few features that will be described in the dts itself so as you can see um we really leverage this mechanism of including in everything device tree to avoid duplicating hardware definition in different files we really split out things into different files in in the smartest way possible so that we have the least amount of information to replicate in our device 3 files for specific boards but it also means that you need to navigate around all those files and get your head around this organization to properly write a device 3 files for your board so some device 3 principles the device 3 one of the foundation principle of the device 3 is that it is there to describe hardware how the hardware is not how you use the hardware like in what specific mode or configuration you would like to use your hardware but very objectively it should describe what your hardware is i have a nice question controller and it is connected to an audio codec at that address and it has this and that which i can objectively see in my schematics also it should be opening system agnostic so for a given piece of hardware there should normally be only a single possible device representation for it which should be the same for linux for freebsd for ubud for bearbox for tfa or other projects so there should be no need to change the device tree when updating the os also the demand stream should describe the integration between hardware components and not the internals of the hardware components so we should again describe i have a nice crazy controller connected to an audio codec on this bus at that frequency and there is maybe a reset gpio that is used so that's really how they are connected together but it should definitely not describe the individual registers of your interrupt of your iscsi controller or the individual register of your audio codec or some internal details of them this should be hidden in the drivers and really the device 3 is here for describing the topology and integration of hardware components together obviously like all beautiful design principles and these principles are sometimes violated so it's not perfect but it's good to have this this vision in mind and to understand device 3 files and how to extend them in in the correct way so what do we put in device three files how do we know all those nodes and properties to describe a given hardware platform or a given piece of hardware well the bayes for national document is the device pre-specification document it is available at device3.org and it gives a specification for the base device 3 syntax like the cpu node the memory node the chosen node the very basic properties but this spec really only specifies this kind of base definition which is not sufficient to really describe the wide variety of hardware that we have so on top of that spec we have the concept of device three bindings the bindings are documents that each specify how a given piece of hardware should be described in the device tree so they tell which properties you should use to describe this particular audio codec this particular ice crease controller this particular display panel or ethernet phi or any other piece of hardware that you might have on your system these documents are stored in the linux kindle sources in documentation device 3 bindings i think here again very much like the dts files themselves the keynote kind of serves as the reference for those bindings and indeed these bindings they are written by keynote developers when they've write a driver for a piece of hardware that will be used in a device tree based platform they will also have to write a corresponding device tree binding document which will be reviewed by a team of maintainers in the kennel community the gt bindings maintainer team to make sure that the binding that you submit kind of makes sense and complies with the general device tree uh principles and design guidelines in the past those documents were written just as you know basic human readable text documents and since a few guys we have moved to using instead um device tree bindings written in yaml so that they can be machine passable so let's have a look at a few of those documents the first one i'm using is a legacy style binding because it's just written in human readable text and you can fairly easily see what it contains for a specific ip block a spear smi it's not used on the stm32 mp1 because on stm32 mp1 all of the bindings that i could find were already converted to yaml so st did a good job there and a good open source citizen they already converted over to the new method for describing binding so i had to find an older example which was not yet converted and as you can see in the document it simply says to describe this piece of hardware you need to write those required properties what are the possible values and what they mean what are the optional properties and you've got a small example in yaml it's a little bit less readable for a human but it has the big advantage of being machine passable so that we can write tooling to validate bindings and i'll get to that but overall it gives pretty much the same amount of information right it's it says what the binding is for so this is for the ice qc controller embedded in stm32 platforms uh it is maintained by someone and it has a bunch of properties compatible interrupt resets clocks dmas clock frequency some of them are required as you can see at the very end um at the the bottom right of the of the slides and the required properties are compatible reg interrupts resets and clocks so it really defines what we expect from the device free representation for that particular device and there is an example that shows how this representation gets used so this yaml view is used for validation of the device tree indeed as i mentioned earlier dtc only does a syntactic validation it is not capable by itself to find that this property doesn't make any sense in the context where you've added that property but with yaml bindings we can do that validation because we know that this ice qrc controller for the stm platform expect this and that property with that and that value and if that property is missing then there is a problem so linux kennel has integrated this validation tooling there are various make rules that you can run to benefit from that validation the first one is make dt binding check which verifies that the yaml binding themselves are valid like they are correct yaml that you can parse the one rule that is interesting is make dtbs check because it is a rule that will check and validate the device refiles that you have against the yaml bindings so it will tell you this device refine that you have written violates this aspect of the binding because it lacks a property or it has an incorrect value for that property or it has this property that doesn't make sense in that context this kind of things you can also reduce the scope of the validation to one specific binding because those tools kind of take quite a bit of time so sometimes it's nice to validate just on on one specific binding using the dt schema files variable so with that said it's good to have a look at a number of really important standard device three properties and the one we're going to start with is probably the most important of all the compatible property which we have already encountered in the many examples before but we need to define more precisely what it means and what it is used for so first of all from a syntax point of view it is a list of string and they should be from the most specific to the less specific and i'll get to that in the example and this compatible property describes the specific binding to which the node complies so it is this string that allows us to know okay this node is described by this binding document all right and this string is also used to uniquely identify what the device respect calls the programming model of the device so to put it simply the programming model is what is the set of registers and the meaning of those registers for that particular device you have an audio codec it has maybe registers at offset 0 4 8 12 16 the first register is for controlling the volume the second one is for controlling the routing of the audio the third one is for controlling the clock of something in your audio codec and so on so they have they have a meaning they have a semantic and this is what we call the programming model of the device what a driver for this device needs to know to program and interact with that device and so this is kind of an abstract view more practically um the compatible string is used by the operating system to find the appropriate driver for this device indeed if you have a driver for an audio codec that understands this programming model that knows how to program this particular audio codec that has register 0 for controlling the volume register 4 for controlling this and that and so on then this driver advertise that i can support this and that audio codec your device tree with its compatible string in a specific node will say this node represents that particular audio codec and if there's a match between the two and they will well there will be kind of a connection between a particular device and a particular driver when describing real hardware the typical form of a compatible string is vendor comma model like as shown below r comma armv7 timer or st comma stm32mp1 dwmac etc the two last examples are not really real hardware like regulator fixed is to represent a fixed voltage rail on your system like you have a fixed 5 volt or 3.3 volt voltage rail and that you need to represent in the demand stream for other devices to use as a as a source of power you can use that that compatible string or gpio keys is a linux driver that uses a gpio to create a kind of a keyboard that can be seen as from user space applications as a regular input device providing key events so again this is not really real hardware it's kind of an abstraction on top of the the gpio hardware hence the the fact that it doesn't have this vendor command model um naming um back to the the second example here you see that this compatible property has two values and from the more specific to the less specific and so this allows to identify different drivers depending on their capabilities pretty much so what the k9 will do and what other operating system have to do is they have to look at the first entry st comma stm32mp1 two mac and check if there's a driver that recognized that if it is great we have the most specific driver for that device that's good we're going to use that one but if there's none we can say in the device 3 okay but if you have a driver that knows about snps dw mac 4.20 a then it should do the job as well because our hardware block is kind of the same maybe it has additional features on top of that but with that specific compatible string it can also work and then the camera will go and search for a driver with that and hopefully find a driver with which may not be the best but should be sufficient for that that's why we order them from the most specific to the less specific another special value is a simple bus which is a compatible value that you can use to say this node is describing a bus of memory mapped devices so all the sub nodes will each describe memory mapped devices this is explained in a little bit more details in in that's in that slide so the rule is that every top-level node in the device tree that have a compatible property and all sub-nodes of a node that carries the simple bus compatible value will cause linux to identify each of those nodes and at what time convert them into platform devices so in the linux kernel platform devices are devices that are sitting on memory mapped buses so if you look on the right side of the picture we have a timer node at the top level it has a compatible string so when the linux kindle boot parses that device tree it is going to instantiate a platform device structure representing that timer in the canon memory then the dt parsing continues it encounters the soc node which has this simple bus compatible property so every sub-node of that is going to be a platform device as well so you are at 1000 it's going to be a platform device as well representing the uart controller the i square c at 2000 is also going to be a platform device it's one of the ice cream controllers in our system and then as you can see there is a sub node inside this iscsi controller and this sub node because it is a sub node of an ice crossing controller it is going to be instantiated by the linux mineral as a nice corset device if that was a subnode of an spi controller it would be instantaneous as an spi device so this kind of parsing of the device tree and conversion to in-memory data structures that make sense for the linux kindle takes place at boot time then each linux keynote driver has a table of compatible string that this particular driver supports it's a table of of device id structures and when there is a match between the compatible string of a node in the device tree and one of those entries in that table then the device is bound to that driver and that allows the driver to know oh i have a new uart ooh i have a new audio codec oh i have a new ice creasy controller etc etc let's have a look briefly at two examples of driver code in the kennel first the stm32uzard.c driver which is the driver for the ui controller found on those uh st ics um at the bottom we have a platform driver structure indeed this whole file is describing a driver for platform devices devices that are sit on a memory map bus and deep down into this structure there is an of match table field that's kind of the last field on that slide this table which is at the beginning of the slide stm32 match is the list of compatible string that this driver supports so if there's any node in the device string that matches this compatible string then the probe function of that driver will be called once for each of those devices so if we have four ui controllers into our sys processor there will be four nodes in the device tree each describing one of these uart controllers most likely they will be of the same kind right they will have each the same programming model the same register set just duplicate it four times to control the four different uart controllers and because we have four of those nodes there will be four platform devices created and all of them will match with this list of compatible strings and therefore the probe function of that driver will be called four times once per each ur controller available in the system giving then in your linux system for uart parts that you can use in your applications next driver is an ice core seat device driver just to show how identical the matching principle is in this driver we don't register a platform driver structure but an is core c driver structure because it's not the same hardware bus that we rely on but this structure also has an of match table and you can see it has pretty much the same the same syntax just this one happens to only support a single compatible string series comma cs42l51 so whenever an ice quest device is encountered with a compatible string of that value in the device tree the probe function of that driver will be called really similar principle so compatible demand the most important property of all the next property that we really need to discuss is reg rank has a different meaning depending on where it is located for memory mapped devices it contains the base physical address of the registers and the size of the register areas because they are memory mapped we have a base address and we have a size of the register area and we can have several entries if we have multiple register areas and this is illustrated in the example below we have two register areas one at five zero zero two seven zero zero for four bytes and we have another area at five zero zero two seven three f zero for 16 bytes for ice corset devices we also have a ranked property because it has a completely different meaning it contains the address of the device on the ice core c bus which is also important to be able to communicate with the device but it is definitely not an address in memory because ice question devices are not memory mapped for spi devices the reg property contains the chip select number here we have an example of a quad spy controller to which two memory flashes are connected they are actually the same memory flash just there are two of them one is connected to chip select zero hence the rank equals zero and the other one is connected to a chip select one hence the rank equal one um the unit address of nodes must be the same as the first address what the address of the first rank entry so the unit address is found in the node name if you look at the example here we have the label sai4 which is before the colon and then the node name is sai at and this address and this address after the add is called the unit address and the device respect says that it must be the same as the address of the first rank so it is kind of a unique identifier for this ip block indeed if you have multiple let's say you are controllers in your system on chip you will have multiple uart nodes in your device tree but you would like them to have unique names and a good way to have unique names is to simply use add and the base address of the register for this particular ui controller because this is going to be different from one ui controller to the other i don't need to introduce the concept of cells we've already seen a bit some aspects related to cells but without making it clear so now it's time to do so so in device tree we represent integral values as 32-bit integers that we call cells so on the right side of the picture you have a property foo which contains a 32-bit value that beef which is just one cell if you want to represent 64-bit values you need two cells of 32-bit each and then we have properties that indicate how many cells we need to use in other properties so this is kind of kind of weird and that's why taking a little bit of time to explain that is important we have those properties that we have seen in a few examples before sharp address cells sharp size cells first of all they are not comments even though they start with a sharp and sharp is often used for commons in python in perl in bash scripts and so on in that case in the case of the device 3 they are not comments comments in device 3 are using cc plus plus like comment like slash slash star things like that so these are not comments the sharp means number off so number of address cells number of size cells and these properties they indicate in the sub nodes how many cells are used in the rank property to encode the address and to encode the size so if we take the example on the right side we have an soc node which you know is this very often this kind of top level node that encloses all the hardware blocks inside our system on chip it says address cells 1 size cells 1 it means that every sub node such as i square c at f 1 0 0 1 000 if it has a rec property this rank property must have one unit one cell for the address and one cell for the size which is correct here we have one cell for the address oxf100 1000 and one cell for the size ox thousand all right and this mechanism we have it in not only for address cells and style cells but here you have an illustration with interrupt cells which we use for interpret controllers i have a more detailed example about interrupts a bit later but that is another another example in this example we see that the interrupt controller the node interrupt controller at something says sharp interrupt cells equal to and the node at the bottom the i square c controller which uses interrupts says um i have interrupts from this interrupt controller and to describe that interrupt it needs to provide two cells 12 24. so what they mean depends on the binding of the interrupt controller and this is a completely invented example but to make the the syntax correct if the input controller says i need two cells then the interrupts property need to also have two cells and this is the same for clock cells gpio cells phi cells pwm cells dma cells and many many other similar properties that indicate to consumers of a particular resource how many cells they need to use to refer to a particular resource that is provided let's continue our exploration of properties the status property is here to indicate if a device is really in use or not so it's its value can be okay or okay just two letters to mean the device is really in use or it can be any other value by convention we use disable but i think really it can be anything else in which case the device is not in used so in the context of linux it really means and controls if a device is instantiated if you have a node in the device tree with status disabled where the kernel is just going to skip over it and not even instantiate a platform device or a nice course device or an spi device based on it which means that the kl will not take care of that device at all so what is very often done is that in dtsi files that describe the system on chip we usually have most all or most of the devices that interface to the outside world that have status equal disabled indeed at the time we've write a dtsi we don't know on the specific board where this processor will be used which hardware interfaces will physically be used will you use the ice controller zero or one will we use the display interface or the network interface will we use this audio interface or this other indoor interface this is not known in the dtsi itself so we usually have in dtsi everything is disabled and it is up to the board specific dts which knows okay this audio interface is used this size question controller is used this uart controller is used so i'm going to enable them but everything else i leave disabled so that's the idea of using that property setting it to disable in the dtsi and overwrite that value in the dts um i was mentioning that we would give more details about the interrupt description noise time so to describe interrupts we have nodes to describe the interrupt controllers and that's on the right side of the picture the top node interrupt controller at a002 1000 it is a geek interrupt controller for arm which we find in a wide range of arm socs it says this is an interrupt controller by having the boolean property interrupt controller comma sorry semicolon and it also gives the number of register because that's an hardware block like any others memory map registers to control the interrupts so we have two two values in that rec property and it also says sharp interrupt cells equal three so that tells us how many cells we need to use in consumers of interrupts managed by that interpret controller and so at the bottom of the the example we have two illustrations of using the interrupts from that interim controller the first one relies on um on two properties inter-apparent and interrupts inter-apparent indicates for all sub-nodes which interrupt controller is used by all the sub-nodes so the fact that we have inter-parent equal ampersand in c at the top of the soc node means that every other ip block that is described down will use that as an interrupt controller unless otherwise overridden at some other point in the device stream right so when this spi controller says geek spy 36 req type level high it gives the type number and flags for a an interrupt and this is three sales right geek spy one cell 36 second cell rq type level high third cell so we are right we match with this sharp interrupt cell property and this interrupt specification is related to the interrupt controller identified by the node that has the in-c label because of this intra parent property the example at the bottom indicates interrupts using a different property in trips extended which is basically the combination of boss in just a single property indeed we specify the interpret controller and then the specification of the intro so in c geekspy 100 rlq type level high is one interrupt in c geekspy 101 rq type level i is a second interrupt and look we have a third interrupt that comes from a different interrupt controller so the x i node is not on my example because i could make it fit on the slide but it's another interrupt controller available on this platform all right so that's the two ways of describing how a particular piece of hardware uses interrupts from an interpret controller and this way of representing the integration and connection of hardware blocks between each other is really a pattern that we see for all the other resources that you can have in a system-on-chip for clock controllers dma controllers reset controllers and so on and i've chosen to illustrate that briefly with the example on the right side and at the very bottom you have an spi controller it has a bunch of properties but the one i would like to focus on are the clocks resets and dma's properties the clock's properties says which clock is provided as an input clock to this hardware block and as you can see it is ampersand rcc and rcc is a nod at the top of my example which describes a clock controller rcc stands for reset and clock controller which is on this specific piece of hardware an ip block that controls the different clocks and the different reset signals inside the system-on-chip so this spi controller is using the clock labeled spi 3 underscore k it is using a reset signal from that same controller named spi 3 underscore r and you can see this second part of the property spi 3k spi 3r there's one extra cell in addition to the the p handle the pointer to this other node and that matches really well with sharp clock cells equal one sharp result reset cells equal one this clock and wizard controller wants one cell to describe which clocks get used or which reset line gets used if we continue the dma's property indicate which dma channels are used by this spi controller and we have a p handle to the dma mux node which describes a dma controller and this dma controller tells us you need three cells to describe a reference to a particular dma channel and indeed in the spi controller node we have ampersand dma mux1 pointer to the dma controller 61 ox40 ox05 i have no idea exactly what they mean because i haven't looked up the um the binding for that specific dma controller but these information are needed by the dma controller to identify which dma channel to use and maybe how to use it how to configure it and again hopefully you see kind of the pattern here which you will find in many many device tree files for various resources provided by hardware blocks and used by others um these reference to resources in various properties are sometimes associated to a corresponding prop names property so for example interrupts you might have an interrupt names property clocks you might have a clock names property which are really tied with each other and basically these names property they give nice human readable names to the entries so for example here you have interrupts equal 0 590 0 70 0. and we can give names to those two entries mac are q and mac pmt no so not only that makes the the device tree a little bit more readable but it also allows the driver code to do something like platform get rq by name and say i would like the mac rq and it also allows us to to give the interrupts in in any order we want right we could swap around the two interrupts and swap around the two names because the first name corresponds to the the first value of the interrupt property the second names correspond to the second entry in the interrupt property so that also provides a bit of flexibility on the ordering of the fields and you can find that for again interrupts clocks resets dma channels and many other things let's talk a bit about pinboxing because this is something that very often uh people struggle with and is also something which is very often the first contact with the divine stream because you very often have to configure pin mixing when you want to simply plug something into an existing board so in most modern processors including the mp1 there's typically more feature inside the processor than the package as pins to expose all those features to the outside world so what those processors do they muck spins which means that the particular pin going outside of the package can only be used at the time for one function or another but not both and this is illustrated with the diagram on the right side we've got just two pins going outside of our soc package but internally those pins can either expose a gpio or for the first pin at the top or a uart receive line or a spy controller master in slave outline or a clock line for a nice question controller so you have to choose um by configuration by software configuration which of those four feature is currently exposed on that particular pin and all of that is controlled using the device stream which describes which pinmaxing configurations are possible and which one you actually want to use on your particular system on stm32mp1 there are two pinmux controllers so there are actually two sets of registers that are used to control that and so you have two nodes in the device tree pin control and pick control z and it turns out that those registers also control the gpios so to control gpios like put a line high low and things like that it's also done within the same areas of registers so as sub nodes we have the gpio banks gpio a b c d e f and so on for the first one and the second one is is smaller with just one bank of gpios so this is in the dtsi file for the soc and then you have definition inside that node right you can see ampersand pin control so we are all what we're seeing here is in fact inside the the pin control node that we've um looked at on the previous slide and this shows different pin configuration here we have two pin configuration ice core c1 pins a and m can one pins a so it's a configuration for a nice qrc bus and a configuration for a can interface at the moment it doesn't say that they are used it only says these configurations are possible let's look at the first one for ice core c and it says that it configures two pins pin d12 in function af5 and pin f in function in pin f15 sorry in function af5 as well and there are some very nice comments that tell us what this means but you can also check it up in the datasheet if we look at pin d12 we open up the datasheet it looks like this it's a pin of part d and in this table we can go in the line pd12 which is somewhere somewhere to the bottom and this pin pd1 as you can see can be one of different functions like if if you configure af1 it's going to be some kind of timer input af2 is going to be some kind of timer channel 1 and then af3 another timer input function 4 it's going to be the clock for the i square c controller four and function five which is the one we're interested in it's indeed configuring that pin to have the function of being the clock of the ice question controller number one which is what we're using here so this is describing a possible way of getting the signals of the ice crossing controller number one out of the soc on two pins d12 and f15 now in the in our board and when we create the the schematics of the board we decide which pins are going to be used for what and so we will have to tell in our board dts which specific pin configuration we will use so when we describe the i square c bus on our board dts we will have to use these pin control properties that are visible in the slides pin control 0 pin control 1 pin control 2 pin control 3 etc etc and pin control names so the reason why we have multiple of those properties is because you can describe multiple states of pin configuration here we have two states we have the state described by p control 0 and the state described by p control 1 and they are mutually exclusive you can either be in one state or in another in this particular example the two states are default so you can see in pink control names the first string default identifies the name of the first state described by the pink control zero property and we have a sleep state second state in pin control names it corresponds to the pin control dash one property and so the driver can on its own decide to switch between one or the other states and in practice in this case what this is doing is that default is the state normal state for the pins to be functional like when you want to really use that ice cream bus they need to be in that state but also if you want to save power um like for example if you put the entire platform in a low power mode you can save power by changing the configuration of those pins to as kind of a sleeping state and the driver can take care of that it has some poor management callbacks and that get invoked when going into a low power state or returning back to a fully operational state so this the driver would do this transition from default to sleep and from sleep to different in most cases you usually only have a single state called default with a single property pin control.0 and a state called default is automatically set up and configured when you boot the system and when the driver is initialized for that particular device to know put that in practice on on hardware let's have a look at the changes that we need to do on a device tree to describe an led and a nice cursive device connected to the dk1 discovery kit platform to do that we'll start by creating our own device free file we'll call it stm32 mp157a dk1-custom.dts to contain our customization and we do that in the linux kernel so it's in arch arm boot dts and for now in this dts we're simply going to be including the dts describing the discovery kit so just one line in our device screen simple we go into arch arm boot dts make file and in this file we can instruct the keynote build system to also build our dts into a dtb so this make file associates some kindle configuration option config arch stm32 to the list of device trees that needs to be produced so we simply add our own next to the one for the dk1 board then we can run the canal build make or more precisely make dtbs if we want to build just the dtbs and we will see the canal build system invoke dtc to compile our new dts into a dtp we can use it and boot our board and we would obviously see absolutely no difference at this point because we are simply including an existing device free without making any changes to it it's time to make some changes first change we want to describe an led and this led we have connected it to one of the arduino connectors at the back of the discovery kit and we've kind of arbitrarily chosen pin three of that connector which happens to be the pin pe1 of the soc so in the device stream we have created a lens node and in this node we are using the gpio leds compatible string which uses a linux keynote driver that turns any gpio into an led from the point of view of the linux system every sub-node is going to be a separate led in our example we have only one that we called webinar and we give it a nice label which is in fact the same and we tell which gpio this is using and this is the gpio number one of bank gpio e remember it's pe1 the pin so hdpio1 of the bank gpio e and we say it's active high i recompile my device 3 i reboot my platform with that device stream and being in sys class leds i have a new folder called webinar which corresponds to my led and when i echo 255 in that brightness file it turns up my led if i echo zero it turns off the led slightly more complicated example connecting a nice quesy sensor here we have a bme 280 sensor a bosch bme 280 which is a temperature humidity pressure sensor and we've decided to connect it to pins 9 and 10 of connector cn13 because those pins very conveniently provide access to the i square c bus 5. you can see i square c5 sda i score c5 scl so nice we have a clock and data so let's plug it there so in the device tree on the left side we are extending the i square c5 node which exists right the ice cream c5 node is described in the stm32 dtsi files it's an explosive controller from the soc but we are going to extend it first we enable it say status okay we want this controller to really be instantiated in the kernel we specify the clock frequency at which the i square c bus will be operating 100 kilohertz then we specify the pinmax configuration with those two state default and sleep and here we can use an existing pinmark configuration of course after checking that this configuration it's indeed going to be configuring pa12 as the clock the data line and pa 11 as the clock line as can be seen on on the right side and in the board data sheet and finally as a sub-node of the iscrocky controller we described the particular iscsi device that we have connected which is this bosch bme 280. it already had a driver in the kennel it already has a device stream binding and this device free representation can be as simple as just providing the compatible string and the address of the device on the rsqc bus which is here ox76 with that done we combine our device tree we make sure that the bme 280 driver is um enabled in our kindle configuration we boot and bing in sys bus iio we have a new folder corresponding to our bme 280 device so why io because iio is the linux subsystem for that stands for input sorry industrial input and output which is basically used for a lot of different types of sensor temperature humidity pressure and accelerometers adcs lots of different types of sensors and we can get the uh the temperature of that sensor humidity level and other things in different files if you want more details about that specifically we've written a fairly detailed blog post that describes all the steps to to bring up a sensor like that connected to the um the stm32 platform and in fact this particular blog post itself is part of a larger series of blog posts that we have written and published which describe from the very beginning how to build an embedded linux system for the mp1 from creating a basic build root configuration connecting a nice qrc sensor setting up an environment for developing a qt graphical application actually developing that application showing measurements of the sensor on the screen um integrating remote updates doing factory flashing and so on so if you're interested i recommend you to check it out it's it's available on our blog so this is kind of concluding our device 3 discussion for today but there's more i was hoping to be able to cover the entire device tree in in an hour and a half but there's still more topics than that we haven't covered the range property to describe address translations between buses we have not covered complex device 3 bindings such as the ones used for audio display camera devices or pcie we have not discussed the linux kernel apis provided to query information from the device tree you can from a kennel driver look at the device tree and find which property is there and parse those properties and so on we haven't discussed the tooling available in ubud to manipulate the device 3. we have not discussed the concept of device 3 overlays so there's many more we could discuss around device 3 but hopefully this was already a good and solid introduction for you here are some resources um the device respect very important on top of that the device three bindings which we mentioned if you're interested you can check out my previous device tree for dummy stock even though i believe and hopefully this webinar is kind of a more extended version of that the e-linux wiki has a very good page on device 3 with plenty of reference to other documents and they also have on the linux wiki a page that is a compilation of references to all the talks that were given at embedded linux conferences over the past 10 to 15 years on the topic of device 3 and you will find lots of details on device revalidation and usage of device 3 concerns around device 3 and so on so to conclude about the device stream the dt is a representation of non-describable hardware in the form of a tree of nodes with properties there is some standardization that is based on device 3 bindings it's a new description language which has lots of properties and sometimes complex bindings and complex topics but it is no use for numerous cpu architectures it's widely used in the linux scanner but also outside in ubud spare box and other projects and so it has become really a must know for all embedded linux developers and i hope this discussion has will help you understand that better or discover that and and help you for your future projects a quick reminder about bootleg again we are a company with expertise in embedded linux we have training and engineering services we can develop psps and drivers we are strong open source contributors so do not hesitate to contact us and again i would like to thank a lot st for supporting this webinar and now we can get started for the qna session so i'm going to switch to a different scene and bring up the uh the chat and hopefully start answering your questions so give me just one moment and switch to the chat all right so let's see if there are a few questions so my colleague alexander bellany was already there in the chat throughout the discussion and i see he has been busy replying to a number of questions so let's pick up one of the questions that um alex has already answered but what does the 76 mean at the the pressure node so indeed um this node is the um this value is the address of the device on the ice core c bus um do we have other questions let's see kind of scrolling down i'm seeing some thank yous let's see you've got other questions all right i don't see many other questions how is a microcontroller different from a microprocessor um indeed um one could wonder what is the the difference uh very often uh i think the difference is mainly around two aspects whether it has a memory management unit or not even though it's not the one thing that makes a very clear difference between the two but very often when you are when you don't have a memory management unit it's more a microcontroller microcontroller class of devices and when you have a memory management unit it's usually more considered to be a microprocessor class of devices and i think the difference is also the type of operating system that you run on that sort of platform um on a microprocessor you will find what sometimes most people call a rich os like linux or some other os's that have a concept of kennel space user space multitasking with privilege separation and isolation and that kind of rich functionality as opposed to more i'm not sure they are more simple but slightly simpler operating systems for microcontrollers such as you know freertos maybe zephyr not x and and so on which don't require a memory management unit and also have um less separation between known user space and and less abstraction layers uh compared to something like like linux but obviously the boundary is not that clear-cut for example there are a number of non-mmu platforms that can run linux so you can configure them as microcontrollers that are strong enough to to run a linux kernel so yeah the boundary is not that clear-cut i agree so let's see if we have more questions um i'm seeing a lot of thank yous um so that's nice i saw interrupt controller uses under nodes like a gpio chip okay that's a very good question indeed a gpio chip can be an interpret controller itself right you have gpio chip which to which the number of gpios are connected and we might want to use some of those input gpios as interrupt signals like you have your touchscreen it has an interrupt signal that you wire to a gpio of your soc and so when someone pushes the screen the touchscreen controller raises that that gpio line and you would like your gpio chip to render that as a as an interrupt so a gpio controller can indeed be not only a gpio controller but also an interpret controller that's perfectly correct so a small question from the relation between kanel and ubud why do you pass the dt when building linux if the final dtb is passed by youboot anyway actually this it was also a question raised earlier uh today in the first session of this webinar so i guess some extra clarification would be needed in in the slides um there are really two different things right there is the the device tree that you would use for itself for knowing what is the topology of the hardware and there is the device tree that the linux scanner needs to understand the topology of the hardware and they don't have to be the same right of course they will somehow need to be somewhat similar right because it's the same hardware platform but it don't have to be exactly identical and you boots might need a more reduced version of it than what the the kindle has but they can also be the same right and it's in fact also possible to ask ubud hey you have a device three block built into your code please pass that to to the kennel because it uses just the same i think to understand a bit the current situation you need to take a step back and look at the history of things um the linux scanner started using the device 3 on arm 32 first and at that time uboot was not using the device free at all for itself so they first modified ubud to be able to pass a device street to the kennel and then it's only later that uh people figured oh but it would be good to also use that device three thing in you boot itself and so make that possible so then why we have this separation between the u the device tree used by ubud the device reused by the kennel and now we have this ability of in fact asking your boot to pass the same device stream but i'm not sure this is so widely used i'm not really sure but i have none i've never used that myself and i don't really yeah i see the benefits but also i believe there could be maintenance issues with that if you want to change your device tree it means that you need to update your u-boot um yeah i'm not sure that that really a very good idea and by the way hello victor um all right other questions um can i access this video at some other time the slides will be available i think we will publish the video as well hopefully the video is not too bad but yeah we will definitely publish the slides and hopefully the videos as well so another question was when using appended dtb how does ubud provide the information it provides normally in the dtb and that's another good question so the appended gtb is a backward compatibility mechanism that's the kernel for arm 32 provides it's not available for the m64 architecture but on the arm 32 architecture it's there it is there to support legacy bootloaders that did not support for for device 3. and the idea of the appended dtb is that you take your kernel image and you append the device tree to it and the keynote will recognize that at the end of its image there is a device tree so from the point of view of the bootloader you just load a big kindle image which in fact is the kennel image plus the dtb but from the point of the bootloader it's just the kindle image and the so the bootloader doesn't have to know about the device tree but your canon will still be able to use that normal device tree representation and you know the question being asked here is in that case how do you get the um how does the bootloader modifies the device tree uh to pass information to the known obviously it doesn't because it doesn't know about the device stream so in that case what the linux scanner does on arm32 is that it can use the legacy mechanisms that were used before device 3 to pass information from the bootloader to the kennel and this mechanism is called a tags uh in in the kennel it's part of the boot protocol between a bootloader and the linux scanner and it's kind of another small data structure that the bootloader leaves in memory passes that memory location into a register to the kennel and this contains the kindle command line and the size and base address of the memory and a few other things but it's very limited it's by far nothing like the device stream all right let's see if we've got more questions [Music] is there any solution to choose dividery at runtime in uboot like having multiple device trees built into u-boot like fit image and the kennel and choose which one to use at run time so as you mentioned for choosing the device tree that you boot will load and provide to the kennel you've got plenty of options there like you mentioned fit image you can also from the you put command line do some scripting and whatever uh for the device tree built into you boot itself i'm not so sure what are the possibilities there i'm not a hundred percent sure so i'd rather not say something wrong then then say something um about pin configuration is it always something that we have to fish up from the data sheet assuming that they exist i also wonder where constants like spi 3k come from all right so that's actually two questions um it is is it always something that we have to fish up from the datasheet it is indeed fairly common that to um get the pin maximum configuration correct you have to get the data sheet of your system on chip there is often quite a few comments in the dtsi files that describe the speedmax configuration so sometimes you can get away with just the comments but having the data sheets around as a way of double checking things is is very um is very nice uh we have this joke at butlin that if your device you're working with doesn't work first check your clock second check your pin marks and if it's not any of these check again so pin max mistakes are very often the source for why you cannot talk to your device so having this ability to double check with the data sheet is is great and your second question was you wonder where constants like spi 3k come from this is a very good question i think i should have covered it but again time was limited and there is a set of header files in include slash dt bindings in the linux scale that define a bunch of macros like spi 3k like geek spy or req type level high all those macro names are simply c defines which get expanded by the c preprocessor so that's where they are located so many of them are kind of generic ones and some are more specialized to a specific piece of hardware like this spi 3k spi 3r so check include slash dt dash bindings in your linux kindle source 3. is it possible to modify the device tree and then compile it using build root um yes so of course um i mean build root doesn't really build directly your device stream uh but it leaves that to the linux kernel build system or to the u-boot build system for example um but you can definitely provide a patch against your linux channel 3 or you can even tell build root that you have a separate device 3 file and you build root will take care of copying that into the kernel sources and build it as part of the canal build process so that is definitely possible and i see that julio bennett is giving lots of details about that so thanks a lot um what tools um tool set reads would you recommend for an embedded linux beginner with his own eval board which utilize f1c 100 which i'm not really sure what these are so to really um get started um there's plenty of books uh of course i'm gonna advertise our training materials i have to do that um they are fully available and i think they're quite comprehensive um so this is this is probably a good way of getting started but there are so plenty of embedded linux books that have been written over the years um obviously the the issue is that they will probably not cover your exact hardware platform and they may be slightly out of date but this is not such a huge deal first because most of the concepts and tools and principles are very hardware agnostic so you will find detailed information and useful information even if it doesn't cover specifically your hardware platform and second even if the information may be like a few years old in fact the concepts don't change too much like what i have been describing about the device tree and we started using the device 3 in arm 32 around 2010 so it's been like 10 11 years now that we've uh started um using like for real the device 3 in in arm 32 and things haven't changed that much and they have evolved a bit we have the yaml bindings we have some better tooling here and there but fundamentally the concepts are still the same um all right so i think we've reached uh 7 p.m here local time um so we've over two hours for this webinar which i think is is good um thank you very much for your participation and i would like to encourage you to contact us at brooklyn if you have any further questions about the device tree or embedded linux topics we'll put online the slides of that webinar and the video as well but don't hesitate to reach out to us for any question again thanks a lot for your participation and have a good day good evening good night wherever you are and take care thank you very much
Info
Channel: Bootlin
Views: 2,853
Rating: 5 out of 5
Keywords:
Id: fD7a6WsyJgo
Channel Id: undefined
Length: 120min 32sec (7232 seconds)
Published: Thu Feb 11 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.