-
Notifications
You must be signed in to change notification settings - Fork 25
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
Pi Zero Compatibility; DTB parser #81
Conversation
fayalalebrun
commented
Mar 9, 2021
- I added the option to run on the raspberry pi zero QEMU board quite easily, by adding a BOARD make option. I also removed the CPU and MEMORY options from the documentation, as they both must be set to a specific value for each board anyways, making them redundant.
- As I have been discussing in Add support for Raspberry Pi Zero (BCM2835) #76 I've been looking for ways to detect the hardware information in the best way possible. Since QEMU doesn't provide the dtb file in r2 when starting from a .elf file, I decided to link it in the linker file, depending on the board that is passed to make. This doesn't mean that the kernel is compiled for a specific board, as we can still use the dtb that the bootloader passes to us in real hardware. This is just to circumvent that limitation in QEMU.
The OS now runs on the Raspberry Pi Zero and is passing all tests. This is what has been added.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are all the binary blobs really necessary? I believe you're only using 2 of them. Maybe make a small index in src/kernel/dtb/README.md
explaining the use of the files that are there and maybe even some more documentation about how the DTBs work (even if it's just links to the relevant docs). That could help future groups a lot.
|
||
|
||
// DTB is in big endian, so it must be converted to little endian | ||
static inline uint32_t fix_endian(const uint32_t num) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe use byteswap.h? I think it might even be available without -stdlib because it's just macros. I'm not sure about that though, if it's not easy to get in the kernel then maybe not. The nice thing is that that header may sometimes use machine instructions to do this which would be nice.
/// Entrypoint for the C part of the kernel. | ||
/// This function is called by the assembly located in [startup.s]. | ||
/// The MMU has already been initialized here but only the first MiB of the kernel has been mapped. | ||
void start(uint32_t * p_bootargs, size_t memory_size) { | ||
void start(uint32_t * p_bootargs, struct DTHeader * dtb) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe not do this in start.c (including the global variable). Might be better to move that to a seperate file which which exports a function get_DTB()
or similar. start.c
is nicer if it's jut a large list of function calls to set up the system, and preferably has as little control flow as possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've moved most of this to hardware info. However, do you mean that I should not pass the dtb header pointer to start? How else could I do it? That pointer must go from the bootloader to startup.s to start.c
@@ -6,14 +6,11 @@ _Reset: | |||
// Disable other cores | |||
mrc p15, #0, r1, c0, c0, #5 | |||
and r1, r1, #3 | |||
cmp r1, #0 | |||
cmp r1, #3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the advantage of 3 here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Though I have not been able to obtain a multi-core Raspberry Pi to verify, everything indicates that newer versions of the RPi bootloader disable all cores except one upon entry. However, in older bootloader versions and in QEMU this is not the case. Older versions of the linux kernel which had to deal with multiple cores being active act as you see here.
The co-processor register that is being read is not documented on the ARM1176. However, it happens to return this value.
Without this change, as you can imagine an Rpi Zero would be stuck forever.