check out MikeOS. Its a fairly simple OS written is readable (as in commented) assembly. Even though its fairly simple, it does have a GUI and supports some networking and multimedia.
edit: MenuetOS is graphical. Its also written is straight asm, but its more sophisticated than MikeOS
Try to read the code of a small, basic open-source OS, such as MikeOS.
Alternatively, I suggest the following steps (should be fun!):
Write a virtual machine. Define all your processor instructions so that you know your system inside and out. Interface it with SDL for keyboard, mouse, screen, audio access. Keep it simple so that you can fit everything in your head at once. It doesn't need to be a state-of-the-art virtual machine, just one that can emulate the function of a 'real' computer.
Write an assembler for your virtual machine's processor. Remember that this assembler need not be a program written in the virtual machine's language, but anything that can convert your assembly language to machine code.
Define an executable format, and write a simple linker.
You've got all the parts to write your operating system now! Write it in the assembly language, assemble it ... etc .. you don't need such a complicated bootloading process, just get your machine to run your OS first.
The above steps may seem kinda stupid for writing a simple OS, but hey, it's damn fun.
Most of the structured approaches (textbook or college class) will walk you through the process, but they supply a lot of the nitty-gritty code that glosses over the arcane details of your chosen platform and lets you focus on the big-picture ideas: process scheduling, memory management, deadlock prevention, I/O, and so forth.
My advice is this: cut way back on your expectations and start with a basic question.
What is an operating system?
A computer scientist will (hopefully) never say that an OS is a graphical user interface, or a web browser, or a way to hook up USB devices, or anything that a user can actually see or touch. Instead, an OS at its most fundamental level are those things I mentioned above. They all fall under one big umbrella: resource management.
An operating system is nothing more than a program that manages the hardware resources of the computer: memory, CPU, and peripherals.
Here's a simple operating system: a program lets the user type in a program (in hexadecimal or binary) using a serial connection. Once the program has been typed in, it runs the program. When the program is finished, control is returned to the user where they can either run the program again or type in a new one.
Do this on a "clean" architecture such as an embedded ARM processor with 64K of memory or so. You can code this up in assembly after a few days of learning the ins and outs of the ARM. And voila!, you've got yourself an operating system.
It does everything an OS is supposed to do:
It manages memory by not letting the user overwrite the OS itself.
It schedules a single process to run.
It handles the I/O to the single serial peripheral.
This gives you a building block to start from. You have many choices now. Perhaps one of them would be to allow two programs to be loaded into memory and let the user decide which one to run next.
Or you could let the user suspend execution of one program, switch to the other, suspend, and switch back. This is rudimentary multitasking, even though it's entirely manual.
Your choices are unlimited but each one is a baby step from what you had before.
Many schools have OS classes that do much of what you describe. My school (CMU) taught OS in C, and we wrote a kernel, file system, and shell, and were provided with code for a boot loader.
Unfortunately, I wasn't able to find any definitive resource for this course (15-412) on the web, and it's evolved over time. But perhaps people could post links to sources and assignments for schools that do have good resources on the web.
Study the A2 System (formerly called the Oberon system) for ideas you can steal. It is a graphical OS built by just two people, although admittedly one is Niklaus Wirth. First released around 1990 and the speed is astonishingly good. There is a book by Gutknecht.
你会意识到,在 PC 上有很多不清楚的东西:x86 指令集本身很复杂,当你直接访问硬件时,可能需要相当长的时间才能理解如何在屏幕上书写单个字符。
不用担心软盘之类的,大多数时候你会使用模拟器,例如Bochs或QEmu。
About low-level graphics programming, this will give you a lot of information: http://www.osdever.net/FreeVGA/home.htm. (It's very interesting for text mode as well.)
What will I undoubtedly run into that will confuse me?
You will realize that on PC there's an awful lot of stuff that is unclear: the x86 instruction set itself is complicated, and when you get direct access to hardware, it can take quite a while before you understand how to write a single character on screen.
Don't worry about floppy disk and such, most of the time you will use an emulator such as Bochs or QEmu.
我最有用的建议是让自己进入一种可以尽快运行 C 代码的状态——即启动、设置描述符表,并让自己达到可以安全运行编译的 C 的程度。如果不是所有的内核都应该用 C 编写,如果你想保持理智并继续努力的话。 虽然在某些地方需要组装,但组装很乏味并且往往难以调试。
I would suggest working, at least at first, on Bochs or some other virtual machine the reason being that you can take it with you wherever you want, it's easier to debug (you can see the exact state of the hardware), and if you need outside help debugging they can use the exact same 'hardware' as you.
The most useful advice I have is to get yourself into a state where you can be running C code as quickly as possible -- i.e. boot up, setup your descriptor tables, and get yourself to a point where it's safe to run compiled C. Most if not all the kernel should be in C if you want to stay sane and keep working on it. Assembly, while required in some places, is tedious and tends to be hard to debug.
You might want to consider taking a look at Operating Systems Concepts, by Abraham Silberschatz - Understanding Systems Programming concepts is a fundamental requirement, take a peek into F/OSS kernel internals of OSes linux *BSD and GNU/Linux, especially earlier versions, which are probably a bit more documented.
Take a look at Minix. Study the source code along with "Operating Systems Design and Implementation". Consider making contributions to the project. I think Minix is a really good and promising OS in the making. It is also well funded project. That means, you might even get paid for your contributions!
It is very easy thanks to the fact that the BIOS already have many input/output functions built into it for changing screen mode, changing pixel color, writing text to the screen and many other things. However, it does not include support for file systems, that is one of very few things you must incorporate in your OS.
The BIOS loads the first sector on the hard drive and starts executing the code from there, so your OS must be placed with the first instruction in the first sector on the hard drive.
This Wikipedia article should get you started on BIOS interrupts for writing text to the screen, receiving keys from the keyboard and other stuff. https://en.wikipedia.org/wiki/BIOS_interrupt_call
Even if you plan to use c++ I would strongly recommend reading up on assembly programming, as it is vital to understanding how the hardware works.
当然,您可以从使用 PC 键盘和视频的控制台驱动程序开始(如果我没记错的话,分别是 BIOS INT 0x16h 和 INT 0x10H 内容)。 但是,我建议从串行驱动程序开始,因为您可以从任何其他现有(功能)系统自动化构建/部署/测试周期。 由于您的新操作系统将作为交叉编译项目启动,因此您必须有一种简化的处理方式。
At its lowest level the minimum that an operating system needs to be able to do is to drive a system's hardware in some way and somehow load an execute some sort of "user code." If you're going to start with a PC then you need to write code that can be loaded by it from some device or another. Older PCs have a BIOS in firmware which determines how the hardware performs some initialization (at least video, keyboard, and some form of storage or boot loader). (Update October 2017: Newer PCs have EFI or UEFI firmware ... which is largely a pedantic difference; the serve the same purposes for this discussion).
So start by learning the low level details of how to use the BIOS or other firmware, on your target system. That is, learn how to write a program that the BIOS can load and execute. That will eventually morph into your boot loader. Start small. Just get a program that prints: "Hello, Linus" directly from the firmware boot process (on a floppy, or USB thumb drive, would be a good start ... or on a hard drive if you like).
From there I'd recommend writing a very simple serial driver ... update your boot loader to initialize some serial port, and start a download there from. Then it can execute the code it pulls across. From there write a bit of bootstrap that can write to another set of blocks (we haven't implemented a file system yet ... not even partition table parsing; so we'd just deal with raw ranges of blocks on the disk at first).
At that point your boot loader should be able to pull new code across the serial line, dump it into a partition (yes, implement partition table handling of some sort ... whether it conforms to standard PC conventions is up to you at this point), and execute it.
From there you should be able to work on far more sophisticated features. From this base you can write and compile a new "kernel" ... reboot your testbed, and have the new kernel deployed to it.
(Your bootloader should take some signal, such as a BREAK over the serial handshaking lines as a command to skip the download and just boot the existing image; and it should handle some timeout in this way as well).
From there write a very simple terminal layer and command shell? A filesystem? Implement commands to download new executable content other than the kernel (files or objects of some sort). And so on.
Naturally you could have started with a console driver using the PC keyboard and video (the BIOS INT 0x16h and INT 0x10H stuff, respectively, if I recall correctly). However, I'd suggest starting with a serial driver since you can then automate your build/deploy/test cycle from any other existing (functional) system. Since your new OS will start as a cross-compiled project it's going to be essential for you to have a streamlined way of handling that.
I don't know how far you want to take your project. A reasonably impressive goal would be to achieve "self hosting." If you can create a simple assembler/compiler that can allow you to use your new OS to (re-)build, link, and boot into a working version of your new OS ... then you've achieved that goal. (Note that's not a requirement. Many embedded systems are never going to be self-hosting and there's nothing wrong with that).
I would start small and purchase an 8086 embedded development kit, and develop a multitasking OS on that. Once you have a kernel and are acquainted with working at the hardware level, you will be ready to do something more challenging.
Building even a VGA display DOS clone is a fairly challenging thing. The details are enormous. :-)
specific topics.
How do I put the code onto the computer? Is it best to do it with a floppy disk? Can most computers do it from a USB stick?
The BIOS will do elementary bootstrapping.
What drivers do I need, and can you suggest any references to building those?
anything that isn't direct cpu/memory operations. Anything that isn't directly in the CPU reference manual.
After the booting sequence--then what? How do I get into protected mode etc.
Protected mode will be part of the boot sequence.
then you start multitasking and figuring out how to start processes.
How do I manage memory without the help of an operating system? Do I just use whatever addresses I want? No initialization necessary?
Correct. You will probably want to sort out a virtual memory system eventually.
What will I undoubtedly run into that will confuse me?
not having debugging tools, not having IO
How can I make it either a command line O/S, and a graphical one?
With grief. Look up Windows 3.1 and Linux, in particular X windows.
What is a graphical O/S built on? Like, how would I do something like, a command line, with a font, and a picture at the top?
Look up X windows.
final advice: study linux/x windows. It's not perfect, but it provides an understanding of one approach. Also study embedded systems.
If you don't mind using hardware virtualisation, there is a course (book + lectures + software) that will take you 'From Nand to Tetris'. You create a full computer system entirely yourself from the (for these purposes atomic, and given) electrical NAND gate, right through to building the OS, a language, and finally coding a simple game on your personal machine.
I think it's a great idea and something I fully intend to get stuck into soon. The book is surprisingly cheap and I believe the course is taught at MIT. I can imagine no greater feeling than having the full, complete knowledge of an entire system you built yourself from the ground up.
如果您想要从裸机实现操作系统的体验,那么有比旧 PC 更好的硬件选择。 使用 PC 架构,您将花费大量时间围绕其 30 年设计历史中无趣的工件进行编码。 例如,仅项目的引导加载程序部分就可能让许多勇敢的程序员精疲力尽。
例如,您需要一组驱动程序来从磁盘和/或网络读取内核。 然后您需要代码才能进入保护模式。 那时,您需要另一组驱动程序! 在那之后,您为使芯片进入保护模式所做的工作很少可以转移。 您想在另一台 PC 上运行它 +- 4 年,并且您将需要另一组驱动程序。
研究引导 ARM 或其他 32 位“嵌入式”芯片。 提供廉价的开发板,或者您也可以焊接自己的开发板! 有些具有内置以太网和 USB。 我认为你会在一个理智的、非硬性的架构上工作得到更多的乐趣,并且也许最终会获得一些可重用的技能。
I see plenty of good references to OS development sites, so I'll describe a different approach:
If you want the experience of implementing an OS from bare metal, there are way better hardware choices than an old PC. With the PC architecture, you will spend an inordinate amount of your time coding around uninteresting artifacts of its 30 year design history. For example, just the bootloader part of the project has probably burned out many a brave programmer.
For example, you'll need one set of drivers to read your kernel off of disk and/or the network. Then you'll need code to get into protected mode. At that point, you need another set of drivers! Very little of the work you do to get the chip into protected mode will be transferable after that point. You want to run it on a different PC +- 4 years and you'll need yet another set of drivers.
Look into bootstrapping an ARM or other 32-bit "embedded" chip. Inexpensive development boards are available, or you can solder your own! Some have built-in ethernet and usb. I think you will have more fun working on a sane, non-crusty architecture, and perhaps end up with some re-usable skills.
More than anything else, if you want this to run on real hardware, you absolutely need a copy of your processor's manual. The Intel manuals (http://www.intel.com/products/processor/manuals/) are invaluable. They go over everything from switching modes (real/protected) to virtual memory management (if you choose to go that far) to making syscalls (if you ever get to doing user mode). Most importantly they explain in great detail a number of things that must be set up for things to function, like the TSS and segment registers, that most OS texts don't discuss because they're more concerned with higher-level concepts than processor-specific details.
Despite the ridiculous cover, it's a fantastic read, especially for a textbook. Tanenbaum is really an expert in this area and his explanations of how the OS works underneath the hood are clear and easy to understand. This book is mostly theory, but I believe he also has a book that discusses more of the implementation. I've never read it, though, so I can't comment on it.
That should help you bone up on process management, memory management, filesystems, and everything else your OS kernel needs to do to get it up to a bootable state. From that point on it's basically a matter of writing device drivers for the hardware you need to support, and offering implementations of the C library functions to make kernel calls for things like opening files and devices, reading and writing, passing messages between processes, etc.
Read up on x86 assembly (assuming you are designing this for an x86 machine). That should answer a lot of your questions with regards to moving between processor operating modes.
If you've got any electronics knowledge, it may be easier to start with writing an operating system for an embedded device that has ample documentation, because it will generally be simpler than an x86 PC. I've always wanted to write my own OS as well, and I'm starting with writing a microkernel embedded OS for This Development Board from Digilent. It can run the soft-core MicroBlaze processor from Xilinx, which has very thorough documentation. It's also got some RAM, flash data storage, LEDs, switches, buttons, VGA output, etc. Plenty of stuff to play around with writing simple drivers for.
One of the benefits of an embedded device is also that you may be able to avoid writing a VGA driver for a long time. In my case, the Digilent development board has an onboard UART, so I can effectively use the serial output as my console to get the whole thing up and booting to a command line with minimal fuss.
Just make sure that whatever you choose to target has a readily available and well-tested compiler for it. You do not want to be writing an OS and a compiler at the same time.
发布评论
评论(20)
查看 MikeOS。 它是一个相当简单的操作系统,编写的是可读的(如注释中的)程序集。 尽管它相当简单,但它确实有一个 GUI 并支持一些网络和多媒体。
编辑:MenuetOS 是图形化的。 它也是直接asm写的,但是比MikeOS更复杂
check out MikeOS. Its a fairly simple OS written is readable (as in commented) assembly. Even though its fairly simple, it does have a GUI and supports some networking and multimedia.
edit: MenuetOS is graphical. Its also written is straight asm, but its more sophisticated than MikeOS
尝试阅读小型、基本的开源操作系统的代码,例如 MikeOS。
或者,我建议执行以下步骤(应该很有趣!):
对于编写一个简单的操作系统来说,上述步骤似乎有点愚蠢,但是,嘿,这真的很有趣。
Try to read the code of a small, basic open-source OS, such as MikeOS.
Alternatively, I suggest the following steps (should be fun!):
The above steps may seem kinda stupid for writing a simple OS, but hey, it's damn fun.
操作系统开发系列@BrokenThorn 可能会让您感兴趣。
The OS Development Series @ BrokenThorn might interest you.
你有一个雄心勃勃的目标。 但执行力是关键。
大多数结构化方法(教科书或大学课程)将引导您完成整个过程,但它们提供了大量具体代码,掩盖了您所选平台的神秘细节,让您专注于大局想法:进程调度、内存管理、死锁预防、I/O 等等。
我的建议是:降低你的期望,从一个基本问题开始。
什么是操作系统?
计算机科学家(希望)永远不会说操作系统是图形用户界面、网络浏览器、连接 USB 设备的方式,或者用户可以使用的任何东西。实际上可以看到或触摸到。 相反,操作系统最基本的层面就是我上面提到的那些东西。 它们都属于一个大范围:资源管理。
操作系统无非是管理计算机硬件资源的程序:内存、CPU 和外设。
这是一个简单的操作系统:程序允许用户使用串行连接输入程序(十六进制或二进制)。 一旦程序被输入,它就会运行该程序。 程序完成后,控制权返回给用户,他们可以再次运行该程序或输入新的程序。
在“干净”的架构(例如具有 64K 内存左右的嵌入式 ARM 处理器)上执行此操作。 在学习了 ARM 的详细信息几天后,您可以用汇编语言对其进行编码。 瞧!,您已经拥有了一个操作系统。
它完成了操作系统应该做的所有事情:
这为您提供了一个起点。 你现在有很多选择。 也许其中之一是允许将两个程序加载到内存中并让用户决定接下来运行哪一个。
或者您可以让用户暂停执行一个程序,切换到另一个程序,暂停,然后切换回来。 这是基本的多任务处理,尽管它完全是手动的。
您的选择是无限的,但每一个都是您之前的一小步。
如果你的目标不是太高的话,这很有趣!
You have an ambitious goal. But execution is key.
Most of the structured approaches (textbook or college class) will walk you through the process, but they supply a lot of the nitty-gritty code that glosses over the arcane details of your chosen platform and lets you focus on the big-picture ideas: process scheduling, memory management, deadlock prevention, I/O, and so forth.
My advice is this: cut way back on your expectations and start with a basic question.
What is an operating system?
A computer scientist will (hopefully) never say that an OS is a graphical user interface, or a web browser, or a way to hook up USB devices, or anything that a user can actually see or touch. Instead, an OS at its most fundamental level are those things I mentioned above. They all fall under one big umbrella: resource management.
An operating system is nothing more than a program that manages the hardware resources of the computer: memory, CPU, and peripherals.
Here's a simple operating system: a program lets the user type in a program (in hexadecimal or binary) using a serial connection. Once the program has been typed in, it runs the program. When the program is finished, control is returned to the user where they can either run the program again or type in a new one.
Do this on a "clean" architecture such as an embedded ARM processor with 64K of memory or so. You can code this up in assembly after a few days of learning the ins and outs of the ARM. And voila!, you've got yourself an operating system.
It does everything an OS is supposed to do:
This gives you a building block to start from. You have many choices now. Perhaps one of them would be to allow two programs to be loaded into memory and let the user decide which one to run next.
Or you could let the user suspend execution of one program, switch to the other, suspend, and switch back. This is rudimentary multitasking, even though it's entirely manual.
Your choices are unlimited but each one is a baby step from what you had before.
It's fun if you don't set your sights too high!
许多学校都有操作系统课程,它们可以完成您所描述的大部分内容。 我的学校 (CMU) 用 C 语言教授操作系统,我们编写了内核、文件系统和 shell,并提供了引导加载程序的代码。
不幸的是,我无法在网络上找到本课程 (15-412) 的任何明确资源,并且它随着时间的推移而不断发展。 但也许人们可以为那些在网络上拥有良好资源的学校发布资源和作业的链接。
Many schools have OS classes that do much of what you describe. My school (CMU) taught OS in C, and we wrote a kernel, file system, and shell, and were provided with code for a boot loader.
Unfortunately, I wasn't able to find any definitive resource for this course (15-412) on the web, and it's evolved over time. But perhaps people could post links to sources and assignments for schools that do have good resources on the web.
研究 A2 系统(以前称为 Oberon 系统)以获取您的想法可以偷。 它是一个仅由两个人构建的图形操作系统,尽管不可否认的是 Niklaus Wirth 就是其中之一。 1990 年左右首次发布,速度快得惊人。 古特克内西特有一本书。
Study the A2 System (formerly called the Oberon system) for ideas you can steal. It is a graphical OS built by just two people, although admittedly one is Niklaus Wirth. First released around 1990 and the speed is astonishingly good. There is a book by Gutknecht.
我在 StackOverflow 上维护了一个资源列表:如何开始使用操作系统开发。 当您开始冒险时,请为其添加新资源(我即将开始:))
I maintain a list of resources on StackOverflow: How to get started in operating system development. Please add new resources to it as you begin you're adventure (I'm about to begin :) )
您可能会喜欢这个名为“推出您自己的玩具 UNIX 克隆操作系统”的教程,它非常有洞察力,应该对您有所帮助。
祝你好运。
You might enjoy this tutorial named "Roll your own toy UNIX-clone OS", its very insightful and should help you on your way.
Good luck.
关于低级图形编程,这将为您提供大量信息:http://www.osdever.net/FreeVGA/home.htm" osdever.net/FreeVGA/home.htm。 (对于文本模式来说这也很有趣。)
你会意识到,在 PC 上有很多不清楚的东西:x86 指令集本身很复杂,当你直接访问硬件时,可能需要相当长的时间才能理解如何在屏幕上书写单个字符。
不用担心软盘之类的,大多数时候你会使用模拟器,例如Bochs或QEmu。
About low-level graphics programming, this will give you a lot of information: http://www.osdever.net/FreeVGA/home.htm. (It's very interesting for text mode as well.)
You will realize that on PC there's an awful lot of stuff that is unclear: the x86 instruction set itself is complicated, and when you get direct access to hardware, it can take quite a while before you understand how to write a single character on screen.
Don't worry about floppy disk and such, most of the time you will use an emulator such as Bochs or QEmu.
http://www.osdev.org/
和
http://www.osdever.net/
欢迎来到操作系统开发世界。
另请参阅 SO 的 x86 tag wiki:Intel 和 AMD 手册、编译器/汇编器文档和各种指南。
它还建议使用 BOCHS 或其他虚拟环境进行调试,因为您可以单步引导加载程序并检查寄存器。
http://www.osdev.org/
and
http://www.osdever.net/
welcome to the OS Development world.
See also other x86 documentation links in SO's x86 tag wiki: Intel and AMD manuals, compiler / assembler docs, and various guides.
It also suggests using BOCHS or other virtual environment for debugging, since you can single-step your bootloader and examine registers.
我建议至少首先在 Bochs 或其他虚拟机上工作,因为您可以无论您身在何处,调试起来都更加容易(您可以看到硬件的确切状态),并且如果您需要外部帮助调试,他们可以使用与您完全相同的“硬件”。
我最有用的建议是让自己进入一种可以尽快运行 C 代码的状态——即启动、设置描述符表,并让自己达到可以安全运行编译的 C 的程度。如果不是所有的内核都应该用 C 编写,如果你想保持理智并继续努力的话。 虽然在某些地方需要组装,但组装很乏味并且往往难以调试。
I would suggest working, at least at first, on Bochs or some other virtual machine the reason being that you can take it with you wherever you want, it's easier to debug (you can see the exact state of the hardware), and if you need outside help debugging they can use the exact same 'hardware' as you.
The most useful advice I have is to get yourself into a state where you can be running C code as quickly as possible -- i.e. boot up, setup your descriptor tables, and get yourself to a point where it's safe to run compiled C. Most if not all the kernel should be in C if you want to stay sane and keep working on it. Assembly, while required in some places, is tedious and tends to be hard to debug.
您可能需要考虑查看操作系统概念,作者 Abraham Silberschatz - 了解系统编程概念是一项基本要求,了解操作系统 linux *BSD 和 GNU/Linux,尤其是早期版本,可能有更多文档记录。
You might want to consider taking a look at Operating Systems Concepts, by Abraham Silberschatz - Understanding Systems Programming concepts is a fundamental requirement, take a peek into F/OSS kernel internals of OSes linux *BSD and GNU/Linux, especially earlier versions, which are probably a bit more documented.
看一下 Minix。 与“操作系统设计和实现”一起学习源代码。 考虑为该项目做出贡献。 我认为 Minix 是一个非常优秀且有前途的操作系统。 这也是一个资金充足的项目。 这意味着,您甚至可能会因您的贡献而获得报酬!
Take a look at Minix. Study the source code along with "Operating Systems Design and Implementation". Consider making contributions to the project. I think Minix is a really good and promising OS in the making. It is also well funded project. That means, you might even get paid for your contributions!
这非常容易,因为 BIOS 已经内置了许多输入/输出功能,用于更改屏幕模式、更改像素颜色、向屏幕写入文本以及许多其他功能。 但是,它不包括对文件系统的支持,这是您必须在操作系统中纳入的极少数内容之一。
BIOS 加载硬盘驱动器上的第一个扇区并从那里开始执行代码,因此您的操作系统必须将第一条指令放置在硬盘驱动器上的第一个扇区中。
这篇维基百科文章应该让您开始了解 BIOS 中断,用于将文本写入屏幕、从键盘接收按键和其他内容。
https://en.wikipedia.org/wiki/BIOS_interrupt_call
即使你打算使用 c++ 我强烈建议阅读汇编编程,因为它对于理解硬件的工作原理至关重要。
It is very easy thanks to the fact that the BIOS already have many input/output functions built into it for changing screen mode, changing pixel color, writing text to the screen and many other things. However, it does not include support for file systems, that is one of very few things you must incorporate in your OS.
The BIOS loads the first sector on the hard drive and starts executing the code from there, so your OS must be placed with the first instruction in the first sector on the hard drive.
This Wikipedia article should get you started on BIOS interrupts for writing text to the screen, receiving keys from the keyboard and other stuff.
https://en.wikipedia.org/wiki/BIOS_interrupt_call
Even if you plan to use c++ I would strongly recommend reading up on assembly programming, as it is vital to understanding how the hardware works.
在最低级别,操作系统至少需要能够以某种方式驱动系统的硬件,并以某种方式加载并执行某种“用户代码”。 如果您打算从 PC 开始,那么您需要编写可以从某个设备或另一个设备加载的代码。 较旧的 PC 固件中有一个 BIOS,它决定硬件如何执行某些初始化(至少是视频、键盘和某种形式的存储或引导加载程序)。 (2017 年 10 月更新:较新的 PC 具有 EFI 或 UEFI 固件……这在很大程度上是一个迂腐的差异;本次讨论的目的相同)。
因此,首先要了解如何在目标系统上使用 BIOS 或其他固件的底层细节。 即学习如何编写BIOS可以加载并执行的程序。 它最终会变成你的引导加载程序。 从小处开始。 只需获取一个直接从固件启动过程中打印“Hello, Linus”的程序(在软盘或 USB 拇指驱动器上,将是一个很好的开始......或者如果您愿意,也可以在硬盘驱动器上)。
从那里我建议编写一个非常简单的串行驱动程序......更新您的引导加载程序以初始化某些串行端口,并从那里开始下载。 然后它就可以执行它所拉取的代码。 从那里编写一些可以写入另一组块的引导程序(我们还没有实现文件系统......甚至还没有分区表解析;所以我们首先只处理磁盘上块的原始范围)。
此时,您的引导加载程序应该能够通过串行线路提取新代码,将其转储到分区中(是的,实现某种分区表处理......此时它是否符合标准 PC 约定取决于您),并执行它。
从那里您应该能够处理更复杂的功能。 在此基础上,您可以编写并编译一个新的“内核”...重新启动您的测试台,并将新内核部署到其中。
(您的引导加载程序应该接受一些信号,例如串行握手线路上的 BREAK 作为跳过下载并仅引导现有映像的命令;并且它也应该以这种方式处理一些超时)。
从那里编写一个非常简单的终端层和命令 shell? 文件系统? 实现命令来下载除内核之外的新可执行内容(某种文件或对象)。 等等。
当然,您可以从使用 PC 键盘和视频的控制台驱动程序开始(如果我没记错的话,分别是 BIOS INT 0x16h 和 INT 0x10H 内容)。 但是,我建议从串行驱动程序开始,因为您可以从任何其他现有(功能)系统自动化构建/部署/测试周期。 由于您的新操作系统将作为交叉编译项目启动,因此您必须有一种简化的处理方式。
我不知道你想把你的项目推进到什么程度。 一个相当令人印象深刻的目标是实现“自我托管”。 如果您可以创建一个简单的汇编器/编译器,允许您使用新操作系统(重新)构建、链接并启动到新操作系统的工作版本......那么您就已经实现了该目标。 (请注意,这不是必需的。许多嵌入式系统永远不会是自托管的,这没有什么问题)。
At its lowest level the minimum that an operating system needs to be able to do is to drive a system's hardware in some way and somehow load an execute some sort of "user code." If you're going to start with a PC then you need to write code that can be loaded by it from some device or another. Older PCs have a BIOS in firmware which determines how the hardware performs some initialization (at least video, keyboard, and some form of storage or boot loader). (Update October 2017: Newer PCs have EFI or UEFI firmware ... which is largely a pedantic difference; the serve the same purposes for this discussion).
So start by learning the low level details of how to use the BIOS or other firmware, on your target system. That is, learn how to write a program that the BIOS can load and execute. That will eventually morph into your boot loader. Start small. Just get a program that prints: "Hello, Linus" directly from the firmware boot process (on a floppy, or USB thumb drive, would be a good start ... or on a hard drive if you like).
From there I'd recommend writing a very simple serial driver ... update your boot loader to initialize some serial port, and start a download there from. Then it can execute the code it pulls across. From there write a bit of bootstrap that can write to another set of blocks (we haven't implemented a file system yet ... not even partition table parsing; so we'd just deal with raw ranges of blocks on the disk at first).
At that point your boot loader should be able to pull new code across the serial line, dump it into a partition (yes, implement partition table handling of some sort ... whether it conforms to standard PC conventions is up to you at this point), and execute it.
From there you should be able to work on far more sophisticated features. From this base you can write and compile a new "kernel" ... reboot your testbed, and have the new kernel deployed to it.
(Your bootloader should take some signal, such as a BREAK over the serial handshaking lines as a command to skip the download and just boot the existing image; and it should handle some timeout in this way as well).
From there write a very simple terminal layer and command shell? A filesystem? Implement commands to download new executable content other than the kernel (files or objects of some sort). And so on.
Naturally you could have started with a console driver using the PC keyboard and video (the BIOS INT 0x16h and INT 0x10H stuff, respectively, if I recall correctly). However, I'd suggest starting with a serial driver since you can then automate your build/deploy/test cycle from any other existing (functional) system. Since your new OS will start as a cross-compiled project it's going to be essential for you to have a streamlined way of handling that.
I don't know how far you want to take your project. A reasonably impressive goal would be to achieve "self hosting." If you can create a simple assembler/compiler that can allow you to use your new OS to (re-)build, link, and boot into a working version of your new OS ... then you've achieved that goal. (Note that's not a requirement. Many embedded systems are never going to be self-hosting and there's nothing wrong with that).
我会从小规模开始,购买一个 8086 嵌入式开发套件,并在其上开发一个多任务操作系统。 一旦您拥有了内核并熟悉了硬件级别的工作,您就可以准备好做一些更具挑战性的事情了。
构建 VGA 显示器 DOS 克隆也是一件相当具有挑战性的事情。 细节是巨大的。 :-)
具体主题。
如何将代码输入到计算机上? 最好用软盘来做吗? 大多数计算机可以通过 USB 记忆棒执行此操作吗?
BIOS 将进行基本引导。
我需要什么驱动程序,您能建议一些构建这些驱动程序的参考吗?
任何不是直接CPU/内存操作的东西。 CPU 参考手册中未直接提及的任何内容。
启动序列之后——然后呢? 我如何进入保护模式等。
保护模式将是启动顺序的一部分。
然后你开始多任务处理并弄清楚如何启动流程。
在没有操作系统帮助的情况下如何管理内存? 我可以使用我想要的任何地址吗? 不需要初始化吗?
正确的。 您最终可能会想要整理出一个虚拟内存系统。
我无疑会遇到什么让我困惑的事情?
没有调试工具,没有 IO
我怎样才能使其成为命令行操作系统和图形操作系统?
带着悲伤。 查找 Windows 3.1 和 Linux,特别是 X windows。
图形操作系统是基于什么构建的? 例如,我将如何做类似命令行、字体和顶部图片之类的事情?
查找 X 窗口。
最后的建议:学习 linux/x windows。 它并不完美,但它提供了对一种方法的理解。 还研究嵌入式系统。
I would start small and purchase an 8086 embedded development kit, and develop a multitasking OS on that. Once you have a kernel and are acquainted with working at the hardware level, you will be ready to do something more challenging.
Building even a VGA display DOS clone is a fairly challenging thing. The details are enormous. :-)
specific topics.
How do I put the code onto the computer? Is it best to do it with a floppy disk? Can most computers do it from a USB stick?
The BIOS will do elementary bootstrapping.
What drivers do I need, and can you suggest any references to building those?
anything that isn't direct cpu/memory operations. Anything that isn't directly in the CPU reference manual.
After the booting sequence--then what? How do I get into protected mode etc.
Protected mode will be part of the boot sequence.
then you start multitasking and figuring out how to start processes.
How do I manage memory without the help of an operating system? Do I just use whatever addresses I want? No initialization necessary?
Correct. You will probably want to sort out a virtual memory system eventually.
What will I undoubtedly run into that will confuse me?
not having debugging tools, not having IO
How can I make it either a command line O/S, and a graphical one?
With grief. Look up Windows 3.1 and Linux, in particular X windows.
What is a graphical O/S built on? Like, how would I do something like, a command line, with a font, and a picture at the top?
Look up X windows.
final advice: study linux/x windows. It's not perfect, but it provides an understanding of one approach. Also study embedded systems.
如果您不介意使用硬件虚拟化,有一门课程(书籍+讲座+软件)将带您“从Nand到俄罗斯方块”。 您完全自己创建一个完整的计算机系统,从(出于这些目的原子的和给定的)电子与非门开始,一直到构建操作系统、一种语言,最后在您的个人机器上编写一个简单的游戏。
我认为这是一个好主意,我完全打算尽快投入其中。 这本书出奇的便宜,而且我相信这门课程是在麻省理工学院教授的。 我无法想象,没有什么比对您自己从头开始构建的整个系统有了全面、完整的了解更棒的感觉了。
链接:http://www1.idc.ac.il/tecs/
If you don't mind using hardware virtualisation, there is a course (book + lectures + software) that will take you 'From Nand to Tetris'. You create a full computer system entirely yourself from the (for these purposes atomic, and given) electrical NAND gate, right through to building the OS, a language, and finally coding a simple game on your personal machine.
I think it's a great idea and something I fully intend to get stuck into soon. The book is surprisingly cheap and I believe the course is taught at MIT. I can imagine no greater feeling than having the full, complete knowledge of an entire system you built yourself from the ground up.
Link: http://www1.idc.ac.il/tecs/
我看到很多关于操作系统开发网站的好参考,因此我将描述一种不同的方法:
如果您想要从裸机实现操作系统的体验,那么有比旧 PC 更好的硬件选择。 使用 PC 架构,您将花费大量时间围绕其 30 年设计历史中无趣的工件进行编码。 例如,仅项目的引导加载程序部分就可能让许多勇敢的程序员精疲力尽。
例如,您需要一组驱动程序来从磁盘和/或网络读取内核。 然后您需要代码才能进入保护模式。 那时,您需要另一组驱动程序! 在那之后,您为使芯片进入保护模式所做的工作很少可以转移。 您想在另一台 PC 上运行它 +- 4 年,并且您将需要另一组驱动程序。
研究引导 ARM 或其他 32 位“嵌入式”芯片。 提供廉价的开发板,或者您也可以焊接自己的开发板! 有些具有内置以太网和 USB。 我认为你会在一个理智的、非硬性的架构上工作得到更多的乐趣,并且也许最终会获得一些可重用的技能。
I see plenty of good references to OS development sites, so I'll describe a different approach:
If you want the experience of implementing an OS from bare metal, there are way better hardware choices than an old PC. With the PC architecture, you will spend an inordinate amount of your time coding around uninteresting artifacts of its 30 year design history. For example, just the bootloader part of the project has probably burned out many a brave programmer.
For example, you'll need one set of drivers to read your kernel off of disk and/or the network. Then you'll need code to get into protected mode. At that point, you need another set of drivers! Very little of the work you do to get the chip into protected mode will be transferable after that point. You want to run it on a different PC +- 4 years and you'll need yet another set of drivers.
Look into bootstrapping an ARM or other 32-bit "embedded" chip. Inexpensive development boards are available, or you can solder your own! Some have built-in ethernet and usb. I think you will have more fun working on a sane, non-crusty architecture, and perhaps end up with some re-usable skills.
最重要的是,如果您希望它在真实硬件上运行,您绝对需要一份处理器手册的副本。 英特尔手册 (http://www.intel.com/products/processor/manuals/) 是无价的。 他们涵盖了从切换模式(真实/受保护)到虚拟内存管理(如果您选择走那么远)到进行系统调用(如果您曾经进行用户模式)的所有内容。 最重要的是它们非常详细地解释了一些必须设置才能运行的东西,比如 TSS 和段寄存器,大多数操作系统文本都没有讨论这些,因为它们更关心比特定于处理器的细节更高级别的概念。
More than anything else, if you want this to run on real hardware, you absolutely need a copy of your processor's manual. The Intel manuals (http://www.intel.com/products/processor/manuals/) are invaluable. They go over everything from switching modes (real/protected) to virtual memory management (if you choose to go that far) to making syscalls (if you ever get to doing user mode). Most importantly they explain in great detail a number of things that must be set up for things to function, like the TSS and segment registers, that most OS texts don't discuss because they're more concerned with higher-level concepts than processor-specific details.
首先要事。 读,读,读,读,读。 您需要先充分了解操作系统的工作原理,然后才能实现自己的操作系统。
阅读 Andrew Tanenbaum 的一本有关操作系统的书。 这是我们在大学操作系统课程中使用的:
现代操作系统PDF
亚马逊上的现代操作系统
读起来很棒,尤其是作为教科书。 Tanenbaum 确实是该领域的专家,他对操作系统底层工作原理的解释清晰易懂。 这本书主要是理论,但我相信他还有一本讨论更多实现的书。 不过我没读过,所以无法评论。
这应该可以帮助您加强进程管理、内存管理、文件系统以及操作系统内核需要执行的所有其他操作,以使其达到可启动状态。 从那时起,基本上就是为需要支持的硬件编写设备驱动程序,并提供 C 库函数的实现来进行内核调用,例如打开文件和设备、读取和写入、在进程之间传递消息等阅读
x86 汇编(假设您正在为 x86 机器设计它)。 这应该可以回答您有关在处理器操作模式之间切换的许多问题。
如果您有任何电子知识,那么开始为具有充足文档的嵌入式设备编写操作系统可能会更容易,因为它通常比 x86 PC 更简单。 我也一直想编写自己的操作系统,并且我开始为 此开发板来自 Digilent。 它可以运行 Xilinx 的软核 MicroBlaze 处理器,该处理器有非常详尽的文档。 它还具有一些 RAM、闪存数据存储、LED、开关、按钮、VGA 输出等。通过编写简单的驱动程序可以使用很多东西。
嵌入式设备的好处之一还在于您可以避免长时间编写 VGA 驱动程序。 就我而言,Digilent 开发板有一个板载 UART,因此我可以有效地使用串行输出作为我的控制台,以最小的麻烦来启动整个系统并启动到命令行。
只要确保您选择的目标有一个现成且经过良好测试的编译器即可。 您不想希望同时编写操作系统和编译器。
First things first. Read, read, read, read, read. You need to have a firm understanding of how the OS works before you can hope to implement your own.
Grab one of Andrew Tanenbaum's books on operating systems. This is the one we used in my OS class in college:
Modern Operating Systems PDF
Modern Operating Systems on Amazon
Despite the ridiculous cover, it's a fantastic read, especially for a textbook. Tanenbaum is really an expert in this area and his explanations of how the OS works underneath the hood are clear and easy to understand. This book is mostly theory, but I believe he also has a book that discusses more of the implementation. I've never read it, though, so I can't comment on it.
That should help you bone up on process management, memory management, filesystems, and everything else your OS kernel needs to do to get it up to a bootable state. From that point on it's basically a matter of writing device drivers for the hardware you need to support, and offering implementations of the C library functions to make kernel calls for things like opening files and devices, reading and writing, passing messages between processes, etc.
Read up on x86 assembly (assuming you are designing this for an x86 machine). That should answer a lot of your questions with regards to moving between processor operating modes.
If you've got any electronics knowledge, it may be easier to start with writing an operating system for an embedded device that has ample documentation, because it will generally be simpler than an x86 PC. I've always wanted to write my own OS as well, and I'm starting with writing a microkernel embedded OS for This Development Board from Digilent. It can run the soft-core MicroBlaze processor from Xilinx, which has very thorough documentation. It's also got some RAM, flash data storage, LEDs, switches, buttons, VGA output, etc. Plenty of stuff to play around with writing simple drivers for.
One of the benefits of an embedded device is also that you may be able to avoid writing a VGA driver for a long time. In my case, the Digilent development board has an onboard UART, so I can effectively use the serial output as my console to get the whole thing up and booting to a command line with minimal fuss.
Just make sure that whatever you choose to target has a readily available and well-tested compiler for it. You do not want to be writing an OS and a compiler at the same time.