testjz wrote:I think that I'd wait some years (I don't know how many exactly) before I recommend BOOTBOOT for those who don't want to write their own, that would be the time I roughly estimate BOOTBOOT reaches better stability with greater probability. ... I think however that we should not be in a hurry to say that BOOTBOOT is mature enough (I'd classify it as beta)
Thanks, but I don't think I called it mature in a hurry. The feature set got frozen
more than a year and a half ago. I'm regularly testing it, as well as many users, and just because you've asked, I've done a through testing with the following combinations:
bochs, BIOS, ROM
bochs, BIOS, disk
bochs, BIOS, cdrom
qemu, BIOS, ROM (-option-rom)
qemu, BIOS, Linux boot protocol (-kernel)
qemu, BIOS, disk
qemu, BIOS, cdrom
qemu, GRUB, Multiboot (via grub-mkrescue)
qemu, UEFI, disk (TianoCore)
qemu, UEFI, cdrom (via UEFI El Torito)
qemu, RPI3, sdcard
qemu, RPI3, serial
qemu, coreboot, ROM (using cbfstool to add initrd to ROM)
qemu, coreboot, disk
qemu, coreboot, USB disk*
VB, BIOS, disk
VB, UEFI, disk
real hardware, BIOS, USB disk
real hardware, BIOS, SATA disk
real hardware, UEFI, USB disk
* - this one didn't work, but the problem is not in BOOTBOOT, libpayload's usb_poll() function does not return for some reason. I guess I've compiled coreboot with incorrect config or I've messed up the qemu arguments to emulate an USB storage. Further investigation required.
testjz wrote:But I was thinking about the rate of stability which, while I think is subjective how good it must be in order to classify a project as mature enough, it usually still depends on some specific factors (in parentheses will be my estimates for BOOTBOOT) like "how big is the project?" (small-to-medium size),
I don't think so. I think testing matters more. However that's true that smaller projects are easier to be tested correct, that's why I have created several, separated loaders all implementing the same protocol instead of a single, bloated code base.
testjz wrote:"how many bugs were found lately and how many of them were fixed?" (I don't know and I'm not going to count the bugfix commits right now)
This tells absolutely nothing. A better designed and implemented software will get fewer bugs. All of my projects in general have very few bug reports, because I put lot of effort in them. Btw, BOOTBOOT right now has about 20 issues, all has been fixed and closed. As a comparition, one of my most popular projects with nearly 1000 stars (and probably 10000 users) has 60 issues, not all of them are bug reports (there are many feature requests), and only 2 are open ATM.
testjz wrote:"how many might use it right now?" (100 to 200, as estimated above), "how much of the users' work is affected by the common uses (i.e. how likely are issues noticed)?"
Now these are very good questions. It is true, that the more users are using it, the more the chances are that a bug pops onto the surface.
testjz wrote:But does it always work?
It doesn't have to always work, it is enough if it works for all the users
No one can guarantee that a software will always work unless it's mathematically proven correct, and even then there could be errors caused by faulty hardware.
testjz wrote:Are all edge cases predicted and taken care of?
I think so! SMP was the last feature to be added, and there was only one issue on real hardware in the last year.
testjz wrote:Is it as simple and as correct as possible?
Yes!
testjz wrote:Are all algorithms used there the most optimal ones depending on the situation?
No. They are not always the most optimal, but always a correct one! I don't care about optimization if the code loads the system in less than a second. There's simply no point in optimizing.
testjz wrote:Is there guarantee that the dependencies will never change (the only one probably not applicable here)?
Yes! If the dependencies (which is BIOS int, UEFI protocols, and hardwired SoC for RPi) change, they will break their standards, and it would affect all boot loaders, not just BOOTBOOT. (Take a look at the 2nd part of the PDF specification, it lists all firmware functions that's been used for a particular implementation)
testjz wrote:Is there guarantee that there won't be any new processor architectures and hardware platforms and that they won't invent a new firmware that might be better or worse than UEFI?
No, but who cares? BOOTBOOT is a protocol, and a new loader can be added (independently to the existing ones) any time that would implement those new hardware and firmware. The BOOTBOOT protocols requirements are so slim, that I'm absolutely sure they can be implemented. There's one exception, BOOTBOOT is 64 bit only, for 128 bit ISA there'll be a need for a new protocol, but that's fine and calculated.
testjz wrote:But I'm not saying that nothing is mature, just that improvement is a continuous process and does never stop
Wrong! You are thinking about one big bloated project! BOOTBOOT is a standard, with many little implementations.
testjz wrote:I think you hurried up this a bit, because probably it also prevents removing features that turn out to be unnecessary
You *think*. On the other hand, I *know* for sure, because I've put several decades of research in this topic.
testjz wrote:I don't know how many years is BOOTBOOT under development (from what I see, at least two years and three months, and I don't know how much time it was before the initial commit and/or also how much time it was for the project this one evolved from).
Decades. The first version of my loaders that was called BOOTBOOT is more than 3 years old, and the main concept hasn't changed a bit. That initial commit 2 years ago just marks the time when I moved the project from github to gitlab.
testjz wrote:I also have this other quote:
Ken Thompson wrote:One of my most productive days was throwing away 1000 lines of code.
which I think is more fitting.
I like this one!
K.I.S.S. was always my favourite principle
testjz wrote:Why would the bootloader need to depend on an entire external hosted library that implements 100 or more functions?
Exactly!
testjz wrote:That should obviously be always the case, but there might still be edge cases that hadn't been predicted (e.g. some operations might be overflowing with some values)
Not possible, there are standards for crypto functions. If overflow happens, then that's an implementation problem, and it surely won't pass the test vectors.
testjz wrote:or the code is unportable to some architectures (e.g. unaligned memory accesses are used).
This is why I prefer a separate implementation of those on all platforms.
testjz wrote:That said, maybe "valid" could only be defined and assigned to when "GOP_DEBUG" is defined
I'm already ahead of you, this has been done!
testjz wrote:I think everyone should write code so others do understand it easily. Since this is C, most people will expect one of the styles usually used with C.
Yeah, using a consistent coding style is a high priority on the TO DO list, no question about it.
testjz wrote:By the way, could you tell me more about Fótism? Unfortunately I searched for it using both Startpage and DuckDuckGo (I don't use Google) and I found only one search result with Startpage: this topic. DuckDuckGo didn't return any results with Fótism (yes, I put it in quotes so it's exactly this and not something similar-looking).
Not surprising
This is a local slang at my university, also called the
Zen-of-Fóthi (sorry, Hungarian only). Long story short, my prof, Dr. Ákos Fóthi created a programming methodology based on mathematics in the early 1980's at
ELTE. I couldn't find that book on-line (I've a printed version), but I could find a link to another book, called "
Prelude to Programming" (sorry, Hungarian only). Note this book is not about the methodology, rather it's a prerequisite that explains the background, a glossary if you'd like.
testjz wrote:I should had been more clear, sorry, I was talking about selecting just the kernel, the boot structures, the initial ramdisk and the framebuffer, and map only those. Either way you already map them specially. I wasn't talking anymore about identity mapping the entire RAM.
That's different. Those are mapped in KERNEL SPACE, that's totally different than identity mapping RAM in USER SPACE.
testjz wrote:I see, though it's probably more complexity for the kernel as it needs to check which protocol level it has been loaded with and to use the appropriate addresses.
No, it is the other way around! The kernel has to check nothing. Level 1 compliant loaders can load kernels that comply with BOOTBOOT Protocol Level 1, while Level 2 compliant loaders can boot both Level 1 and Level 2 kernels. To check which version a kernel complies to, use
testjz wrote:By the way, do you plan making the BIOS version support level 2?
I'm not sure. Maybe, but TBH I'm good with supporting Level 1 only, and at least there's an example Level 1 loader.
testjz wrote:is it guaranteed that UEFI won't try to do anything with the cores between the point you send the IPI and SIPIs (shouldn't the second SIPI be sent only in case it the first one didn't work?) and the point where you call ExitBootServices()?
Yes. UEFI runs on BSP, and ExitBootServices(0 must be called on the BSP.
testjz wrote:But how do you formally prove your code to be correct?
For example Fóthism
Here's a
list of things required for a master's degree, called "Theory of Programming Methodology" (again, sorry, Hungarian only). This is a non-official paper written by one of PhD students.
testjz wrote:Which methods do you use and what medium (written logic and math, a computer program)?
None! It is extremely hard to create proof of correctness! What Fóthism teaches you is that you don't need proof. It is enough if you learn mathematically proven algorithms, then you do a thing called "backtrack" (however this is confusing, because there's a search algorithm also called backtrack, I'm not talking about that). The point of backtrack method is, that you use bidirectional relations to transfer the state-space of your problem until you can find a (proven) algorithm that fits and solves your original problem. Then you transfer back the result to the original state-space, and you're good. Hope this makes sense to you, there's an entire semester on this topic.
testjz wrote:I'm genuinely interested because I also want code to be correct (and it amazes me that so many widely used projects have very low quality code).
I would say the easiest way is practicing. Do lot of things. See your code fail deliberately. Fix your code. After a couple of decades, you'll feel it in your guts what solution is going to be good and which isn't. Using mathematics for that might help, but it is hard and it isn't the only way.
Cheers,
bzt