Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UART boot #115

Open
T-Duke opened this issue Jan 19, 2019 · 9 comments

Comments

@T-Duke
Copy link

commented Jan 19, 2019

Приветствую!

Did you think about UART booting to reduce wear of SD card, and overall development speedup, at least for development/debugging period?

When some new lessons will delight us?

@s-matyukevich

This comment has been minimized.

Copy link
Owner

commented Jan 21, 2019

HI @T-Duke. We can add an optional exercise to the lesson1 with a short description of how to implement UART boot. A PR to this file together with a reference implementation would be much appreciated.

Not sure about the estimate for the new lessons. My initial idea was to implement support for Raspberry Pi in Google Fuchsia OS and write a couple of articles/lessons about it. I am still working on it, though looks like it is going to take much more time then I thought initially.

@T-Duke

This comment has been minimized.

Copy link
Author

commented Jan 21, 2019

Hmm... I have some practice in embedded solutions for Cortex M0-M4 devices, but RPI is pretty different, especially weird booting process through the GPU. So I can try to write some UART bootloading stuff, but werry likely some degree of assistance will be needed.

I think, that this little bare metal OS is better choise to start own OS development for RPI. Things like google products, or mature linuxes IMHO is not good time investment for beginners or even geeks, who wanna build their own lightweight OS.

@andre-richter

This comment has been minimized.

@T-Duke

This comment has been minimized.

Copy link
Author

commented Jan 21, 2019

Thank you, I'll take a look.

@Benjoyo

This comment has been minimized.

Copy link

commented May 13, 2019

@T-Duke I experimented with UART boot and found c3r3s which is a great little serial bootloader with a much more robust protocol than raspbootin64. Unfortunately the included command line tool didn't work for me, so I quickly coded one in Kotlin.

You can find my tool and an explanation on how to set everything up here:

https://github.com/Benjoyo/c3r3s4j

@nicolasmesa

This comment has been minimized.

Copy link

commented Jul 12, 2019

Hi all,

I decided to give this issue a try. I ended up using the kernel to copy over the newly compiled kernel over UART. The thing I like about this is that I can copy experiment with the kernel by loading it over UART whenever I want, and I also can copy it to the SD card to make the changes more permanent.

I also created a Python client that handles the copying of the kernel as well as the command line interface afterward (screen was not working very well for me).

There are a few assumptions that I made (for example that the kernel would never be larger than 16KB) but overall it's been working for me.

You can find the code here:

Also, @s-matyukevich, thanks for these tutorials! I've learned a lot!

@s-matyukevich

This comment has been minimized.

Copy link
Owner

commented Jul 12, 2019

Thanks a lot, @nicolasmesa, this looks awesome!

I'll update the tutorial and add the link to your project with some explanations.

@T-Duke

This comment has been minimized.

Copy link
Author

commented Jul 18, 2019

Hi
nicolasmesa, if I understand correctly your kernel, shift its own code up by 0x8000 bytes, jumps to new location (and works relocated) and loads via serial port a new fresh kernel to location 0x0000. I can't ubderstand one thing - How relocated (by copy) kernel adjust all addresses (data offsets, jumps) to work properly? Probably I don't understand how ARM architecture works, and those trick works just fine, or maybe I'v lost somethig when looking to your code.

Jump to relocated code works fine I'v tracked execution of relocated code up to the moment when fresh kernel starts downloading. I try to load kernel from 1-st example. But after downloading new kernel, old code is wiped and can not work furter. After downloading new kernel, we can not directly call any old function, for reason that addresses changed. All what is left - is just jump to new kernel entry point (0x0000) But unfortunately it is not hapens for unknown reason.

Thanks.

@nicolasmesa

This comment has been minimized.

Copy link

commented Jul 19, 2019

@T-Duke, you are right that it won't adjust all addresses, so we need to fix that by making sure that the kernel uses relative addresses instead of absolute. This can be done with a two line change in the Makefile (basically, add the -fPIC flag. See this StackOverflow post to understand how the flag works.

I hope it works after you do this :)

I'm planning to write a blog post about it, but haven't had time to do it yet. Anyway, let me know if you have any other questions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants
You can’t perform that action at this time.