From f8aca1d03016c2f4a4ae878fd9afab424cb6b72a Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Sun, 5 Jan 2020 00:22:00 +0100 Subject: more about other's mistakes found --- TODOs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'TODOs') diff --git a/TODOs b/TODOs index bdf9051..c65683c 100644 --- a/TODOs +++ b/TODOs @@ -11,10 +11,14 @@ high priority TODOs are higher; low priority ones and completed ones are lower; · VERY NAUGHTY PROBLEM · I wanted to make our bootloader and kernel able to run no matter what address they are loaded at (see comment in kernel's stage1 linker script). To achieve that, I added -fPIC to compilation options of all arm code. With this, I decided I can, instead of embedding code in other code using objcopy, just put that code in separate linker script section with section_start and section_end symbols defined, so that I can copy it to some other address in runtime. I did it and it worker with interrupt vector and libkernel (see point below). But once I changed EVERYTHING to use linker symbols/sections instead of objcopy embedding it turned out it doesn't really work... and I had to make it back the old way :( The thing is -fPIC requires code to be loaded by some os or bootloader, that will fill the global offset table with symbols. I knew it's possible to generate bare-metal position-independent code, that shall work without got, but it turned out this is not implemented in gcc (it is in arm compiler, but only in 32-bits and who would like to use arm compiler anyway). I ended up writing stage1 of both bootloader and the kernel in careful position-independent assembly, thus achieving my goal (jut with a bit more of effort). · Not strictly a problem, but a funny mistake of mine, that is worth mentioning... At first I didn't know about special features of SUBS pc, lr and ldm rn {pc} ^ instructions. So I would switch to user mode by first branching to code in PL0-accessible section and having it execute isb instruction. This worked, but was not good, because code executed by the kernel was in memory section writable by userspace code. So i separated that into "libkernel", that would be in a PL0-executable but non-writable section and would perform the switch... Well, it did work. Still, I was happy when I learned how to achieve the same with subs/ldm and could remove libkrnel, making the project a bit simpler. · system mode has separate stack pointer from supervisor mode, so when going from supervisor to system we need to set it... We didn't know that and we were getting weeeird bugs (where changing something little in one place would make the bug occur or not occur somewhere completely else); also, it's not allowed (undefined behaviour) to switch from system mode directly to user mode... (at least this didn't cause such weird things to happen...) - · both arm peripherals manual and the manual to uart itself say, that writing 0s to PL011_UART_IMSC unmasks interrupts; its the opposite: writing 1s enables specific interrupts and writing 0s disables them. wiki.osdev code also got it the way it's written in those docs, but this didn't cause problems, since uart irq was not enabled in ARM_ENABLE_IRQS_2 (using #define names from our code), so, as intended, no irq was occuring + · both bcm arm peripherals manual and the manual to uart itself say, that writing 0s to PL011_UART_IMSC unmasks interrupts; its the opposite: writing 1s enables specific interrupts and writing 0s disables them. wiki.osdev code also got it the way it's written in those docs, but this didn't cause problems, since uart irq was not enabled in ARM_ENABLE_IRQS_2 (using #define names from our code), so, as intended, no irq was occuring · STILL UNFIXED · The very simple pipe_image program somehow manages to break stdin, so that even other programs run in that same (bash) shell can't read from it... (in zsh other interactively run commands work ok, but command following pipe_image inside a shell function still have that problem) - Our sources of information - · wiki.osdev (good for starting off, but we should also mention the things that were broken there) + · wiki.osdev (good for starting off, we could also (in a polite way) mention the things, that were broken there) + > getting uart irq masking wrong (not really their fault, see above) + > zeroing bss even tho it was placed in a section, that wasn't marked NOLOAD (I need to verify that yet) + > switch inside an enum!?!?!? + > + There is already some more mentioned in HISTORY.md · ARM Architecture Reference Manual® ARMv7-A and ARMv7-R edition (man, this has 2720 pages! But I think this was the most useful document of all) · dwelch67 · http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html - very good description of atags @@ -35,6 +39,8 @@ high priority TODOs are higher; low priority ones and completed ones are lower; !!! not important but very simple !!! * have one convention of linker script names +* inform linux errata guys about incorrecty-described uart irq masking in bcm arm perif manual + * maybe add some comments in code (would do with some feedback from someone who didn't write this, as to what is unclear) * Add multiple processes -- cgit v1.2.3