 Hi, I'm Jason Kreidner. I am an employee of Texas Instruments. Been there a fair amount of time, but about ten years ago. I started up this project called BeagleBoard.org, later to become a non-profit separate entity, the BeagleBoard.org foundation, of which you are, you know, we have, it's a non-profit foundation, which we have five board members and then, you know, a paid executive director and then everybody else's, you know, kind of contract jobs here and there. You're fortunate enough that we have a quorum in here today. We have two other board members. I'm the only board member that works for TI. Drew works for Osh Park. Does some contract work for Adafruit. Robert's full-time at Digi-Key. The other two guys are professors and didn't travel to a Bed and Life conference. So one's at Rose Holman. The other one's, is it Brown? He's a professor at MIT. Most recently, I think he might still be there. But he has a new kid also, so that's keeping his life busy. So that's the structure of BeagleBoard. But I'm still an employee of TI, but BeagleBoard is itself a separate entity. I want to talk to you about the USB net console. We're doing board bring up using net console and USB without a serial debug net. That's not really 100% practical today, but we want to try to dive into the issues. Hopefully some of the folks in the room are actually some of the ones that we're going to be working with to ultimately solve the problems that still exist. There's still a handful of them that are real, but things are to a point that you can essentially boot over USB, get to a U-boot prompt, which is really cool, and then also get to, you know, to kernel, to reasonably early kernel messages, although I have some work on myself to birth regards to USB. Anyway, I don't want to give away the ending. So I don't need to go over that. That was in your show description. So I want to talk about what USB net console is. That's kind of the background theory. Then I want to go into my example and then I'm going to kind of step back out of that at the end just to try to give you some inputs on why this is really cool. You must think it might be kind of cool in some way. Maybe you wouldn't be there and then I'll talk into some of the issues. How many of you have actually used net console already? Because I know a number of people I've met have used net console on server farms. Sorry to try to eliminate the serial cable nightmare, but not too many of you have used that. So I imagine even fewer of as anybody ever used USB networking and net console at the same time. That's impressive. That there was anybody that even tried it, which is cool. But after about a time you're out of here and you go to the GitHub and follow this, you too will be able to do USB based net console. How many of you have any patches in the kernel? A few? Okay, quite a few. Yes. Awesome. Okay. I feel this is going to be a super incredibly productive thing then, yes. Traditional. The way that we usually work with embedded systems, kind of just jumping past JTAG. JTAG is what a lot of people do, but when you get into the Linux SBC world and you get into the kernel, just give me the stinking serial port and let me do print K. I'm going to debug all my drivers with print K. And that's a really common way. Yes, lots of thumbs up on that. Get rid of that obnoxious little JTAG thing and allow me to do my print Fs and allow me to add my debug statements. The sooner I can get to trace functions the better, but for now, like as I'm trying to do initial, to do that, bring up just print K. And that's really pretty cool. So what it typically looks like is you have two wires really that matter. There's power and ground and there's the transmit and receive lines to wire it up on a board. Sometimes you'll need some other ones, right? You might need RTS, CTS. Those are the most common clear to send and ready to send as hands shaking. Most of you guys doing embedded systems, these stuff will not use those in your configs and just say, you know, let everything flow free and if I drop stuff, I drop stuff, whatever. Because you just want to get some output. And there's other signals, but like, so there's a little bit of wiring challenge. It's not that complex from a wiring standpoint, but you do have to dedicate a port. You do have to get something physically wired up in order to go and do that. And, you know, anytime you're doing debug, what you really care about is reducing configuration steps that are error prone, right? You don't want to run into the situation. With JTAG, it's mostly did I get the pull ups or pull downs, right? With USB, did I get the BOD rate, right? Did I have the right number of stop bits? Data bits, 8 in 1 these days is a pretty safe assumption. But you still have the BOD rate to deal with. How fast is your serial port running at? You have to, you know, you can kind of try to do some auto BOD rate detection if you have the right hardware, but if you get it wrong, you screw up. So it's still error prone, even at that level when configuring the hardware. So what is Net Console? It's essentially networked serial, right? It's a way to get the base functionality of a serial connection, but instead of transmitting it over the transmit receive lines, I'm going to send UDP packets. And the format is really, really, really simple. If I want to send a data byte, I throw it in UDP packet, and it's the length of the UDP packet says how much data there is, and that's it. That's how I send data one direction and receive it the other direction over the wire. Pretty darn simple. Not a lot of configuration headaches. You can potentially configure it. You can create a configuration issue here with the port number. If you're doing Net Console, the typical thing is to put it over port 6666. The extra 6 is important. I don't know what these guys were thinking. They thought it was particularly evil. Extra, extra evil. Anyway. And then specify some little IP addresses and go. So that IP address specification part is also kind of tricky. You're trying to boot up a device and get into it and go do other things. So you can hard code those on a subnet. If you haven't isolated, subnet, and go about things that way, but if you're sharing the network with other things, then you need to think a little bit more about the process for getting those magic IP addresses. And if you've seen the networking stacks, this is essentially the buildup. You got your Ethernet packet, and you're using IP to specify the source address, destination address, so it's IP routed. And then you've got the UDP packet, which has the port numbers in it to say that it's source port, destination port. Just do 6666. Don't play with any of the funny port remapping stuff anyway. Just set those ports. Don't have to do anything funky there. And then the length. And then the payload. And the payloads are bits. So it's pretty simple from a networking perspective. That IP address stuff is the only place where you need to put a couple little services somewhere to handle these things on that network. Now if you have any other computers on the network with running network stacks, they already do this. At least with the first one. So ARP is the address resolution protocol. That's how you get the IP address. You associate the MAC address with the IP address of the server that you're going to be talking to. In this case, the server is the one you're viewing all the net console data. So there's the server, and then there's the target system. And so the target system is going to send out an ARP proxy or probe. That's the term. An ARP probe. And then everything on the LAN is going to send back. Here's my IP address, and here's my MAC address. So what do you want to send Ethernet packets to this IP address, and you send them to this Ethernet MAC address? And so it builds up an ARP table on the target, and it can send to, you know, it has that, and now knows the MAC address for that particular IP address. But then if you're sitting on a network, and you could potentially statically configure the IP, but you'd have to still know the MAC address. Anyway, you could do that all on the target, but more typically if you're sitting on a shared network or just about any real configuration, you want to try to do something like bootp or DHCP to get the target's IP address. So the ARP tells the target what the server's IP address is, now how does it find out its own? It's going to go do a bootp and try to get its own IP address. So it may also, this may be also where it gets the magic information of what am I actually going to load to boot. So if I'm going to boot, I'm going to transfer the data with TFTP, the bootp packet would also contain the file name of what it wants you to load. So what the server wants to serve up to the target device to boot. Hopefully this is a lot of detail, but I'm not going to go any deeper. So you need those in order to get the IP addresses, and that's kind of the hardest part in the configuration, but there's stuff there to do that. Now we're going to add that extra layer. Maybe I should do these out of order. Now we need to add that extra layer, which is to do that all over instead of over a real ethernet, harder ethernets, where we've got an ethernet card in both computers, we're going to do that over USB. So the drawing looks pretty similar, except now I'm here down at the very bottom for the physical layer. You've got this extra element to the protocol, which is our endis. Remote network, I don't freaking know. It's the way to encapsulate, it's a way to encapsulate ethernet packets over USB. The CDC standard has another way, ECM, there's TLA, TLA, TLA. But it's a way that we're going to be used to transfer those ethernet packets over your USB bus. Hopefully I don't have to explain USB as a TLA. No? Anybody not know what USB is if we're in the right room? Thank you. Somebody's listening anyway. So we're going to use, for our example, we're going to use our endis. There's different ways that you can go and do it. And our endis plus TFTP, the nice thing is it's supported in the processor that we're going to be using, it's supported in the boot ROM. So the boot ROM actually understands how to do USB or endis. It's going to look like a network device to my host computer. And there's some of this that gets incorporated all within the device side driver. So the host PC looks like it gets an ethernet device. But inside the target device, it also looks like it has, in the driver, it has its own ethernet device. So it looks like there's two ethernet adapters connected directly to each other over an ethernet cable but yet no ethernet exists. So USB just makes it, on the USB class drivers, just make it look like your host gets an ethernet adapter. I have my virtual ethernet adapter and we're going to talk ethernet even though there's no ethernet. There's just USB. Lose everybody? I saw some heads nod. That's awesome. That's the hardest concept I'm going to go over today. It's all downhill from here. But it's nice that the boot ROM and the device actually understands our endis and TFTP. You provide it code that you want it to run by TFTP. It shoves that into the internal SRAM in the processor. That then configures the DDR on the processor and triggers off, so U-boot itself, there's a SPL, secondary program loader, that's tiny and fits inside that internal memory. That understands USB R in this and TFTP as well. So from that SPL, you can, you know, so the SPL configures the DDR. So from that SPL we're going to TFTP now into the DDR. And what we're going to put in there is U-boot. So U-boot itself, the big U-boot, not the tiny little version of it that's SPL, that's all shrunk down to just do one exact thing. Now we've got U-boot, which is an extremely flexible bootloader base that we have to work from, and a great way to do your board, debug, and bring up. So you're now in a nice environment. So SPL knows how to do that R-endis and TFTP and get you into U-boot, and U-boot supports Net Console. And it really doesn't care what it's putting Net Console over, it wants to put it, it needs UDP packets, and that's all it needs. U-boot provides a service for doing networking, it plugs into that stack that does it over USB. So U-boot doesn't necessarily care if you're using Ethernet, or at least at some level of abstraction, it doesn't care whether it's using real Ethernet or USB Ethernet, but we'll deal with some of the particulars. And also Linux understands how to do, I mean obviously Linux knows how to do everything, but it knows how to do UDP R-endis and that console as well. I'm going to move back, talk about how some of that's accomplished, I think, you know, just to kind of make sure you got that USB gadget concept. So the client drivers are running on the target, right? So you've got this gadget driver, so that's the Linux terminology for it at least, but it just means that I'm acting like a device, a target, not the guy that's actually driving the USB bus, but the guy that's like answering the USB bus requests, right? And USB, all the transactions, all the transfers are initiated by the host, and the target just merely answers them. So there's a driver that knows how to answer those requests and treat them as network, right? So a gadget driver like, you know, is to something like act like the USB fob that you have, that you plug in, has the flash memory on it, to act like the fob, not to host the fob, right? It's not what's reading the disk, it's what's serving the information of the disk off. And in USB everything, all the clients are grouping classes to simplify the host design, right? So there's, so we just, you know, we're using a networking class driver, and R-endis is one of those classes that provides USB Ethernet, CDC, CIMA is another, but you know, forget about that. That's actually a better one and tremendous amount of respects, but it's not the one that the AM335 ROM implements. That's where the train goes. So why did I want to do any of this in the first place? There's actually, there's a lot of reasons. Ultimately trying to actually boot these devices from the browser and really expose you know, more users to really low levels, so they can build some understanding. But from a practical standpoint, what was the tipping point? It said, okay, I'm actually going to open up, you know, Pindar's box and start playing with USB net console. It was actually the pocket Beagle production. So that's a new, that's what I'm doing the demos on. It's a new single board computer. That's 25 bucks and all that stuff. But we needed some way to test them in production and to uniquely serial number them because we do that for all the Beagles and we like to be able to identify when it was built and in all this fun stuff. I don't know if the serial numbers are all that really necessary, but we've kind of committed to doing it. And so we're going to do it. And so we needed some place where we can get those unique numbers and really quick. So the pocket Beagle tester runs in like three seconds, like two, three seconds. I started out actually trying to boot everything over USB, but it boots up a whole lot faster. If I boot, you boot off the microSD. So I ended up using the microSD to boot, you boot, but it then enabled net console for communications over the USB line where I'm fetching the serial numbers, fetching some basic tests, fetching some scripts that are actually going to go and like set the LEDs. So that it actually issues those commands over the USB net console. And I'm actually going to bring up some code now here because this is a live... Oh, I'm not going to bring up some code because I can't get to the internet. Man, I wanted to show that. So in this just, there's my... Checked in binary files, but there's always ugly, but I did also include the commit IDs, so you can look at the versions of U-boots that I built with this and to my repo that has the patches for it. But I actually have a JavaScript routine that I'm running on a BeagleBone Black, actually a BeagleBone Black Wireless, technically, that when you want to test the Pocket Beagles, you plug in the microSD that has U-boot on it, and then you plug in the USB coming out of the BeagleBone Black Wireless, and that powers it up. So the USB connection powers it up, boots up the U-boot, and enables the net console. And then in the JavaScript code, I'm just using the TCPI framework that's on the Pocket Beagle to just send streams of U-boot commands. So I just send the streams of U-boot commands to do different operations, including writing a serial number. And then the serial number that's on the file that stores the serial number is living there on the BeagleBone Black Wireless, and it increments that every time it tests one successfully. And it updates the LEDs to tell you if it actually completed or not. It happens really quick and it's nice. But since then, last minute, of course, always, but that's what gave me the confidence that said I could come out here and talk about this. But it wasn't really where I wanted to be at to come talk, and that all happened in the last couple of days. But we took this project that we'd done at last year's Google Summer of Code called Node BeagleBoot, which implements all those critical servers that we're talking about over Node USB, which is just a Node.js wrapper for Lib USB. So it takes Lib USB. If it sees the right vendor's IDs, it grabs it and says it's mine. And then it implements all of those protocols. It implements the R-Indus. It implements the ARP. It implements the Boot P. It implements the TFTP all in Node.js. So it provides all those. And so I wanted to add on to that the support for Net Console, which is now there. So hopefully, I actually have a demo. The nice thing about putting it all into this one application versus just using the services that are on the device is I can't even remember how I configured my BeagleBomb Black Wireless in order to make it answer all the services things. It just takes away the confusion. It makes sure everything all in one place. So it doesn't depend on the host configuration. Like, you're not messing with the host network stack, right? If this is my platform that I want to be, you know, acting with, do I really want to, like, you know, set up specific network interfaces to always come up to these static IPs where if I'm on wireless network, anyway, it becomes a real pain in the ass. So we get rid of any that changes to your real host system. And, you know, we want to get this into, like, a different electron apps, namely Etcher, right? So Etcher is a tool that, like, the Node BeagleBoot was originally done to bring up USB mass storage class on the target device so that you can actually write the onboard flash of a BeagleBomb Black, right, without having to have, you know, any other boot source, right? You just boot up over USB and I can reflash the device. So bring up either UMS and either Linux or in even Uboot has UMS support now. So the Node.js one is actually using the UMS in Uboot. The previous generation that we wrote in the server in C had used, you know, a small Linux image and was using that. The Linux image is a little bit faster acting as mass storage class than Uboot is, but you really, like, simplicity is king and just getting it to it in Uboot is really, really nice. So you can make an electron app, if you don't know it's a Node.js framework for actually making GUI standalone applications, this cross-platform, you know, potentially now with this I can create an electron app that's going to give me a console, a Uboot console in an electron app. And in the future, because of the API for Node USB is largely similar to the Web USB API. I'll go ahead and throw in the, while I'm thinking about them, I'll go ahead and throw in some of the limitations. Web USB does have an issue that we were a little bit concerned about initially, issue. It's not very secure to begin with, but from a security standpoint it says if your host has a driver for that device, you know, it's going to grab a hold of it and you're not going to be able to grab it with Web USB. The workaround is pretty simple. We change all the descriptors so it doesn't load a driver, right? If you control the other end of the wire, just change the descriptors. Web USB won't grab it and we can grab it. It kind of sucks from keeping everything general, so if you want to build other host stacks, you can, but it allows us to take control over it. Now, the other thing is, yeah, so I already mentioned that it implements all these different protocols, so let's get on to it. I'm trying to put some of these slides up front because once I actually go into the demo, I don't want to try to go back to slides, so goals for node Beagleboot. We want to try to get node Beagleboot in this net console context, get to interactivity as soon as possible, get to the point where we're actually peeking and poking things inside the device under our control as quickly as possible, really minimize the hardware dependencies, right? So all I need for a system now is USB, right? USB is providing power, it's providing communications, it's booting it. I don't need anything else. And yeah, so running into browsers where we're headed, etcher is also kind of redundant there. Eventually, keeping in, so right now, the limitation of my demo is that it comes up to Uboot net console for, you know, I'm not able to take that on into the kernel booting. So it's possible, and I've got some, my slides are kind of out of order, and I'm going to answer it here and not spend the time on the other slide. It's possible to actually create a console in Uboot and expose that through UEFI and essentially carry that console on through boot, right? So that as the kernel is booting, if you're providing the UEFI service, it keeps that stuff alive. Essentially, if you're a DOS programmer, think of Terminate and stay resident, sort of like world, but it creates hooks so that I could do that in the future where I can keep that console alive, the same console, on through the process of booting the kernel. Today, you can run some scripts and kind of restart net console. One of the bigger issues, I should say, with running net console over USB with the kernel is the wonderful advent of config FS. For those who know, it provides, you configure your USB, but it doesn't allow you to do it statically in pre-boot, right? It doesn't really get you, it doesn't get very early. It actually relies on user space being up before you start poking config FS. That's great for those of us that love to hack and create keyboard emulators and all the cool stuff that it can do, but it's a pain in the ass when you want it up really early. So ideally for me, it would be both in the device tree as well as in config FS, but most of those drivers don't support today, as far as I know, don't support any sort of device tree-level configuration. You can compile gmulti and hard code that into the kernel, so it's kind of a legacy gadget driver. You can get there reasonably early that way, but you'll see in my final wrap-up slides, next steps, that's something I haven't tried to this point because I was just happy to get my U-boot stuff running. So what can you do in U-boot? So what's this big deal about getting to a console booted over USB U-boot? Well, I can do a lot in USB. I can read and write memory all over place. I can read and write files on just about any sort of file system. I can read and write them up with SD cards or USB sticks, spy flash, NAND flash, and all sorts of devices. I'm now unable to go and talk to and create scripts and do things so that I can verify my hardware before bringing it up into Linux. I can toggle GPIOs. I can do generic I2C or SPI accesses. And the most importantly, I can boot the kernel. There's currently a bug in U-boot with regards to Net Console that I haven't yet narrowed down, but if you leave Net Console alive while doing TFTP, U-boot will crash. So my workaround is to cut and paste this line in at the end in order to boot my kernel. So I turn Net Console off, but standard in and standard out. I do my FTP transfers. I then turn Net Console back on again, and then I'm back at the prompt with the TFTPs happening in the background. In the meantime, on my host, I can watch things happen because I see all the TFTP transfers happening. So I kind of still know everything's good and clean, but I don't get my console back up until the end. And then I can interactively just run these last few things. The RAM args just sets up the boot args, and I'll show you that, sets up the boot args for the kernel, and then boot Z actually loads and runs the kernel. So at that point, at that point, well, okay. This is where to get the code. My GitHub node-beagleboot. It's on the Net Console branch. So the Net Console branch, I've got it referred to by a build root build image. So I can build kind of everything all in one place. It builds my kernel, my root file system, and everything. So I have something nice and reproducible. For node-beagleboot itself, you get into that directory, you do NPM install, pseudo NPM start. You do need to point the bin folder into the build root output images folder in order to get to them, plug in my pocket beagle, and then I'm at the Net Console prompt. Do you believe me? Anybody thinks this is going to work? Does anybody think this is going to work? Oh, right. Man, you're way overconfident. So I'm going to, so I do have this other, so I talked about being without a serial debug net. Reality is I've got a serial debug net. It's hidden over there. So I've got that up on the console. It's nice to kind of see things as we're going along, but realize I'm not going to do stuff over there other than to show you that this is, make sure, you know, like this is currently running Linux that I booted earlier, but it's just going to be sitting around there for nice, pretty information pictures. This is my, let me control C this. This is me running the fat finger my keyboard. I felt like it did. And so that's my Node.js based server. So I'm going to click reset button and TFTP from the ROM, TFTPing the whole U-boot. Then when you do the DHCP, for some reason, it immediately tries to transfer U-boot image all the time as default. My default boot arcs. So this again, this is run, that window is running, the window you're looking at right here is running that console. I can do print boot command. This is what ran. So it did the DHCP that caused U-boot.image to run, to transfer over again. That's just the way the DHCP thing seems to work. I set my environment to the NCIP to be the server, print server IP. It also needs, because over DHCP it also got the print IP address, the IP address for the target device. Both of those were provided by the Node program that answered the DHCP request. So DHCP set the network environment, then set the standard out. So when I compiled U-boot, I compiled it so that it would tee. So you can compile U-boot so that it has net console. And then there's another extra configuration saying it says I can have more than one at a time. So I can put a comma in there. So I'm keeping the serial active. So I haven't completely turned off my debug net at this point. My serial net. And I set standard out, standard error, and standard in all to be net console. And then I printed version. You can see that the version of U-boot printed on the screen. Hey, it worked. So at least to there, right? So we're at least now in U-boot. And I mentioned you could do a lot of things in U-boot. Oh, and this is kind of cool. Like any time I type in here, that's over the serial port, right? It just automatically shows up on the net console over the UDP packets. But I can do things like GPIO, set 53. Oh, I've got a cape on the top of this. But that turned on an LED under there. 53 is the user zero LED. Oh, I can't. Limitation, sorry. I'm so used to working at this serial port. What I'm currently doing in Node.js, it's not actually going to capture any of the standard in until I press enter. So I'm used to just typing. If I edit my Node.js thing to actually grab live keys, it would be sending those over because right now I can't press the history and do all that fun stuff. But that's a Node.js side thing. You've got a lot of commands in here, too many to show. I2C. Where's the help? That's not much help. So I can do SPI commands. If I can remember the right one, SSPI one, colon one, bit length of 32, data out of 40, 0000. Sounds good. Oh, crap. Apparently that wasn't quite the right SPI command line. But I was going to try to turn on some more fun LEDs. Anyway, brought me right back into here. I'm happy again. If I plug in a USB drive, I did test, like I could do USB start and list contents of disks there. I can, you know, I print out what the SPL has configured, the, um, what's the BD info? Oh, yeah. So you can see some of the stuff embedded in the info. There's a lot of stuff that you can do from here to work with your target environment and bring up a new board and they haven't had to add anything funky to your board. I want to copy and paste that line. Let me see if I can do it from memory. What's the chances I could do the kernel boot from memory? Probably not very good. Standard, standard out to serial, set environment to standard in to serial. I don't know. I don't think I have to do standard error because I don't think it tries to send anything across it. TFTP, the kernel into the load address, the image, TFTP, uh, the, um, let's get the short one. Let's get the, let's get the finite device tree first or flatten device tree. Sorry. I'll put the right number of D's in there. AM335X pocket beagle.DTB, TFTP, the RAM disk, the, um, RD, ADR, um, it's called, um, rootFS.CPIPIO.Uboot has to be Uboot packaged. One of the, 10 minute, thank you. At that point I should have everything loaded in memory. So we're going to set environment standard out back to serial, come on net console and set environment standard in back to serial and net console. Pray, pray them if you got them. I don't know. Is that quite work? Um, and now we're going to actually go and do the, the, the TFTP transfers of all those, um, of all those other images. So, um, well that's running. Um, this is a good point for a few questions because, because this, this is the meat of the demo. This is the part that's supposed to be, woo. Um, I'm not in the kernel. So you can't say that a lot needs to function in the kernel for this because I'm not in the kernel. I'm in the boot loader. So, yeah. So the, the, the statement is, is this isn't really that great for bringing up the kernel because if there's a bug in the kernel where it can't bring up memory, um, you know, I'm not going to get any sort of useful feedback. Um, yes, yes, complete, completely agree. You are just, you are just much easier from a, from a inside the, the kernel perspective. Um, you know, my assertion is that this is becoming, um, much more stable. Um, and that, um, the, the, the big thing from, from our perspective is that some of the things like memory, I mean, in you boot, I can do a lot of the hardware testing. Like I can test the memory, I can test all the, the things that are really going to fail, um, at mostly at the, at the hardware level, uh, from a, from a kernel and system level, um, with the, what makes this useful is using something like the, the system and package, um, that we're using on the pocket beagle because the things that we need for to get the kernel to run are all the, you know, very, very static and very much the same, um, between those systems. The only thing that I have to have work, um, to get back, uh, the, the connection to the, um, to the, the processors, essentially the USB, um, uh, well, every, every, at this point, everything that I would need for, to run was already be tested, um, by bringing it up in, in U boot. The SOC support is upstream, the device tree, I, I can use a minimal device tree that doesn't configure anything, um, outside of the, the SIP, except for the USB. Um, so I can get that kernel booted, um, without any sort of other board level dependencies. Um, so yes, in the case of bringing up a really totally new architecture or a new, um, you know, a subsystem with, with, with different, um, controllers, this doesn't really scale well, uh, for bringing up new boards based on this system and package, this is really enough. Uh, in fact, we've, I've, I've done like, like with basically this set of infrastructure, um, you know, board, bring up for, you know, somehow 20 boards. So the, the question is if you really want to use a USB connector, why not use, um, um, UART over USB? Um, that's a, that's a pretty good question. Um, and the, what, what, um, what spawned this off initially is the fact that the boot ROM, uh, chose to use network over USB and, um, and, uh, you know, you're still either way on the, the, the, the device side needing to bring up a USB stack, um, and an, an unknown driver. So, um, does it matter too much if you're bringing up the serial drive, the serial gadget driver or the serial, uh, network driver? Um, my assertion is it doesn't matter too much because those bits are pretty darn proven. Um, but, um, from a practical standpoint, it could reduce your host infrastructure if you use serial. Um, my big limitation though is I needed to do the, the, the ARP, the boot P, all that other junk to handle the ROM. Um, and, and that there's no other real good justification for that other than the fact that I had to do them to handle the ROM code before you boot load, loads and runs. Um, but my, my approach here is that because I had to do those things anyway, why not keep doing them? Um, maybe I can bring up the, the, the serial gadget in the kernel faster, uh, in the boot stream so I can get more of the print, the print messages. Uh, I really think the solution for getting early messages in the kernel is EFI. Uh, okay. Now that's a, that's, um, that's not, that's not, that's not quite right. So the, the comment was, um, I could use a small hardware piece, um, to essentially convert from the, the target, um, um, USB to some hardware serial where I can connect up hardware serial externally. That's not quite right because at that point I still, I have to have a host driver, um, on the USB target anyway to get to serial. Um, so at that point, um, you know, because I've had to add external hardware there for it, and I'm depending on, at this point I'm depending on the infrastructure to actually go and, you know, act as the host and configure that, that, that UART. I s, I s, I still need to depend on that the system booting up to that point to get that. It doesn't, it doesn't come for free, um, uh, to turn that into a host port versus a slave port. Uh, the question, the comment is you don't need USB at all on the target. You just use the USB to, yes, you're still connecting to the hardware serial on the target. Uh, and that's, and if you look at what I've actually got, what I'm actually using on here, um, we don't do any of this in the production test, and we don't necessarily end up much on the, the board bring up. Um, occasionally we still do use USB serial, but that's exactly what I have here. This USB, uh, this USB side connection is actually on the, on the top board is actually the USB to serial converter that looks at the, the console. Um, so that's what's showing up in this, um, in this other, uh, get my arrows in the right place. Um, that's what's showing up in that other window. That's actually this USB to serial. So that, yes, that's, that's the state of it is today. My, my aspirations for this talk, um, is actually to encourage those people who help maintain these subsystems, um, to, to look at these issues of bringing up something like USB gadget networking and net console very early looking at problems at, at consoles that are over it and, and translating those into the kernels and look at doing this really without the serial debug net. Um, because at, you know, that might not be a, uh, this year or this two years thing, but like, you know, three or four years down the line, um, we're, we're going to get into a situation where we just don't need the USB to serial anymore. It's, it, it, you know, it's just like we don't, we, for, for most of us in this room, we don't need JTAG anymore, right? You know, you're never not going to need JTAG, right? There's somebody who's going to need JTAG. They're going to need to get into the, the shift registers of the device itself. But I'd say that, you know, does anybody use JTAG on a daily basis? Yeah. So you're, you're, you're in the minority at this point. Um, you know, so, um, it's, uh, and that's, and serial is going to go that way too. And that's, that, I'm trying to start trying that vector, um, because serial is going to go that way as well. Um, and not that it's, not that it's not needed. I, I, you know, occasionally I still need JTAG, um, but it's, it tends to be very specialized and very early on in the, in the architecture. We're just, there's just more infrastructure that's being already brought up. And before, you know, people are doing a board level system designs. Um, I mean, let me, let me, a conclusion here. Let me just show the, the kernel running. So I loaded everything. Let me do, uh, what's the first thing I need to do to load the kernel? Um, I should know this. Oh, run ram args. Uh, that all it does is set up boot args. So that's our same boot args. And I do boot z, load address, um, and, um, device tree. So the ram disk and the device tree. And at that point, um, in all practical purposes, because I haven't done the EFI thing, I don't have the early kernel stuff, my net console stuff becomes largely useless. And, um, but we can go over here to the serial stuff. We see the kernel is booting right up. And I've got a ram disk, um, you know, root file system up and I'm loading, I'm running Linux entirely booted over USB. Um, no SD cards. Um, you know, um, that, that's straight from, from boot ROM. There's no boot medium on that device. It's just USB, um, all from a JavaScript app. Yeah. Um, so, um, next steps. Let, this, this is, this is the, the, some of the motivation, right? So I actually point to the problem. So thank you actually for, for, for, for playing it out because it's not ready for prime time. Uh, I mentioned the config fs thing. Um, you know, what I plan to try is G multi to see if I can get it earlier on, um, initially, and then going from there to EFI. I don't understand it today, but my understanding, but what my fundamental belief is, is that, that it does provide some way to, to extend the console, um, from the bootloader into the, to the, to the kernel, um, for initial boots. We can keep that open. Um, I mentioned the crash. If you leave the, the net console live, we're trying to do the TFTP. Um, and, um, and then also just integrating in this into more things. Now that we've kind of got this root framework, um, we want to try to make sure it runs on different host architectures because there, I mean the, the, the torpedo here is getting people running windows and Mac systems to try out Linux, right? So this gives you a way to, to have them do that without having any real infrastructure. Um, and, um, you know, using etchers for turning on flashing and do other sort of automation and web USB. If you want to learn more about UEFI last year, Alexander graph gave a rep talk. Um, so, uh, and that's it. I don't think I have any questions for, uh, time for questions. I think I'm over. If you want to find me, I will be at the technical showcase, uh, tomorrow. Um, please come by and see me there. Um, I'll also go stand at the back of the room, uh, if you have any questions for me to, uh, today. Really appreciate your time and your patience. I hope you enjoyed that and are inspired. Um, thank you.