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

Pi Zero Compatibility; DTB parser #81

Merged
merged 23 commits into from
Apr 26, 2021

Conversation

fayalalebrun
Copy link
Collaborator

  • 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.

@fayalalebrun fayalalebrun changed the base branch from master to multiprocessing March 20, 2021 21:11
@fayalalebrun fayalalebrun changed the title Pi zero board make option; DTB linked into elf file Pi Zero Compatibility; DTB parser Mar 20, 2021
@fayalalebrun
Copy link
Collaborator Author

The OS now runs on the Raspberry Pi Zero and is passing all tests. This is what has been added.

  • A parser which performs a search for a specified property in a DTB. It does this without allocating any data structures, making it well suited for running when OS initialization is in its early stages. This is now used for board and memory detection.
  • The UART driver was refactored, so it may be used for both the BCM2835 and BCM2836, as it is identical in both.
  • New timer driver for use with the BCM2835, which uses the BCM's system timer. The timer which was previously used, which was interfaced with via the coprocessor, is not available in the ARM1176, which made this necessary.

@fayalalebrun
Copy link
Collaborator Author

Resolves #56, resolves #76

Copy link
Collaborator

@jdonszelmann jdonszelmann left a 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.

src/kernel/Makefile Outdated Show resolved Hide resolved


// DTB is in big endian, so it must be converted to little endian
static inline uint32_t fix_endian(const uint32_t num) {
Copy link
Collaborator

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.

src/kernel/src/common/dtb.c Outdated Show resolved Hide resolved
/// 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) {
Copy link
Collaborator

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.

Copy link
Collaborator Author

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

src/kernel/src/common/start.c Outdated Show resolved Hide resolved
@@ -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
Copy link
Collaborator

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?

Copy link
Collaborator Author

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.

@fayalalebrun fayalalebrun merged commit cb0c7d0 into rellermeyer:multiprocessing Apr 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants