 in the other file, and again in a way that is not static, right, and theoretically it should work. Except for one thing that I didn't think of. And that is in fact we need to extern it, right? Again, trivial.c, in fact it can be static, thinking about it. But I have to do an export symbol. Again, we need to tell the internal linker about it, so it works appropriately. You'll see here that I've actually been able to make it static and I've called export symbol in order to make the appropriate function work. So what I'm going to do now is I'm going to, whoopsies, build it. And so I'll get out of here, I'll do a make. So the thing about externing is you only need to do externing for something where it's stored. So for a variable. Functions, we provide prototypes all the time without externing. So you don't need to extern function pointers. I do unfortunately need to add this to the make file, so let's just quickly edit that. And for some reason my editor is doing silly things. So let's do the build, here we're going to make, and this will be the last of this because a function isn't a prototype. Yeah, I'll just get rid of that. Again, we're not relying on the, we're not relying on the kernel, sorry, on the compiler linker to do this, so it can be static. The fact that we are exporting it using export symbol is sufficient. It's just that the compiler itself gets messed up. So I'm making a mistake of some sort that I am not seeing trivial. I shouldn't have to, that isn't a prototype. No, but the thing is you don't need to provide a, you don't need to provide it in this particular case. I guess the kernel does. Oh, we will try that then. You're probably great. The function version isn't a prototype. Okay, sadly we're out of time anyways, it doesn't matter. All I wanted to show you here was that in fact when you build the two together, this is what happens when you try to root code on camera. All I wanted to show you was that when you have modules and one depends on the other, when you insmod them out of order you get an error. That's pretty much all I wanted to show you. Once we install them and then use ModPro, it would have automatically loaded them in the appropriate order. Okay, anyway, that's it for today. Unfortunately, we've just run out of time and we need to get on to the next presenter. The next talk that we're giving is on Uboot, but otherwise for those of you who are here to see modules in KBuild, I hope I answered your questions, I hope you know more about modules in KBuild, I hope this now brings you into the ability to write your first kernel code. Yeah, and we have a couple of questions. I'll take two questions then we're going to have to move on. It'll be under user source by default. That's where the package puts it. No, you have to install the package first. So the package, yeah, yeah, yeah, nothing. We're going to give you those on a USB stick. So yeah, it's nothing you need to do. So the next talk is momentarily. And I'll make adjustments if necessary. So we get a good level, okay? Thank you. Can I ask you to do another favor and wear another mic? Yes. I mean it's going to be recorded by the conference, so you can just get the recording from the conference. Yeah, it's going to be recorded. Can you actually hear me? It's probably not on. Oh, it says on, but it does say on, doesn't it? Yeah, let's see. Yeah, can you actually hear me? It's probably not on. Oh, it says on, but it does say on, doesn't it? Yeah, let's see. Test, one, two, three. Okay, so it has to be. What about now? Test, one, two, three. No? One, two, three. I mean if I have it like here then it's working, but it's like, it's not working. Yeah, anyway, yeah, so I guess I'll be talking like that for a while. Let's get to the UBOOT talk. Just like being said, I'm a software engineer. I work on UBOOT, Linux, OpenMVidit, and this is the stuff I work on mainly. I am maintained in those three projects, one way or the other. In UBOOT I do USB, I do SOGFPGA, or NSAS stuff, and I'm one of the most active maintainers there. That's quickly about me. Can you just assemble it for me? I can do that. I can do this. I'm going to put it right here. Let's see if it's in. Yeah. Test, one, two, three. Hello? Test, test, test. One, two, three. Yeah? One, two, three. Test, one, two, three. Test, one, two, three. Yeah, absolutely. Now, where is it actually? Yeah, go ahead, let me look at it for a second. No, that's in good shape. Okay. I know what's happening. It's running away from you. Yeah. You don't like this. Yeah, just whatever. Is that going to work? How is it now? Can you hear me? One, two, three. Test, one, two, three. Yeah, test, one, two, three. Test, one, two, three. Yeah, there we go. Now it's better. Yeah. Test, one, two, three. Yeah, you're good. Yeah? Okay, yeah, well. Oh, yeah, this is so much better. Super. Thanks. Yeah, so I wanted to start with a slide about booting a computer. So basically what happens when you turn on the device, which you have on your desk, is that there's some sort of power sequencing happening in the CPU, obviously, but then the CPU has to end up somewhere in the memory, which is called the reset vector. And in that place, in memory, there has to be some initial code. Now this will be your first stage bootloader. Nowadays, it's going to be in the chip, because the technology is just advanced so significantly that people want to boot from something else and parallel flash. So there is some sort of bootloader buried in the chip, which does the initialization of the platform and then loads the next stage bootloader from some external media, which can be like SD cards or it can be USB, it can be whatever, something more complex. Usually this second bootloader is loaded into an on-chip RAM. The bokeh legal is this, the MLO, it's loaded into the on-chip RAM, executes it, and that, again, that's some initialization of the platform. It usually brings up the DRAM up, the U-boot proper, into the DRAM, executes U-boot in the DRAM, and after that U-boot loads the Linux kernel into the DRAM, executes Linux kernel, and the Linux kernel does its thing again. So this is basically the multi-stage loading, which happens today on a contemporary platform. It didn't have to be... It wasn't like that every time back in the past, it usually happened to be that the CPU core had the address was directly routed to the pad of the chip and you just attach the parallel flash and the CPU core just directly booted from the parallel flash. So your first code running on the core was something you controlled. It's not like so. Replaceable code on the Pocket Beagle is U-boot, and I would like to talk about this today. A boot loader, yeah, it's just the one thing it does. It can load the next stage and execute it, which usually is Linux. It can be anything else. It can be a VST, whatever. It doesn't matter, but it can also be used as a really good debug tool in boot monitor. That means, like, the U-boot can start the Linux kernel, right, and then you will not see it again, but it can also drop into U-boot shell where you can, like, poke registers, operate buses, and so on, debug your platform, which is really useful, not only if you're, like, trying out new hardware, but also when you have, like, your platform, for example, out of manufacturing, you want to check out quickly if things work or not. And I would like to show you how to use that U-boot shell and really, like, how to poke the hardware and really test out everything. So, first of all, this is how U-boot looks like. If you power up a system, what you see here is the U-boot SPL, that's the U-boot tree loader, and that just loads the U-boot dropper from the, in this case, the card into DRAM after initializing it, and then it starts the U-boot dropper. The way you can identify that these things start, it is by just printing out on the serial console that they are running. This print, the U-boot SPL and U-boot information is, like, the first thing U-boot prints out on the serial console to notify you that, hey, I'm running, like, at this point, everything still works. What else do you see here? U-boot itself, U-boot dropper will print which CPU it is running on, how much DG RAM you have. It will also print the board name, which is somewhere down here. Right. In case you are getting, or trying to get support from the U-boot community, you should include definitely the U-boot version. In case you have some extra patches, you should include that information as well that you have some extra patches. You should definitely include which board you are using. Now, once you get through the entire U-boot boot log, you will get to the Out-of-boot countdown. The U-boot will be running this countdown. If it reaches zero, it will just do the default boot action. If you interrupt the boot countdown, it will drop into the U-boot shell. Minor note on the U-boot SPL versus U-boot, there are three different things, actually, which can build out of the U-boot sources. Nowadays, you will usually meet only the U-boot SPL and the U-boot proper. What that means is that with modern platforms, the first thing that happens, or that can be loaded, is some sort of small piece of code, like tens of kilobytes big, which has to initialize D-RAM. It gets us for that, and is able to build a stripped-down version of U-boot, which will do the D-RAM initialization, and then chain load the U-boot proper. This is what the U-boot SPL is. There is also possibility to build a smaller version of U-boot, which is the U-boot TPL. You will likely never run into that, but just so you know it exists, it usually is present on devices which have sensing one end, and we are talking about like units of kilobytes big artifacts built from U-boot sources, which basically is responsible for loading like the U-boot SPL into the on-chip RAM, executing that and then U-boot SPL is responsible for initializing the D-RAM, loading U-boot proper into the D-RAM, and executing U-boot proper. So on some specific devices, you may also have to use the U-boot TPL. But usually you're never going to run into that one. So that's it for the interaction into U-boot. Now I would like to show you some commands which are useful in U-boot. First useful command is echo. It just allows you to print whatever some string. It doesn't interpret any control sequences except for the C control sequence which says do not print new lines. Otherwise it doesn't behave like the shell echo which does support interpretation of the control sequences, okay? The other thing is help command. This is really useful because even if you get like completely alien platform which you have no idea about what it can do, if it runs U-boot, if it gets into the U-boot shell, you can just do help. It will print you all the commands that the U-boot supports so you'll know what you can do with that U-boot. Now you can also do like help command which will give you more detailed information on that command. And this is useful even if you are like confident with U-boot but you just don't remember what's the order of like arguments for specific command. You can just do like help command and get this information. In this case it's like help for the USB sub-system which you can see in here. So what can we do? We can stop the USB. We can reset the USB bus. We can stop it. We can get the USB 3-listing. We can get USB test mode running. That sort of stuff. So you can get like a detailed help. If you need further help you can look into the U-boot documentation which is in the U-boot sources. You can see it down below here. Also in case you have some specific question you can visit the U-boot IRC. It's on 3.0. I mean if you ask questions please wait at least like a while then just immediately leave because no one responded to your question quickly. The people maybe like in Europe you know just ask at the time when they are asleep okay they just cannot reply immediately. And if no one really replies on the IRC which usually doesn't happen but it can just ask in the U-boot mail English. So that's it for getting help. Now getting board info even if you have like a board which you know about just want to check what the board is about is done using the bdinfo command. And here the interesting parts are the DRAM information here. So basically U-boot is using just physical addresses and in case you need some sort of memory with which you can operate on the U-boot shell you just run bdinfo, look at the memory layout you see okay there is a DRAM it starts at 8000 on this board. What is that? Yeah here it starts at 8000 it's 2000 with 8.0 big and this is the area which you can use for whatever you want loading files experimentation whatever. It is just a small detail that U-boot itself will relocate itself at the end of the DRAM so you should probably avoid like the last 16 or so megabytes of DRAM because otherwise you can put up the U-boot or it's structured and bad things will happen the system will become either unstable or it will hang or something like that. So like using most of the RAM is okay it's just the last couple of megabytes that are not okay. You can also see at what location U-boot itself actually relocates it it's the Reload address somewhere down here to look it up. Yeah the Reload address at the Relocation address which U-boot placed its code but this does not take into account Molocare which is like above that and U-boot stack which is also above the Molocare area so you should like round it up a little and then avoid that piece of memory. I mean you have plenty, you have like 512 megs of memory anyways. There's some other interesting stuff in here Ethernet address which is like the current Ethernet address we can't really make use of that on the Pocket Beagle but in case you have a board which has actual Ethernet then yeah the current Ethernet address is also in this list I think. So now that you know what your memory layout looks like you can also do something with the memory like read it, write it. For that we have the memory dump and memory write commands MW and MD. Well they allow you to access both DRAM and device registers and device registers can be sensitive to access with they also support off-access which allow you to select like how wide the access to the register should be we support byte what else do we have here. What access which is 16-bit long that's the default that's the 32-bit and quad on 64-bit platforms which is 64-bit access. By default the MD the memory dump will read 64 words of data but you can specify how much data you actually want to read out from the memory. That's an argument to the MD. Another trick is that if you do like MD and some address potentially some amount of data and then enter it will dump that that much data. If you press enter one more time it will dump one more time and add many data again. So like you can do like MD some address okay but I want to read some more enter will read some more and so on this way you can keep dumping the memory. You can actually see it at the end here this is just a matter of pressing enter here. Okay. You can also use these commands to access device registers in this example here I'm using it to toggle the blue LED on the pocket beagle board. So what I do is first I just dump registers of the GPIO controller. This is something I fished out of the datasheet for the OMAC chip. So I noted that address 4804 C130 there is GPIO controller direction registers then there is input register then there is output register and value register something like that. So I set the direction register here to most of them are inputs those which are set to zero are output that's for LEDs and then I can set the output value register using the MW command to just turn on the LEDs. You can just try it on the pocket beagle yourself you will see that the blue LEDs come up. Now these particular masks I'm using here are converted to these face masks here and just these four specific bits which are connected to the same GPIOs which control the LEDs on the pocket beagle. Now there are a couple of additional commands which allow you to poke around with memory which are not that well known and are less used. It's memory modify. This command if you run it on some sort of address will reach out the value on that address and print it on the command line and ask you which value you want to store to that address. So if you supply a value it will store it to that address. If you just press enter it will do nothing and automatically increment the address if you supply a minus then it will go like one address but four. So this might be interesting if you want to interactively operate with some sort of register or something. Also NM is another command which doesn't do the automatic increment of the address. So you can basically do something like NM 0x4804 C13 C C13C This will allow you to change the GPIO controller output register and then you can just specify different values and toggle different LEDs on or off. With that? With this stuff? This is just syntax highlighting which went wrong. Sorry about that. It's probably just shell syntax highlighting. Yeah but this example is just showing that you can do the NM on some sort of addresses. We'll read out that address. You can specify something if you don't specify any value here. It will just skip the address not write anything in there. And this is basically the LED example done using the memory modify command. Oh and if you specify Q then you can just exit from the command. Okay. Last two commands which are kind of useful. Cp is memory copy. The same thing applies as on the memory dump and memory write. And Cmp is memory compare. Now this is useful if you are debugging stuff like you're reading data through some sort of bus and you want to be sure that when you read the data twice that the data are exactly the same. For that you can use the Cmp command. In case the data are the same the Cmp command will tell you so in case they are different the Cmp command will tell you that there is this sort of offset that offset the data are different. So okay. These are the tools for manipulating the memory and checking the memory. But what I would like to look at next is actually you would actually have two types of shell which you might run into. Nowadays by default it should be the hash shell which is like much more modern much more sensible shell but there used to be a shell version before that in the uboot and it was really painful to use that. So you might have run into this and the experience was probably not so pleasant. Hopefully now a days you will just run into the hash which is imported from busybox some time ago but anyways. If it's a pain in the... then you are running the old one pretty much. You will notice severe limitations of the shell if you like try to do something. What's that? If it doesn't behave like a born shell then you are like running the old one. There was quite a simple test in that let's see. Yeah for example I believe TAP completion didn't work on the previous one so you can try that one for example. Anyway I will focus on the hash shell because this is what's enabled on the beagle as well anyways and I would like to talk about that one. It's similar to what you are used to with your born shell on your regular PC and also it does support environment it does support environment persistency you can have scripts in the environment in addition to values so that's what the beagle shell does. Now the beagle environment is pretty much what you know from your standard channel that is key value storage but there are a couple of details to it. First of all the default environment so the default key values are stored in the uboot binary that's the default environment but on most of the boards there will be some sort of dedicated uboot environment storage so that when you save the uboot environment it will be stored in this additional environment storage and when you power cycle the board whatever you had in your environment it will not get lost but it will get loaded from this storage now uboot always has a life copy of the environment which is in the RAM but unless you explicitly save it into the storage it will get lost so you can kind of change the life copy of the uboot environment do whatever you want with it if you reset the board then all those changes will be lost for it you can experiment with the uboot environment whatever you want you can do to it and then just reset the board and you will start from trash which is probably convenient at this point now to operate the uboot environment there are a couple of commands for that print the environment content if you just run it like so without any arguments it will dump the entire environment on the the environment is quite rich so if you run like printend it will be just really really long list you can also just say ok printend specific environment variable and it will just print that one for example printend arc will print arm because arc is arm there might be a bit of a confusion about printend and endprint so the situation is as such recently we decided to consolidate everything under the end command so you should be using like end print endf, save, endf whatever this is the modern way to do it obviously for compatibility sake and because you will see everywhere on the internet there are legacy aliases like printend, saveend, setend and so that's just to clarify the situation so ok now we can print the environment great you can also access the environment as a variable so if you do like echo dollar arc like you see at the bottom it will also print arm so whatever is in the environment whatever keys are in the environment you can access them this way as variables now if you want to modify the environment you can use setend name of the variable and then the content or an endset you can also do like 3D questions if you want to pull the user for some information using askend and you can also if you have some sort of like long script in the environment you just use the editend and you can kind of move left and right then when you hit enter this environment variable will be adjusted so you can use those and finally if you did some changes to your environment you want to make them persistent so you can use saveend this will just commit it into the environment storage now in case you want to undo that stuff like you want to just get back to the default environment you can use just like fdefault-a the local copy of the environment if you want to make this persistent then you can do like fdefault-a and then follow it by saveend so that's the environment access but there is not, no you would probably have to do that yourself on the remote machine side patches are welcome yeah okay so anyway that's it pretty much for all the environment variables you can also use the run command to store scripts in the environment so if you have like environment variable which you set to like echo hello and then you do run name of the other environment variable it will run just a script so in this case if you do like run foo it will print hello because that content of the environment variable is just evaluated you can chain multiple of these commands using the semicolon operator that's just like you know it's from the shell just like you know it's from the shell it just ignores the return value of the previous command so it will just run those commands one after the other in this case hello world it will print hello world that's the run command but yeah there's one pain point here which is the environment variables people keep running into this one if you do like if you want to set some sort of script in the environment which is accessing variables it just so happens that you will run into this first case where the line 2 is immediately evaluated and then you wonder why is it printing like something which I do not want yeah because it is immediately evaluated this foo variable there now to work around it the best way to do it is just to use the single quotes around the entire script content when you're setting it into the uboot variable just like it is done here at the end so that's probably the best practice around it and yes you can escape the dollar sign and if you like start chaining the command you'll also have to start escaping the semicolons and all the other dollar signs so when you have like more complex script it gets difficult using the single quotes around the entire script is just so much easier so there is that another thing is uboot has a couple of variables which have special meaning that will always contain the version of the uboot bootloader so if you want to inquire for example your customer which version of uboot are you running you can just tell them ok either run the command or do like print and you will immediately get the latest information which version he's running if you have multiple like standard input output possibilities you can configure those using the std and std out std adder variables if you set that variable it is immediately triggering the change in the input output so be careful about that interesting variable is load address so if you're loading any sort of data from anywhere this will be the default load address to which uboot will load those data I'll get to loading commands in a bit now once the loading is done you can see the file size variable and that will be the amount of data that you would load it so like if you load for example a file from sdmmp and want to print it you can do like md whatever dollar file size and it will print exactly the amount of bytes that was loaded so this is the automatic variable which is useful really useful it is also useful if you want a file from let's say tftp and you want to write exact amount of bytes then you can just use the file size boot command is the default boot command so in case you have this auto boot countdown in uboot when you just start it up if the countdown counts to zero it will run this boot command which is the default command which is executed then and it is really meant to stop the boot arcs and external boot arguments interesting variable is preboot now this will be useful for example if you do some sort of commissioning this is a script which is executed before the auto boot even kicks in in case you have something which needs to be done at that point you can put it into the preboot environment and it can be useful if you have it like built into your default environment and then in the preboot you do your like one time thing for example one time provisioning of the board and then certain preboot to clear it from the environment and then save ends to write the environment into the system so the next time when the system reboots there will be no preboot variable and it will just not do this provisioning action anymore then there are a couple of variables which are used to configure network IP address NATMASC server IP PTH adder for MAC addresses and finally there is one last command which I would like to show you about for manipulating the environment which is set expert this might not be present on all the systems but it's really like an environment manipulation like this army knife sort of device so this one allows you to well it allows you to do like basically three things one is to load memory content into uboot variables another thing which allows you to do is do arithmetic operations both on uboot variables and on memory addresses which can be useful like if you are doing for example some types which need to pull some sort of bit somewhere in memory or whatever yeah you know you can do like both my business standard multiplication division and you can do also bitwise operations which is useful and in case you have regular support enabled in uboot then they also allow you to do basic regular expressions so you can like have a variable in the uboot environment basic substitution on it for example including like back references and this sort of stuff it's all there so that's what you can do in an environment but with the uboot shell you can also do conditional stuff basic things like true false commands return 0 for true and false returns non-zero it also has a return value so we can have uboot check for that and we also supported the dollar question mark variable which prints the return value of the previous command we also do support the shell if conditional where you can provide whatever if command then do some operation else do some other operation that supports it to this one we also support the short-term for conditional expressions with the or or and and this is also supported here is some example of that so if true echo hello hello will print hello obviously so there is that we support test command so we can like use the standard shell test command which allows you to do like arithmetic comparison and string comparison this is all supported as well you can use it in the if command so like if test something something then do something this is supported there is one small detail about that is we do not support if negation that means like if not something then do something is not supported but what you can do is like if something then do true else do whatever your desired operation is for loop iteration over the list of elements that just like you know it from the bone shell for loop while loop is also supported this example here will run indefinitely so you can like press control C to abort this while loop this one and that is pretty much for the Yubu shell there are also hardware manipulation commands here is a GPIO command which you can use to manipulate the GPIO pins on your board we support reading out the GPIO input which by the way also has a return value so we can do like if GPIO input some number of the GPIO then do some action this is also possible you can set the GPIO you can clip the GPIO you can toggle GPIOs using this command so if you need to poke GPIOs in the Yubu environment you can just do that I2C commands commands for accessing the I2C bus on the Pocket Beagle you have actually multiple I2C buses if you do I2C bus you will see the list three of them and you can use the I2C commands to operate the devices on those buses I2C dev allows you to select which bus you want to access there is only one at a time so you have to always switch with I2C dev and then you can do something like I2CMV to write memory or MD to dump memory convenient is I2C probe it allows you to probe the bus for devices which are sitting on the I2C bus one thing about the I2C probe is that it can confuse some old I2C devices so I2C by default it's not a bus which you can probe nowadays it works mostly but there can be some devices which will just be confused by this probe action so be careful about using this one and I2C speed you can set up the I2C speed in this example here I am accessing the accelerometer actually on the bacon bit escape so I'm setting I2C bus to accelerometers on bus 2 and then I2C probe I see there is just one device the accelerometer I can just read the registers using the I2CMW I specify that it's supposed to be chip 1C because that's the I2C address of the accelerometer and I'm reading from 0 8 bytes and this is what I get out of it yeah success I did manage to read some data out of it okay so that's for hardware poking commands next thing loading from storage so you can access different kinds of storage SATA, SDMMC NAND whatever for each of that we have a dedicated command to access the raw storage and its common properties but you can also load from file system like SATA, DMMC USB sticks whatever so for that you can use the load command or ls command to list that storage device there used to be times before this generic file system interface was available where we did have dedicated command for like listing XFS listing VFADFS so you might run into ubooth which will have like these commands XLS, Xload but nowadays the modern way to do it is just with ls and load the generic interface which detects the file system here's an example of loading file from SDMMC so what I do here is there's a lot of extra stuff but first I rescan I have like all the latest information from the controller then I'm looking at the partition table I see that I have only one partition in here which is of type Linux okay there is probably X file system on that I can list the MMC in this case it's controller 0 partition 1 okay I see that there is some sort of file it's perfect I can load the file to load address which is the default load address and then I can dump the content of the file and I'm using the file size here because ubooth conveniently set that up for me to just exactly dump the amount of bytes that the file has we won't be able to exercise this one loading from network but ubooth has a network stack in it it's UDP only it doesn't support DCP but this is not that limiting and it significantly reduces size so this allows us to use ICMP obviously ARP and then we can use TFTP we can use NFS over UDP we can use DHCP to obtain information from the network now in order to use the Ubooth network stack you need to set up a couple of properties obviously you need to configure your network in case your vendor does not provide you with any way to obtain MAC address you might need to set that one up as well and then you can start just using ping to test whether the network connectivity works you can TFTP download files from your TFTP server or you can just use DHCP to obtain the IP address information and then download the files that's how loading from network works now if everything else fails and you just have no way to get files into the Ubooth you can still use load yes which allows you to load files over serial line so the way this works is you would support multiple of these protocols actually we support Xmodem Yesmodem and Kermit and in this example I'm using the EAmodem to like load EA you can specify also an address here to which you want to load the stuff and then in your terminal emulator you just say ok send over Ymodem this file and you would be receiving the file and storing it to that address so you can do that it is useful in case your Ethernet for example doesn't work for some reason then you still want to and you can just look it up if you want ok but that's about the question actually I would like to look it up so you can just load stuff over serial and I would like you to actually try this one out now finally it's bootloader right so you probably want to boot the kernel but even this is not that easy because if we have like Gathillion different Linux kernel formats on ARM you will find that image which is the raw one which is basically a Linux kernel image with a decompressor together you just put it into the RAM and basically set up a couple of registers just jump to it and the Linux kernel starts loading there is no protection against Petra now in the times of old there was an attempt to solve this problem and the U image came up which is like the U boot image but it's been legacy since forever because it's like just an envelope for a file so there is CRC32 and there are a couple of metadata in that U image which say like where that image should be loaded what's the entry point and couple of information about that image but the CRC32 is just today it's too weak it's useless so this has been legacy but there has been image format which supersedes that and that's the fit image which is like a multi-component device tree based image format basically allows you to write some sort of device tree specification and pull in blocks like the Linux kernel and have configurations which say ok this kernel goes together with this device tree and U boot will know how to interpret that and boot the kernel including the device tree and so on and you can bundle any amount of blocks you can configure different checks some algorithms and so on so the sort of flexibility is what the fit image is all about in case you're building some sort of embedded device definitely look at the fit image because this is what you want to deliver in the field now booting the kernel it really depends on which image format you have that you use the different commands for that so for that images we use boot set for U images and fit images we use boot M you just specify like the image address in case of the boot set you might need to specify also device tree location if your machine is device tree capable and you can specify also in it the address there we go or you have boot E because for some reason boot set was not good enough so we have to use that one and here's an example of booting the kernel so first of all we need to set some boot arcs because otherwise the kernel would not know where to send serial output then we just load the VM Linux we load the device tree and then use boot set somewhere around here the kernel with the device tree address and then the kernel starts booting so it's that easy to boot a kernel on the vehicle now speaking of device tree you would be able to also manipulate the device tree using the device tree command so when you load the device tree from your storage into the RAM you can say fdtadder pointed to that address of the fdt in the RAM and then you can modify the fdt in the RAM in case you want to modify it you need to first do fdt resize because whatever you just loaded into the RAM is like the flatten device tree blob and there is no extra space so if you want to add nodes you first need to do fdt resize to have you boot just add some extra space for your new nodes once you do that you can do fdt print to print whatever is in the device tree you can do fdt sad to add new nodes into the device tree and all that is like done on that device tree blob which you loaded into RAM so if you then do like boot that with a Linux kernel and that blob the Linux kernel will be given this modified device tree blob so if you want to like experiment with tweaking the device tree here is your way to do it yeah, so what you can do is like you load your device tree into the RAM then you use this fdt command to like point you here is a device tree and now the fdt command will be able to tweak the device tree or like add new stuff to it remove stuff you have to load the device tree manually into RAM so the way like booting the Linux kernel with device tree works is that you load the kernel into RAM you load the device tree into RAM and then you say assuming that it is an image right, then you say ok, so jump here but with these registers with these ARM core registers which point to here in the RAM what the device tree is sitting and the kernel will boot it will start executing and the first couple of instructions in the kernel just say ok, if these registers are set to these specific values then this kernel is being booted with device tree capable bootloader device tree is telling me the bootloader is telling me the kernel that device tree is somewhere in RAM and I should use that address for the device tree location so yeah, you have to do it explicitly yourself like load everything into the RAM and then say boot Linux device tree yeah, the bootloader is passing some sort of register settings to the kernel and the kernel is interpreting those early on in the boot and you can see that the bootloader will pass a tag to the kernel at which point the kernel is likely not running with device tree so this is what happens in the old times when ARM was being used without device tree yeah here is an example of the fit image content so this is like the device tree describing the fit image where you can see here is being pulled into the kernel section you can specify a lot of properties here, name where the kernel should be loaded was the entry point of it here I use a hash algorithm for this kernel section which is like CRT32 but I can have like secure hash algorithm 1, 256 whatever I can also have like this section digitally signed to prevent tampering here is an FDT section which is pulling in device tree it's an ARM device tree with again CRT32 and then there is configuration section ultimately here which is tying together this kernel and the device tree again it can have a different checksum algorithm it doesn't in this example now if I have this sort of fit image source file I can compile it with MK image it will generate the blob on the machine and blob will contain the kernel image the device tree and people will know where to put those and where to start those so the final bit is getting the input sources you can get them from the gate repo here in case you need some specific tweak from a maintainer you are in touch with a maintainer he might point you to one of these forks for the maintainer trees both of that is available through both gate and ICDPS protocol in case you were trying to clone new boot sources recently it could be that you had some trouble because we just replaced the server so I think last week the server had some sort of failure it could be that you were not able to get easy access to these repos that should now be fixed there are also sources for the uboot available on that USB stick you have now if you want to build the sources clone them, export architecture for which you are building in this case this would be ARM export your cross compiler prefix which will be like ARM Linux or ARM known whatever and then make your board that config and make the board that config in this case the 35x pocket beagle you can check if the config is present in the config directory so it has to be there otherwise you wouldn't be able to configure the uboot and then just make it it will generate the uboot binary for the pocket beagle that's uboot IMG and the MLO which is the SPL and that's it for the intro part do you have any questions in a little bit too much oh yeah you do and then this will write it into the storage so there is this environment storage partition whatever depends on how your board is set up into which the environment will be stored and this will be persistent at that point so if you do safe and it will be made persistent all of it the local snapshot of the environment any other questions if you can disable the output do you mean it will still check yeah I usually set it to like really long value when I do development but I do not think you can disable it from the uboot shell you have to do it program like you have to tweak the uboot itself there should be some configuration options for that yeah to disable autoboot but I would have to look it up what that is I would try something boot delay to minus one maybe that might actually work quick break we are going to do a quick practice in the last 10 minutes then we are going to do both the labs and Mark do you have some labs for people to try yeah absolutely so there is a practical part we are going to play with that after the break so everybody quick file break and when we come back we will do the practical part of the board incidentally we should do the practice you can play around with the uboot a little everyone has to be a little accessible I will do it BN one second give me a second don't worry you are doing great you are doing great yeah someone will help you out a bit this gentleman great yeah okay so task zero is just drop into the serial port see if you can do stuff like version or help if you can access that super task zero I will give you a couple of minutes for that so if you are getting bored let me know the slides are organized so that alright so anyway before you start discussing stuff and the slides are organized so that there is always some sort of task here which you should do and then on the next slide there is a solution for that okay so task one is just to drop into the uboot prompt task two is to conveniently load content into your uboot environment like the load y command please try it out this way you can kind of develop your uboot script and then load y them into the uboot environment so you will have always a sort of local copy of whatever you created for the uboot so that will be task one zero and one are nothing exciting do you all have actually access to these latest slides okay if you don't have access to them they are on the eail github repo so please download the latest slides in case you get bored you can start moving forward with a subsequent task and if you have a problem with task zero or task one raise your hand and let me know if you need assistance so you can just create your text file like key equals some sort of value exactly just save it as a text file and then use the load y to load it into the uboot and then import to import that file actually if you look into the slides like a couple of slides before that you will just find an example of it you can kind of put it together and it should be easy on the next slide there is also an example yeah in the github there is a latest slide loading environment over serial port into uboot just using loading just load the file yeah over serial port and then import that content into your uboot environment so you can have like your custom scripts written on your pc and then just import them into the uboot environment conveniently for this that's the instruction yeah okay so who of you actually is in the uboot shell right now can you raise your hand so what about the rest of you do you have some problems with that or do you need some assistance that's about it what's that yeah but you are now in the on Linux right so if you reboot yeah if you reboot then eventually you will get like this this sort of out pad this is what you will get so then just press space and this will drop you into the uboot shell I think yeah or you can just press the reset button on the board there is like one in the middle one of these three buttons yeah just try all three of them something happened there there you go super super so I figured I should explain task one a little bit more so the idea here is that use the load E command to load some sort of file containing environment and import it into your uboot environment so that you can conveniently this way import uboot script yeah yeah no there is not but you can like use shift page up shift page down I think so should work maybe it's the terminal emulator property what are you using what was that can you help up yeah going up and down there is like escape something like that I think it was like control A escape like escape and then you can go page up page down okay if I'm not used to strange oh did something happen maybe you too can kind of cooperate and figure it out yeah I don't think so yeah alright now it's in copy mode oh that's the one looks like you're here controlling oh cool so yeah so here's the question did you manage to get this loady working with the ymodem so the question what are we supposed to do with this task so what I would like you to do is prepare a text file with the uboot environment that means like a key and a value tuples in that text file then use loady to load that into memory and then import to import that uboot environment this is what I would like you to do here in this one was that I don't have an example text file but you can create one with like hello equals world that's this sort of yeah exactly and you can probably also put some sort of script that like you know foo equals echo bar something like that this is kind of how it should look like so if this is readable you can just create a random file then use loady and send it over to imodem when you finish loading you can just do md.b load address file size you'll see that the file was loaded and then import to import this environment file this is what I would like you to do to try this sort of thing was that was that yeah in the linux command line you just like use the cat command which means read from standard input until you type eof do you have a linux machine I do I'm just run you shell in your linux machine oh no I'm on your development machine