[HN Gopher] Writing a simple operating system from scratch (2010...
       ___________________________________________________________________
        
       Writing a simple operating system from scratch (2010) [pdf]
        
       Author : agomez314
       Score  : 298 points
       Date   : 2022-03-25 11:14 UTC (11 hours ago)
        
 (HTM) web link (www.cs.bham.ac.uk)
 (TXT) w3m dump (www.cs.bham.ac.uk)
        
       | 0x20cowboy wrote:
       | This looks cool for x86. Somewhat along these lines, is there a
       | piece of software that lets you emulate chips, connections and
       | custom built systems?
       | 
       | I've been trying to play with building an OS for riscv (and / or
       | maybe pic32) using qemu, but I'd like to simulate my own display,
       | keyboards and other components.
       | 
       | Basically a digitised bread board where you can send compiled
       | code to emulated chips and run.
        
       | billpg wrote:
       | I tried writing a simple OS decades ago as an EXE you'd run from
       | MSDOS. It would rewrite all the ISR vectors and take over all the
       | memory including the space that was previously used by MSDOS. I
       | was told that because I relied on DOS, whatever I wrote was not
       | an operating system. I politely disagreed.
        
         | dasyatidprime wrote:
         | See also both Windows 3.1 and the "DOS extenders" used to build
         | applications that were launched from DOS but ran in protected
         | mode with additional facilities.
        
           | billpg wrote:
           | The same guy insisted to me that Windows (pre-95) was not an
           | Operating System either, for the same reason mine wasn't.
        
             | rep_lodsb wrote:
             | Win9x also uses DOS as a boot loader :)
        
         | knorker wrote:
         | LOADLIN could load linux from DOS. And being a .EXE it relied
         | on DOS to bootstrap.
         | 
         | So yes, if you didn't use the DOS code (I mean... you overwrote
         | it), then DOS is not there. And if DOS is not the OS, that just
         | leaves your code to be the OS. :-)
        
       | rmasters wrote:
       | From the PDF: "It is true: in our quest to make full use of the
       | CPU, we must abandon all of those helpful routines provided by
       | BIOS. As we will see when we look in more detail at the 32-bit
       | protected mode switch-over, BIOS routines, having been coded to
       | work only in 16-bit real mode, are no longer valid in 32-bit
       | protected mode; indeed, attempting to use them would likely crash
       | the machine.
       | 
       | "So what this means is that a 32-bit operating system must
       | provide its own drivers for all hardware of the machine (e.g. the
       | keybaord, screen, disk drives, mouse, etc). Actually, it is
       | possible for a 32-bit protected mode operating system to switch
       | temporarily back into 16-bit mode whereupon it may utilise BIOS,
       | but this teachnique can be more trouble than it is worth,
       | especially in terms of performance."
       | 
       | --
       | 
       | In the toy 32-bit OS I am currently writing, having easy disk
       | access and text output was more important to me than performance,
       | so I decided to implement this technique to access the disk and
       | screen via the BIOS instead of writing an ATA disk driver.
       | 
       | Although I could not find any minimal yet complete working
       | examples of dropping to 16 bit and later resuming 32 bit mode, I
       | was able to piece it together and write assembly functions called
       | enter_16bit_real and resume_32bit_mode. See
       | https://github.com/ironmeld/builder-hex0/blob/main/builder-h....
       | Those routines are working well but beware the project is a
       | volatile work in progress and is coded in hex for bootstrapping
       | reasons.
        
         | afr0ck wrote:
         | If you are running your OS on a VM hypervisor (e.g.; Qemu,
         | kvmtool), then you can just use virtio for disk and network
         | I/O. No boring and complex device specification (e.g.; ATA) to
         | implement.
        
           | rmasters wrote:
           | Yeah, I'm avoiding modern interfaces due to my peculiar
           | bootstrapping requirements (e.g. must run on old HW; no SW
           | dependencies). virtio is probably a better choice for anyone
           | trying to build something practical. On the other hand, it
           | looks like using virtio would need a lot more code than
           | accessing the BIOS and I couldn't easily find examples in
           | assembly.
        
         | chungy wrote:
         | Windows 3.1, 95, 98, Me all did exactly the thing described as
         | "more trouble than it is worth"; they are 32-bit protected mode
         | operating systems[0] that makes frequent context switches to
         | 16-bit mode and utilize BIOS functions.
         | 
         | [0] Yes, I know, Windows 3.1 applications were almost always
         | 16-bit unless you installed Win32S. It's somewhat complicated.
        
           | smhenderson wrote:
           | I guess in their case they had so much already written code
           | to work with BIOS calls it was worth adding the shim layer.
           | But if you were to start tomorrow with no legacy code then it
           | would be more trouble than it's worth.
        
             | chungy wrote:
             | That is the story of Windows NT after all :)
        
       | ale42 wrote:
       | Would be nice to see this updated for UEFI!
        
         | BirAdam wrote:
         | UEFI kind of is an OS. you can read the UEFI docs and get a
         | general idea of what is required.
        
       | chimbosonic wrote:
       | I really enjoyed doing the OS course at UoB. Awesome to see UoB
       | paper trending on Hacker News. This was also one the easiest to
       | follow "tutorials" on making a OS from scratch I've followed.
        
       | tachim wrote:
       | Can't recommend https://www.cs.cmu.edu/~410/ enough.
        
         | bogomipz wrote:
         | Are these lecture online anywhere? The lectures in the menu
         | just redirects to a login page.
        
       | Decabytes wrote:
       | I know there must be, but are there examples of people using the
       | linux kernel as a base but having a radically different userland
       | from traditional linuxes? I feel like all the Gnome and KDE
       | Distros feel really samey whether they are arch or debian based
       | (this isn't necessarily a bad thing!).
        
         | edgyquant wrote:
         | Android is the goto example afaik
        
         | ben_bai wrote:
         | Android, ChromeOS, ...
        
       | bogomipz wrote:
       | This looks like a nice guide. I had a couple of questions.
       | 
       | When reading the "entering protected mode" section I started to
       | question my own understanding of some the details. My first
       | question is:
       | 
       | When a CPU starts up in real mode it's running in a kind of
       | privileged state since there are none of the 4 protection rings
       | that protected mode give us. We then build a GDT and switch the
       | CPU to protected mode. In practical terms where does this code
       | live GDT building and long mode jump code live? Is it in GRUB or
       | whichever stage 2 bootloader is in use?
       | 
       | My second question was about the "chicken and egg" situation
       | about how the kernel code inherits that privileged address space
       | defined marked with ring 0 bits in the GDT. Is magic that once
       | the GDT has been defined, when we subsequently decompresses the
       | kernel into those memory addresses the kernel memory will have
       | ring 0 bits in its descriptors?
       | 
       | This is how I've understood it but I've often found the texts
       | about this a little murky and this part still feels a bit like
       | magic to me I guess.
        
         | afr0ck wrote:
         | For the first question, it can be done in various ways. It can
         | be done by the firmware or the bootloader for you, or you can
         | do it by yourself once the platform jumps to your kernel code
         | upon machine startup.
         | 
         | For the second question, you just build your GDT entries with
         | the highest privelege, then you switch to protected mode.
        
           | bogomipz wrote:
           | I understand about that you build your GDT entries and mark
           | them all with privilege bit set to 0. However at that point
           | your kernel is still sitting as a compressed image on disk.
           | This is the disconnect I seem to have. We have an in memory
           | data structure that's the GDT and we have kernel image that
           | still on disk. How are those GDT entries allocated to the
           | kernel?
        
             | rep_lodsb wrote:
             | As you observed before, real mode is also privileged. Both
             | before and immediately after enabling protected mode, the
             | code segment you are running from is already "ring 0" (even
             | if it wasn't loaded from a GDT descriptor), and so it is
             | allowed to transfer control to the "proper" kernel code
             | segment.
        
               | bogomipz wrote:
               | Thank you. For clarification is that same code segment
               | from real mode sort of automatically "remapped" then to a
               | descriptor in the GDT after CPU transitions into
               | protected mode? Is that correct mental model?
        
               | rep_lodsb wrote:
               | No, how would that even work?
               | 
               | The OS (or loader) is responsible for setting up
               | descriptors and managing memory. In 64-bit and most
               | 32-bit kernels, segmentation is basically not used
               | anymore, and the descriptors are just flat address spaces
               | (all start at 0, no limit) with different privilege
               | levels.
               | 
               | Example of 32 bit flat GDT:                   0000 (null
               | descriptor; reserved by hardware and can't be used)
               | 0008 kernel code (ring 0)         0010 kernel data (ring
               | 0)         0018 user code (ring 3)         0020 user data
               | (ring 3)         0028 TSS (hardware defined structure)
               | 
               | Isolation between processes would then be done through
               | the page mapping mechanism. This is kind of hard to wrap
               | your head around at first, but makes it much easier to
               | allocate memory. One big problem with using segments
               | instead of fixed-size pages is that when you need to free
               | them in some random order, memory becomes fragmented.
               | 
               | But you can also have segments _in addition_ to paging,
               | which is helpful for transitioning from /to 16-bit mode.
               | 
               | Hope that helps at least a little bit!
        
               | bogomipz wrote:
               | Sorry "remapping" was a poor choice of words on my part.
               | 
               | What I meant was the code segment register gets reloaded
               | to some offset in that GDT that has those protection bits
               | set to 0. According to your flat address space map above
               | that would be at offsets 0008 and 0010. That makes a lot
               | of sense, thanks.
        
       | igravious wrote:
       | Tangentially, does anyone remember "Developing Your Own 32-bit
       | Operating System" (1995) by Richard Burgess ? I was absolutely
       | fascinated by this back in the day. Misplaced some of my computer
       | books (Design Patterns, this, a few others) on my travels so
       | don't have it to hand any more. Was gob-smacked that it took what
       | seemed like mere nanoseconds to boot on bare x86 hardware.
        
         | edgyquant wrote:
         | I have this from a decade ago when I was trying to build my own
         | OS. I think Tannenbaums book has probably stood the test of
         | time more but it was a great resource regardless.
        
       | rbanffy wrote:
       | At the core of almost every 8-bit computer game there is a
       | cooperative multitasking kernel, without memory protection
       | (because, of course, there is none), running multiple little
       | taska - updating the screen, reading inputs, moving characters,
       | checking if someone exploded, clicking the speaker to make some
       | sound, etc.
       | 
       | It was a lot of fun!
        
       | knorker wrote:
       | Errata:
       | 
       | Page 37 says that pipelining is the reason we need to jmp after
       | setting 32bit mode in CR0, but that's not true. The execution
       | mode is part of the CS descriptor, and setting CR0 merely means
       | that "on next segment (CS:EIP) jump" we should treat the segment
       | part not as a 16bit segment, but as a segment descriptor
       | selector.
       | 
       | Otherwise, dude, that would be a race against the pipelining with
       | undefined behaviour.
       | 
       | So no, pipelining is an implementation detail you _STILL_ don 't
       | have to care about.
       | 
       | Like, do you know the instruction pipeline length on a 386SX? No,
       | because you don't have to. There's no rush to jump. (though what
       | else are you going to do?)
       | 
       | Actually, you could continue executing 16bit code, loading only
       | DS/ES with 32bit selectors. Why, I don't know, but you could.
       | 
       | > a near jump[...] may not be sufficient to flush the pipeline
       | 
       | Nope, that's not it. You are literally jumping into a 32bit
       | address space by loading the descriptor. The descriptor is not
       | loaded until you load a new selector into CS by using a far jump.
       | 
       | Mind you, this is from memory when I made my OS in high school.
       | Back when there was a lot of moving floppies back and forth to
       | iterate. :-/
       | 
       | For more on this (and the resource I wish I had back then), see
       | https://wiki.osdev.org/
        
         | userbinator wrote:
         | _Actually, you could continue executing 16bit code, loading
         | only DS /ES with 32bit selectors. Why, I don't know, but you
         | could._
         | 
         | That's almost how flat real mode (aka "unreal mode") works,
         | except it's _returning_ from protmode with 4GB selector limits.
        
         | rep_lodsb wrote:
         | This probably no longer applies in any way to modern
         | processors, but the 286 and 386 did have a "prefetch queue"
         | (containing opcode bytes fetched from CS:eIP), as well as a
         | "decoded instruction queue".
         | 
         | Up to 3 instructions could be pre-decoded and stored in that
         | queue, while the execution unit was still busy with some other
         | instruction (keep in mind that back in the day it was multiple
         | clock cycles per instruction, not multiple instructions per
         | cycle!)
         | 
         | Each decoded instruction included a microcode entry point
         | address, depending on the opcode and the state of CR0 _at the
         | time of decoding_. On the 486 this was further optimized to
         | actually store the first micro-op in that queue.
         | 
         | If you set the "Protect Enable" bit in CR0, it does not affect
         | instructions that have already been through the decode stage,
         | so they would not run with protected mode semantics. A _far_
         | jump would actually not work in that case, because it would
         | load the CS base with (selector  << 4) instead of going through
         | the descriptor table. So you should first do a _near_ jump to
         | flush the pipeline, and only then jump to the protected mode
         | CS.
         | 
         | In practice, you could get away with not doing this step,
         | depending on the exact timing of the code used to switch to
         | protected mode. A lot of instructions are short enough that the
         | processor never has enough time to pre-decode anything
         | following.
         | 
         | The Intel manuals did (and still do?) document you have to do
         | this near jump first, though not the exact details of why.
        
           | knorker wrote:
           | Oh yeah, thanks for the context. Checking my old OS it seems
           | I did do that near jump too. I'd forgotten about that.
           | 
           | It looks like the author of this PDF confused the two jumps.
           | 
           | Looks like Linux nowadays does the far jump immediately after
           | setting cr0, thus doing two in one:
           | 
           | https://github.com/torvalds/linux/blob/master/arch/x86/boot/.
           | ..
           | 
           | But the near and far jump (if you use both) still have VERY
           | different purposes. And the CPU is not really in 32bit mode
           | until all the segment descriptors have been loaded manually.
           | 
           | Linux didn't used to combine them:
           | 
           | https://elixir.bootlin.com/linux/2.2.26/source/arch/i386/boo.
           | ..
           | 
           | Here we see the near instruction-flushing jump, then a bunch
           | of code (that is still in 16bit mode!), and then the long
           | jump that switches the instruction set to 32bit.
           | 
           | The comments in that last link explains it well, too.
        
             | rep_lodsb wrote:
             | The point is that the CPU might still be in real mode at
             | the point in time when the far jump is decoded, and thus
             | execute it with real mode semantics. Coding a seemingly
             | useless near jump was the way to prevent that.
             | 
             | Whoever wrote the modern Linux code doesn't seem to
             | understand any of this. There is even a jump _before_ the
             | switch to protected mode, with the comment  "Short jump to
             | serialize on 386/486". Cargo-cult programming at its finest
             | :)
             | 
             | As I said before, it may have always worked in practice
             | without the jump, and modern Linux doesn't even support the
             | 386 anymore.
             | 
             | Actually, with all the crazy out-of-order speculative
             | execution going on, one could expect newer CPUs to have
             | similar requirements, but I guess they also _had_ to get
             | better at providing the illusion that such internal details
             | don 't matter. Making LMSW / MOV CR0 a serializing
             | instruction seems to be an easy way to do it.
        
               | knorker wrote:
               | > the CPU might still be in real mode at the point in
               | time when the far jump is decoded,
               | 
               | It definitely is in real mode when the far jump is
               | decoded. Or is that not the right technical definition of
               | "real mode"?
               | 
               | Do we leave real mode as soon as CR0 bit 1 is set, even
               | though nothing has changed until the code puts a new
               | value into a segment register? I've always thought of it
               | as when CS becomes 32bit, meaning the long jump.
               | 
               | Anyway, that's just terminology.
               | 
               | > "Short jump to serialize on 386/486". Cargo-cult
               | programming at its finest :)
               | 
               | That's weird. I tracked down the commit:
               | 
               | https://github.com/torvalds/linux/commit/2ee2394b682c0ee9
               | 9b0...
               | 
               | > Actually, with all the crazy out-of-order speculative
               | execution going on
               | 
               | I would expect those to detect that dependency and not
               | take effect. But I could be wrong.
               | 
               | Edit:
               | 
               | Interesting. The new Intel docs explicitly say to do the
               | far jump "Immediately" after setting the PE bit in CR0.
               | 
               | https://www.intel.co.uk/content/www/uk/en/architecture-
               | and-t... section 9.9.1.
               | 
               | Whereas the example code for the original 386 programming
               | manual has the short jump, many other instructions, and
               | then the far jump.
               | 
               | Haha, but then the actual example code on page 9-20 (new
               | manual) still has the "clear prefetch queue" near jump.
        
               | rep_lodsb wrote:
               | >Do we leave real mode as soon as CR0 bit 1 is set
               | 
               | Yes, that's what the bit is defined as doing. Protected
               | mode was introduced on the 16-bit 80286, and 16-bit code
               | segment descriptors are still supported to this day.
               | 
               | Even in real mode, the segment registers have hidden
               | fields containing base, limit and access rights. The
               | difference is that when they get loaded in real mode, the
               | base will be set to the segment shifted left by 4 bits,
               | with the limit1 and access rights2 generally left
               | unchanged. What the PE bit actually affects is how
               | segment load instructions operate, how
               | interrupts/exceptions are handled, and a few other
               | details.
               | 
               | Most instructions run exactly the same microcode in
               | either mode: any memory access will form the address and
               | do protection checks based on whatever is currently in
               | those hidden fields. But a segment load (or far jump)
               | decoded while PE=0 will execute different microcode than
               | one with PE=1.
               | 
               | >That's weird. I tracked down the commit
               | 
               | Shuffling the code around may have fixed some alignment
               | bug? The jump could likely be replaced by two NOPs, in
               | any case the comment is completely wrong.
               | 
               | 2.6.22 seems to be the last version using LMSW followed
               | by a near jump, and presumably worked on that CPU (at
               | least there is a comment mentioning bugfixes for Elan),
               | so it isn't likely to be the cause of the problem.
               | 
               | 1 the limit on power-on/reset is 64K, but it is possible
               | to change it to 4G, allowing access to all memory
               | ("unreal mode")
               | 
               | 2 CS will always be made a writable data segment,
               | something not possible to set up in protected mode
               | without the use of LOADALL
               | 
               | edit: >Interesting. The new Intel docs explicitly say to
               | do the far jump "Immediately" after setting the PE bit in
               | CR0.
               | 
               | Well, it's probably not required to do any kind of jump
               | immediately on modern CPUs, but it wouldn't be the first
               | time Intel got something completely wrong:
               | https://www.os2museum.com/wp/sgdtsidt-fiction-and-
               | reality/
        
       | NoOn3 wrote:
       | https://www.udemy.com/course/writing-your-own-operating-syst....
       | If someone interesting It's good course for OS kernel
       | development. Using this course, I was able to write a 64-bit
       | kernel with memory management, user space, file system, shell. It
       | only lacks an ata disk driver for something like minimum complete
       | kernel. https://github.com/JustVic/melisa_kernel. Sorry for the
       | ads.
        
         | sidmitra wrote:
         | This is the course the above comment mentions, since the
         | original link redirects to a login page.
         | 
         | https://www.udemy.com/course/writing-your-own-operating-syst...
        
           | NoOn3 wrote:
           | Yes. This is this course. Maybe your link better.
        
       | jesprenj wrote:
       | https://sortix.org
       | 
       | quote:
       | 
       | Sortix is a small self-hosting operating-system aiming to be a
       | clean and modern POSIX implementation.
       | 
       | It is a hobbyist operating system written from scratch with its
       | own base system, including kernel and standard library, as well
       | as ports of third party software. It has a straightforward
       | installer and can be developed under itself. Releases come with
       | the source code in /src, ready for tinkering
        
       | a-priori wrote:
       | Nowadays, I would recommend not using BIOS booting. Modern
       | machines with UEFI firmware only emulate BIOS anyway, for
       | backwards compatibility with old bootloaders.
       | 
       | UEFI gives you a much nicer initial environment -- it's already
       | in 64-bit long mode, for example, unlike BIOS which drops you
       | into 8-bit real mode, with a maximum of one sector in which to
       | perform all the gymnastics you need to do to load the rest of
       | your program and switch to _at least_ 32-bit protected mode
       | (notice how this PDF doesn't even go to 64-bit long mode).
       | 
       | UEFI also gives you better, easier to use boot facilities than
       | BIOS: you can access a memory map, read from the boot file
       | system, switch video modes, and even access network drivers. And
       | you can access all this from long mode, unlike BIOS which only
       | works in real mode. Then once you've booted you can take over the
       | system by exiting the boot services, and have full control over
       | the system just like you want for making an operating system.
        
         | khaledh wrote:
         | If anyone is interested, I have a couple of implementations of
         | booting under UEFI and getting a bunch of info about the system
         | (don't expect a functioning system, they just boot and dump
         | some info):
         | 
         | Nim: https://github.com/khaledh/axiom
         | 
         | Zig: https://github.com/khaledh/axiom-zig (this one goes into
         | depth in disassembling ACPI DSDT bytecode)
        
         | kevin_thibedeau wrote:
         | BIOS boot is necessary for PCI cards with extension ROMs.
        
           | a-priori wrote:
           | I suppose it depends what you're going for, but in general I
           | don't think being able to fully support some very old PCI
           | devices should be the determining factor.
        
             | emteycz wrote:
             | That depends only on their own project goals. Retro
             | computing is a thing too.
        
               | a-priori wrote:
               | Yes of course. If your goals are retro computing, yes by
               | all means go ahead and use retro technology.
               | 
               | That's my point though: today, BIOS is retro technology.
        
               | emteycz wrote:
               | It's also good for learning. But I agree that most of
               | today's basic OS dev learning should rather be done with
               | UEFI and/or Virtio.
        
           | convolvatron wrote:
           | is that even still a thing?
        
             | kevin_thibedeau wrote:
             | I have one in a Ryzen system.
        
         | javajosh wrote:
         | You sound very knowledgable about UEFI - it is intimidating
         | since the spec is so big. It also...concerns me that _so much
         | code_ is running prior to my own, even if it is for a good
         | purpose. I get it that CPU mode selection and boot device
         | intitialization isn 't something most programmers want to deal
         | with, but doesn't putting it in UEFI firmware put it out of
         | reach of most programmers? Should we not aim to put as little
         | as possible into firmware?
        
       | billti wrote:
       | I notice this pdf and most of the links in this discussion are
       | for x86 architectures, and deal a lot with BIOS, getting out of
       | 'real' mode, etc.
       | 
       | Are there any such resources for ARM (preferably ARM64) that
       | would cover similar "Get a basic OS up and running" topics that
       | you could follow on a device or emulator?
        
         | incanus77 wrote:
         | This one's a little less theory and a little more tooling, but
         | is pretty modern:
         | 
         | https://www.rpi4os.com/
        
         | NoOn3 wrote:
         | Find another course about building arm arch kernel writing:
         | https://www.udemy.com/course/raspberry-pi-write-your-own-
         | ope.... I did not take this course, but I took another course
         | on architecture x86 from the same authors and it was pretty
         | good. I have already written a comment in this thread about the
         | course I took. Look for that my comment. It has the
         | disadvantage that it is paid. Sorry for adv again.
        
       | snvzz wrote:
       | I would love to see a modern such take, targeting RISC-V OS-A
       | platform and a microkernel, multiserver architecture.
       | 
       | There's far too many of these courses targeting x86-32 and the
       | deeply flawed UNIX architecture.
       | 
       | The closest we've got today is MINIX 3's book, Operating Systems:
       | Design and Implementation.
        
       | jonpalmisc wrote:
       | This PDF brings back memories. I went down this path about a
       | little over a year ago--it's great fun. I didn't end up finishing
       | anything significant but I'd highly recommend everyone give
       | writing a kernel or an OS a shot sometime. You will learn a whole
       | lot.
       | 
       | If you're interested, the OSDev Wiki [0] is a great place to
       | start, as are Bran's Kernel Development tutorials, which I can't
       | seem to find on mobile right now.
       | 
       | [0] https://wiki.osdev.org/Main_Page
        
       | userbinator wrote:
       | The boot sector is only 512 bytes, but if you're using Asm that's
       | actually more than enough for some nontrivial functionality.
       | Here's a few of many examples of "what fits in a boot sector"
       | that has appeared on HN:
       | 
       | https://news.ycombinator.com/item?id=21951241
       | 
       | https://news.ycombinator.com/item?id=20569438
       | 
       | https://news.ycombinator.com/item?id=25531677
        
         | agumonkey wrote:
         | and very recently https://justine.lol/sectorlisp2/
        
       | kuharich wrote:
       | Past comments: https://news.ycombinator.com/item?id=8380822,
       | https://news.ycombinator.com/item?id=11840573
        
       | upwork09 wrote:
        
       | curling_grad wrote:
       | I also found "The little book about OS development" useful.
       | 
       | https://littleosbook.github.io/
        
       | Dzugaru wrote:
       | Unfortunately, this (really nice) PDF isn't complete.
       | 
       | For me an Operating System means processes in userland, sadly it
       | comes short of that.
       | 
       | I'm now pushing my own x86 32bit OS in Rust using [0][1]:
       | 
       | There is definitely a shortage of information on this stuff (for
       | example writing a USB driver is really hard and I couldn't find
       | easily available tutorials - you have to resort to raw *HCI and
       | USB specs to get things done).
       | 
       | [0] https://wiki.osdev.org/Expanded_Main_Page
       | 
       | [1] https://os.phil-opp.com/
        
         | wrycoder wrote:
         | It appears that Chuck Moore gave up on a Colorforth
         | implementation of usb - he was probably disgusted with the
         | complexity.
        
         | progbits wrote:
         | Slightly off-topic: Anyone knows when the new edition of [1] is
         | supposed to come out? It's been so long and the articles are so
         | well written, I'm eagerly waiting for their UEFI rewrite to be
         | released...
        
         | gjadi wrote:
         | To understand the USB stack, I've used the following resources:
         | 
         | - the spec itself (obviously)
         | 
         | - USB Complete by Jan Axelson (quickly go through this one
         | before reading the spec)
         | 
         | - USB The Universal Serial Bus by Benjamin Lunt
         | (https://www.fysnet.net/the_universal_serial_bus.htm)
         | 
         | If you're writing your operating system, checkout other books
         | by Benjamin Lunt:
         | 
         | - https://www.fysnet.net/osdesign_book_series.htm
        
         | capableweb wrote:
         | > For me an Operating System means processes in userland, sadly
         | it comes short of that.
         | 
         | I'm no OS expert, besides using multiple of them daily, but
         | isn't there different categories of Operating Systems? The ones
         | you say are "A Real OS" are specifically multitasking OSes,
         | while there also exists a section of OSes that only runs single
         | tasks. Aren't those also real Operating Systems?
        
           | msla wrote:
           | If it doesn't run any other programs, it's more like firmware
           | than an OS.
        
           | bregma wrote:
           | I would argue a single program that runs on bare metal to
           | performs a specific purpose is not an "operating system". An
           | "operating system" is a program that runs on bare metal
           | (operates the system) and runs _other_ programs. Those other
           | programs are  "userspace" regardless of the security or IPC
           | model involved in communicating with the actual operating
           | system.
        
             | matt_heimer wrote:
             | Userspace typically makes people assume a security model,
             | Ring 0/3, etc.
             | 
             | I think of an Operating System as something that provides a
             | Hardware Abstraction Layer (HAL) and system calls to take
             | advantage of that hardware. Drawing on the screen without
             | knowing the details of the video card, file io without
             | caring about IDE/SCSI, etc.
             | 
             | If it runs other programs but those programs still need to
             | take direct control of the hardware then the OS is just a
             | glorified boot loader.
        
             | l33t2328 wrote:
             | > runs other programs
             | 
             | This is a lot weaker of a statement than
             | 
             | >processes in userland
             | 
             | Even if you take a very broad definition of userland.
        
             | skissane wrote:
             | Pick R83 is an (8086 real mode) operating system for the
             | IBM PC. It runs a byte code virtual machine, and has a
             | compiler for a dialect of BASIC which generates that byte
             | code as output. Most programs were written in BASIC,
             | although the system also had a byte code assembler and some
             | system-level software was written in that instead. Its
             | filesystem is rather primitive in some ways (it only has
             | single-level directories, a directory cannot contain
             | subdirectories), but at the same time supports key-indexed
             | files, which was essential for the business database
             | applications it was used to run. There was never (as far as
             | I know) a C compiler, although in principle someone could
             | have compiled C to the same bytecode that BASIC was
             | compiled to. It is multi-tasking and multi-user, albeit its
             | security is rather primitive by today's standards (as one
             | might expect for a real mode 8086 operating system). Does
             | that count as "running _other_ programs "? If it does, just
             | make your "single program" be an interpreter (Tcl, Lua,
             | whatever you wish) and now you have a "real operating
             | system".
             | 
             | (The byte code for R83's VM, called Pick assembly, came
             | from Pick's earlier non-PC hardware systems, in which it
             | was actually the hardware machine language, implemented by
             | microcode; I believe the parts of the system which ran on
             | top of the VM were a pretty direct port from those earlier
             | platforms. R83 was succeeded by Advanced Pick, which
             | supported both running as a standalone OS - AP/Native - or
             | as a process on top of a host OS - AP/Unix and AP/DOS.
             | AP/DOS was later succeeded by AP/NT for Windows NT, and
             | Advanced Pick eventually evolved into D3, which is still
             | around - now sold by Rocket Software. D3's virtual machine
             | environment, VME, is a direct descendant of the same byte
             | code VM, although it now supports much deeper integration
             | with the AIX/Linux/Windows host platform than the original
             | hosted AP versions did. Early MUMPS systems were similar in
             | being hosted directly on the hardware, but Pick as an
             | operating system arguably lasted a decade or more longer
             | than MUMPS as an operating system did.)
        
           | Dzugaru wrote:
           | Sure, there is a gradient of complexity here, first you can
           | just do your stuff in kernel in a single thread, then you'll
           | probably want to load programs and execute them in userspace
           | [0], then you'll want multitasking and task scheduling,
           | memory isolation and process syncronization etc. You can call
           | any of those steps an OS of course, its just I personally
           | find earlier steps not that interesting.
           | 
           | Another one great resource (that actually inspired me to
           | tinker with all this awesome stuff) is this book [1]
           | 
           | [0] https://wiki.osdev.org/Getting_to_Ring_3
           | 
           | [1] https://pages.cs.wisc.edu/~remzi/OSTEP/
        
         | pdonis wrote:
         | _> this (really nice) PDF isn 't complete._
         | 
         | It is for the author's definition of "complete", which he gives
         | explicitly early on in the paper.
         | 
         |  _> For me an Operating System means processes in userland_
         | 
         | As the reference to the author's late professor in the
         | introduction to the paper will show you, it hasn't always been
         | so. Once upon a time, an "operating system" just meant "the
         | code you have to write before you can do anything at all with
         | this computer". That code could be anything from a special-
         | purpose system for one particular task, to something like MS-
         | DOS, which could run other programs but had no notion of
         | "processes in userland" (because there wasn't any "userland",
         | every byte of code ran on the bare metal), to the kind of
         | multi-tasking system we now generally think of when we think
         | "operating system", like Linux or Windows or Mac OS X.
        
         | jhgb wrote:
         | I'm sure that there's plenty of operating systems where there
         | isn't "userland" in the common sense.
        
           | terracatta wrote:
           | TempleOS comes to mind.
        
             | paskozdilar wrote:
             | PhantomOS too.
             | 
             | Although there's still "userland" in Phantom, it's just
             | that it uses type safety for memory protection, instead of
             | MMU.
        
       | erwincoumans wrote:
       | From a glance, it looks interesting to get started.
       | 
       | Reminds me of some 'bare metal OS' series for Raspberry Pi:
       | https://www.rpi4os.com and
       | https://s-matyukevich.github.io/raspberry-pi-os and
       | https://github.com/rsta2/circle
       | 
       | Recent x64 AMD and Intel PC's use UEFI secure boot and require
       | signed boot images, so this simple approach won't boot out-of-the
       | box anymore I suspect. Same for Mac M1. So some update would be
       | useful, without requiring to disable UEFI secure boot.
        
         | nurettin wrote:
         | Is this UEFI something you have to design your OS around, or do
         | we get away with a simple "how to sign custom kernel image"
         | search?
        
           | emteycz wrote:
           | You can't sign your custom kernel, only Windows can be signed
           | and signing has to be disabled for Linux and other OS.
           | 
           | UEFI offers some basic IO functionality, it's like BIOS in
           | that regard. You don't design your OS around it, you use it
           | to have easy graphics, networking etc during boot time, then
           | you switch to your own drivers and don't touch UEFI again.
        
           | erwincoumans wrote:
           | Custom signing will do of course, this is just out of
           | curiosity.
           | 
           | https://ubuntu.com/blog/how-to-sign-things-for-secure-boot
        
         | cillian64 wrote:
         | I've never come across an amd64 system where secure boot
         | couldn't be disabled in the BIOS (as you'd do when installing
         | Linux) - do you have any examples of this?
        
           | the_only_law wrote:
           | Not OP, but I'm pretty sure I've seen more and more firmware
           | lately that does not want to give me any usual functionality
           | at all.
        
             | emteycz wrote:
             | Demand your money back, only Windows can be signed, so the
             | device is not up to spec if you can't disable it.
        
           | erwincoumans wrote:
           | Of course you can switch secure boot off. I am just
           | interested in a solution that boots with security on: just
           | out of curiosity, this is about learning after all.
        
       ___________________________________________________________________
       (page generated 2022-03-25 23:01 UTC)