首先,评论这是我的第一篇文章,希望大家都喜欢。
在本系列中,我们将模拟 Linus Torvalds的,我们将从0创建操作系统。在第一集中,我们将看到启动并将内核中的文本显示在屏幕上。
就我而言,操作系统称为 下一个旅行。 一旦考虑操作系统,我们必须做出的第一个决定是引导加载程序将是什么?
这里有多种变体,我们甚至可以自己创建一个。 但是在本教程中,我将使用 GRUB,因为大多数人或多或少地了解他。 我们创建一个文件夹,该文件夹将成为操作系统的根目录,并在其中创建/ boot / grub文件夹
mkdir nextroot && cd nextroot
mkdir -p boot/grub
在这里,我们创建grub.cfg文件,如下所示:
menuentry "NextDivel" {
echo "Booting NextDivel"
multiboot /next/START.ELF
boot
}
在此文件中,我们看到了 GRUB 在这种情况下,将在/next/START.ELF中加载我们的内核。 现在我们必须创建内核。
为此,我们将需要 GCC y 天然气 (项目的汇编程序 GNU,通常随gcc一起提供)。 因此,我们将创建内核。
我们首先创建一个名为kernel.asm的文件。 该文件将包含内核的起点,还将定义多重引导(某些引导加载程序的功能,例如 GRUB)。 kernel.asm的内容将是:
.text
.globl start
start:
jmp multiboot_entry
.align 4
multiboot_header:
.long 0x1BADB002
.long 0x00000003
.long -(0x1BADB002+0x00000003)
multiboot_entry:
movl $(stack + 0x4000), %esp
call NextKernel_Main
loop: hlt
jmp loop
.section ".bss"
.comm stack,0x4000
与multiboot相关的所有内容都只是遵循规范。 一切都将从开始开始,它将调用multiboot_entry,我们将在前4k中定义multiboot标头,然后将其放入(使用movl)。
稍后我们调用NextKernel_Main,这是我们的内核C函数。 在循环中,我们暂停以停止计算机。 编译为:
as -o kernel.o -c kernel.asm
现在,我们将开始使用C语言进行编程。您会认为,现在一切都变得轻而易举, 的printf en 主 就是这样,我们已经做到了。
好吧,因为 的printf y 主 它们是操作系统定义的功能,但是我们正在创建它们! 我们只能使用自己定义的功能。
在后面的章节中,我将不时讨论如何放置我们自己的C库(glibc,bionic,newlibc)。 我们已经讨论过要在屏幕上放置文本,我们将看看如何做。
有两种选择,一种是调用 BIOS 另一个是直接管理屏幕内存。 我们将执行后者,因为从C可以更清楚地看到它,并且当我们进入保护模式时,它也将允许我们执行此操作。
我们创建一个名为NextKernel_Main.c的文件,其内容如下:
int NextKernel_Main()
{
char *str = "NextDivel says Hello World", *ch;
unsigned short *vidmem = (unsigned short*) 0xb8000;
unsigned i;
for (ch = str, i = 0; *ch; ch++, i++)
vidmem[i] = (unsigned char) *ch | 0x0700;
return 0;
}
这样我们就可以直接操纵记忆 VGA 并逐个字符地编写。 我们通过禁用stdlib进行编译:
gcc -o NextKernel_Main.o -c NextKernel_Main.c -nostdlib -fPIC -ffreestanding
如果您已经做到了这一点,那么现在就想尝试使用全新的操作系统,但是我们还没有完成。 我们需要一个小文件来告诉编译器文件中每个部分的位置。 这是通过链接描述文件完成的。 我们创建link.ld:
ENTRY(start)
SECTIONS
{
. = 0x00100000;
.multiboot_header :
{
*(.multiboot_header)
}
.text :
{
code = .; _code = .; __code = .;
*(.text)
. = ALIGN(4096);
}
.data :
{
data = .; _data = .; __data = .;
*(.data)
*(.rodata)
. = ALIGN(4096);
}
.bss :
{
bss = .; _bss = .; __bss = .;
*(.bss)
. = ALIGN(4096);
}
end = .; _end = .; __end = .;
}
这样,我们定义了每个部分的位置以及我们在kernel.asm中定义的入口点start。 现在我们可以将所有这些混合在一起:
gcc -o START.ELF kernel.o NextKernel_Main.o -Tlink.ld -nostdlib -fPIC -ffreestanding -lgcc
现在,我们将START.ELF复制到模拟操作系统根目录的文件夹中的/ next。 我们使用控制台转到新操作系统的根文件夹,并验证是否存在两个文件:一个/boot/grub/grub.cfg和另一个/next/START.ELF。
我们转到上层目录,并使用GRUB调用一个ISO创建实用程序,称为 格鲁夫·麦克里斯库
grub-mkrescue -o nextdivel.iso nextroot
完成此操作后,我们将有一个 ISO。 可以在计算机上打开此ISO x86 (也是64位)和虚拟机。 为了测试它,我将使用 QEMU。 我们称之为 QEMU 从命令行:
qemu-system-i386 nextdivel.iso
将开始 海洋BIOS 后来我们将有 GRUB。 稍后,如果一切正确,我们将看到我们的短语。
我会回答,您会认为这很困难,是的。
真正创建一个操作系统很困难,这里的操作系统没有任何用处。 在以后的章节中,我们将看到如何处理屏幕上的颜色,保留内存以及如果可以的话如何从键盘获取数据。
如果有人不想在这里复制所有内容,我在这里有一个存储库 GitHub上 (更详细)与操作系统 下一个旅行。 如果要编译 下一个旅行 您只需要拥有git和cmake:
git clone https://github.com/AdrianArroyoCalle/next-divel
cd next-divel
mkdir build && cd build
cmake ..
make
make DESTDIR=next install
chmod +x iso.sh
./iso.sh
qemu-system-i386 nextdivel.iso
如果您有时间和愿望来创建操作系统,我鼓励您在NextDivel上进行协作。 也许甚至优于Linux……时间会证明一切。
:O
Torvalds将Minix操作系统(从UNIX派生)用于Andrew S. Tanenbaum,并对其进行了改进。
Tanenbaum与Linus发生了争执,他们互相侮辱。 Tanenbaum表示,微内核是未来(HURD,Minix新圆锥微内核)。
http://www.taringa.net/posts/linux/17215999/Linux-vs-Hurd-Kernel-Monolitico-vs-Microkernel.html
这是我迄今为止在此博客上看到的最好的帖子。 我已经想知道还要做什么。
被感动
真是令人印象深刻!
FUUUUUUUA!
这是我见过的最讨厌的帖子恭喜阿德里安,关于妓女的文章! 超级有趣! 🙂
我同意。 我想象这种情况:
GNU / Linux高级用户(笑容满面):
“我已经知道如何编译我的Gentoo”
书呆子(轻蔑地):«PFF,我创建了自己的发行版...»
是的,我可以创建自己的Linux发行版。 实际上,我正在为嵌入式Linux开发一个initramfs和一个内核。 创建操作系统不同于Linux发行版。 第一个要困难得多,几乎是不可能的,第二个就像您所说的一样,甚至可以是带有xD徽标的Ubuntu。 所以我会这样保留它:
GNU / Linux高级用户(笑容满面)
-我已经知道如何编译我的Gentoo
半书呆子
-Pff,我从头开始学习Linux,并制作了自己的发行版
书呆子(轻蔑的态度)
-pff,因为我已经在汇编器和C中编写了内核
Saludos!
在接下来的章节中,这对我来说很有趣。
我前段时间看过本教程,它是针对C ++的
https://github.com/SamyPesse/How-to-Make-a-Computer-Operating-System
感谢您的链接,我来看看。
我想要一个与AMD显卡100%兼容的操作系统:/
Windows
Windows Catalyst中的hahaha不支持OpenGL,尽管在Linux中我无法使用所有图形功能,我将一直等待观察会发生什么!
只等阀门消灭市场
神奇,完美,出色的贡献,看起来像是一系列精彩的文章🙂
Buah我想知道如何编程来帮助您,只是作为一种在您所学和有帮助的知识上进行练习的方式。 现在,一旦您完成“使用NextDivel,色情内容看起来相同(或更好)。”,我就留下您的座右铭,以吸引人们对该项目的关注。
Mooooooolaaa !!!!
很好的文章,但很好奇为什么您没有关注Linux From Scratch项目?
问候
好吧,Scratch的Linux很好,您可以说它是您的,但是它确实非常机械:
-下载字体
-修补它们
-编译
-安装
-以下
在这里,即使最后的结果更糟,您也可以说已经检查了所有文件。
从我之前的评论中可以清楚地看出,因为它的复杂程度并不相同。 而且,从头开始创建linux并不是真正意义上的从头开始创建系统的过程,而是从头开始创建系统,而是自己编写程序,编写自己的内核,而不是linux内核,如果可能的话,甚至是自己的bootloader而不是grub, lilo,syslinux等尽管LFS并非易事,而且相当复杂,但它甚至与您自己的内核编程还差得远……
此外,我同意AdrianArroyo Calle的观点,即它太机械了,我读了一段时间,最后在第六页放弃了,他们还告诉您使用什么版本的软件包,因为否则该说明将无法正常工作(表示缺乏灵活性,我认为)。 我认为最好有一个自己的想法,编译所需的软件包,甚至编写一些程序,然后编译Linux内核并保持平静。
Saludos!
哦! 我从来没有像这个职位那样多地获得过职位。
请继续😀
我不知道怎么了:
错误:找不到多重引导头。
错误,您需要先加载内核
如果有什么安慰的话,我犯了同样的错误。 尝试使用GitHub中的源,那里的错误已经得到解决。 无论如何,我认为如果将grub.cfg行从“ multiboot /next/START.ELF”更改为“ kernel /next/START.ELF”,则可能会起作用。 我不知道。
首先,华丽的入口entrance
我从grub加载内核时遇到了同样的问题。 甚至使用GitHub源或更改内核的多重引导...
错误:找不到多重引导头。
错误:未加载内核
您是否正在使用clang作为编译器? 更改为gcc
您还记得使用链接脚本吗? 链接器(在我们的例子中为ld)必须知道要将每件事放在文件中的什么位置,这是必要的。 在这种情况下,多重引导标头必须位于开头。
您正在使用CMake系统吗? 如果您使用它,我认为它不会失败。
如果对您不起作用,我将尝试寻找其他解决方案。
[+100]
太棒了!!!
真的很酷🙂
我脱下帽子。 令人印象深刻的帖子。 恭喜你
哇!
如果您可以打开使用HTML5和Javascript制作的应用程序而不必使用浏览器,那就太好了,这可能吗?
我说的是它们就像本机应用程序一样。
因此,对该操作系统进行编程将很容易😀
在这种情况下,我不打算这样做,因为它需要大量的工作,但是有一个名为“ is”的操作系统可以执行您所说的事情。 实际上,命令行是JavaScript,并且使用JavaScript Canvas函数绘制窗口。 任天堂的工程师做到了,现在它是开源的。
http://code.google.com/p/es-operating-system/
瓦拉,谢谢你的信息😀
我会看一看
谁能够制作自己的操作系统,谁就可以和平地死去,因为他必须具备相应的知识水平。 它使您无需天堂或地狱。
一块过帐。
到目前为止,还没有人知道是从头开始制作的,可以说是一个像样的操作系统,甚至没有像您一开始所说的那样是Linux Torvalds,因为这是从Unix来源开始的,其他所有内容都是共同创作的,甚至更多。与一个人相比,生命非常短暂,任何人都无法想象从头开始,即使想要相反的情况,在Linux Torvalds复制和粘贴过程中犯的许多错误中也可以证明这一点。
Unix源是封闭的,使用minix ...是另外一回事。
而那些制作QDOS的人呢?
基于什么?
从我的角度来看,谁没有自己的操作系统是因为他们不想这么做,哈哈哈哈。
现在认真,很有趣! 我的编程知识已经远远超出了我的范围,但是我会急切地阅读本系列的其他部分。
感谢您的帖子!
你给我留下了O_O的脸...不想低估任何人的贡献,这是我最近见过的最“亲”的东西。 问候。
很好的文章,Adrián。 请继续…
您是在愚人节开玩笑吗?您的意思不是“模仿Linus Torvalds:从头开始创建自己的操作系统”。 对于那些在某个技术学院或大学追求职业的人来说,我认为这并不困难; 但是对我来说,我是一个新手弓箭手(有些人说“ Noob”,但我认为自己更像是新手,有些懒惰),听起来好像不踏上土地。 无论如何,该文章创造了很多好奇心,并且毫不怀疑和尊重其编辑,祝贺; 我要做的第一件事是尝试至少了解一些这种有价值的材料。
谢谢Adrian Arroyo Calle,出色的工作和高尚的知识交付。
LEL优秀帖子,请继续努力。
多么棒的帖子啊,这就是我错过的 desde linux。精彩的。
很棒的帖子,非常感谢。
我不明白link.ld文件的作用,有人可以向我解释一下吗?
link.ld文件告诉链接器(在本例中为ld)在代码的每个位置应位于结果文件中的哪个位置。 我们还定义了入口点,因为由于我们没有操作系统,所以不能将main用作常规程序,在这种情况下,我们选择启动功能。
伟大的所有您的帖子! 等待7! 如果我有疑问,例如,如果我只想运行没有OS的算法,该怎么办,我怎么知道我可以使用什么而不能使用C?
如果以这种方式使用它,则将无法使用stdlib中的任何内容,而这实际上是每个人都使用的内容(没有malloc,free,printf,scanf,strcmp等)。 一切都必须直接从内存或ASM实现。 也许在更高的章节中,我将向您展示如何为操作系统安装C库。 如果使用C ++,则不能使用异常以及new和delete运算符(当然还有更多)。
我认为 ESTO 它可以让您更好地了解如何进行操作。
您好,大约5年前,我遵循了类似的出版物,并开发了一种以相同方式启动的微内核,它有一些方面需要改进,但是您可能会感兴趣,它以保护模式运行,执行多任务并执行内存虚拟化,最近致力于磁盘驱动器和CD驱动器,使其可安装,而不仅仅是在实时CD上运行。
亲爱的,执行命令时出现错误:
gcc -o START.ELF kernel.o NextKernel_Main.o -Tlink.ld -nostdlib -fPIC -ffreestand -lgcc
link.ld:5个语法错误
collect2:错误:ld返回1退出状态
链接
。 = 0x00100000;
.multiboot_header:{
*(。multiboot_header)
}
在第5行中,我没有看到错误,有人吗?
我正在VirtualBox中使用虚拟化的Debian Wheezy
添加“;” 在*(.multiboot_header)的末尾
非常好的创举,我一定会关注这篇文章的各个章节,打算从中学到很多东西。 非常感谢您抽出宝贵的时间教我们。 关于这方面的一个细节,应该注意,Linus Torvalds不是任何操作系统的创建者,他创建了GNU / Linux系统(已在其他OS中使用的系统)的内核,这仍然值得,但重要的是要感谢Richard Stallman创建了大多数操作系统。
非常感谢您的投入,希望您考虑我的看法。
我已经讨论了一段时间了,阅读标题后我就变得很感兴趣。 但是消息不断
错误:找不到多重引导头。
错误,您需要先加载内核
我已将我上传的内容上传到github上的仓库中 https://github.com/rkmax/GenyOS
我也发生了同样的事情,找到解决方案了吗?
我开始介绍语法的一个问题,菜单行告诉我命令找不到,谁能告诉我原因
这就是我所做的
黑色@ BLACK-pc:〜/ blackroot $ menuentry«NextDivel»{
menuentry:找不到命令
该内容的内容不在命令行中输入,而是在您创建的名为grub.cfg的文件中输入。
优秀的文章,谢谢!
壮观……! 就像缺少的链接一样。
我喜欢您的Emulation LInus Torvalds教程,但是有一个我不理解的步骤,以下是:
现在,我们将START.ELF复制到模拟操作系统根目录的文件夹中的/ next。 我们使用控制台转到新操作系统的根文件夹,并验证是否存在两个文件:一个/boot/grub/grub.cfg和另一个/next/START.ELF。
我们转到上层目录,使用GRUB调用一个名为grub-mkrescue的ISO创建实用程序
有人可以向我解释:p
只是为了生成GRUB可以加载的最低ISO,我们将内核复制到(ISO的/,任何文件夹)/next/START.ELF,将GRUB配置文件复制到(ISO的/,任何文件夹)/ boot / grub / grub.cfg。 完成此操作后,我们尚未在ISO上安装GRUB,并且有一个实用程序可从文件夹生成ISO并安装称为grub-mkrescue的GRUB。 然后,我们最终得到一个已安装GRUB的可引导ISO,该ISO可以读取配置以稍后正确执行START.ELF。 我不知道自己是否已经解释过,但是我们所要做的是一种错误的文件系统,通过它我们可以生成一个ISO。
太棒了
好吧,真的不多看一个新系统,但是,如果您改进Linux,例如,创建一个带有服务器组件的Linux外核,如果您愿意的话,它可以充当微核,也就是说,一个具有微核行为的exo结构将是超级的。和linux。
另一件事是我不是编程专家,只是一些俗气的c ++和一些java,对于我来说,给linux内核程序一个模块,删除它,修改它就足够了。
毫无疑问,我已经要去度假了。
这个好东西,你用什么程序设计和编码
请给我那个答案
从您的git编译时,我得到:
[jmponce @ jar build] $ cmake ..
-创建NextRoot目录
-生成ISO脚本
使DESTDIR =下次安装
./iso.sh
-找到Doxygen:/ usr / bin / doxygen(找到版本“ 1.8.9”)
-配置完成
-完成生成
-构建文件已写入:/ home / jmponce / next-divel / build
[jmponce @ jar版本] $ make
扫描目标START.ELF的依赖项
[7%]构建ASM-ATT对象src / CMakeFiles / START.ELF.dir / start / boot.asm.o
[14%]构建CXX对象src / CMakeFiles / START.ELF.dir / start / NextShellLite.cpp.o
[21%]构建CXX对象src / CMakeFiles / START.ELF.dir /开始/ ND_Screen.cpp.o
[28%]构建CXX对象src / CMakeFiles / START.ELF.dir / start / NextKernel_Main.cpp.o
[35%]构建CXX对象src / CMakeFiles / START.ELF.dir / start / ND_Panic.cpp.o
[42%]构建CXX对象src / CMakeFiles / START.ELF.dir / start / ND_Timer.cpp.o
[50%]构建CXX对象src / CMakeFiles / START.ELF.dir / start / ND_Memory.cpp.o
[57%]构建CXX对象src / CMakeFiles / START.ELF.dir / start / ND_Ports.cpp.o
[64%]构建CXX对象src / CMakeFiles / START.ELF.dir / start / ND_GDT.cpp.o
[71%]构建CXX对象src / CMakeFiles / START.ELF.dir / start / ND_ISR.cpp.o
[78%]构建CXX对象src / CMakeFiles / START.ELF.dir / start / ND_String.cpp.o
[85%]构建CXX对象src / CMakeFiles / START.ELF.dir / start / ND_IRQ.cpp.o
[92%]构建CXX对象src / CMakeFiles / START.ELF.dir / start / ND_IDT.cpp.o
[100%]构建CXX对象src / CMakeFiles / START.ELF.dir / start / ND_Keyboard.cpp.o
链接CXX可执行文件START.ELF
/ usr / bin / ld:不兼容的/usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/libgcc.a在查找-lgcc时被跳过
/ usr / bin / ld:找不到-lgcc
collect2:错误:ld返回退出状态1
src / CMakeFiles / START.ELF.dir / build.make:402:目标'src / START.ELF'的失败指令
使[2]:*** [src / START.ELF]错误1
CMakeFiles / Makefile2:106:目标'src / CMakeFiles / START.ELF.dir / all'的失败指令
使[1]:*** [src / CMakeFiles / START.ELF.dir / all]错误2
Makefile:117:目标“ all”的指令失败
使:*** [全部]错误2
错误似乎是因为您拥有64位版本,所以找不到llibgcc,并且当前编译系统被迫使用32位。 您应该在发行版或更高版本上安装兼容包,使用32位系统。
我有32位,并且出现相同的错误,您是指操作系统还是体系结构? 我的是64位的,但是我使用的是32位的Ubuntu,不要问,财务问题,我就这样说。
优秀的话题,等待更大的范围。 干杯
太棒了,我希望更多
您好,我是一位年轻的大使,他想创建一个支持所有程序和平台的操作系统,以便开发人员不必在PC上拥有功能强大的计算机,应用程序或程序。
这就是为什么我对此帖子感兴趣,但是当我下载您的git或尝试创建它时,一切正常,直到我执行命令./iso.sh或grub-mkrescue -o nextdivel.iso nextroot时,您会收到此错误
“ Grub-mkrescue:警告:您的xorriso不支持” –grub2-boot-info“。 某些功能已被禁用。 使用xorriso 1.2.9或更高版本。
grub-mkrescue:警告:您的xorriso不支持“ –grub2-boot-info”。 您的内核映像太大。 磁盘启动已被禁用。 使用xorriso 1.2.9或更高版本..»
我真的不知道,因为我对应用程序和Web知识很多,但是对grub一无所知
您可能需要在发行版上更新xorriso程序。 您使用什么发行版和版本?
我使用xubuntu 14.04lts并尝试运行xorriso,但是shell告诉我它找不到它,并且我得到apt-get install xorriso,尽管我真诚地希望得到一些响应,因为我在Linux上安装了我不知道的东西时经验很差,呵呵。 我将立即更新并告诉您发生了什么
然后从软件中心安装xorriso或直接从终端安装“ sudo apt-get install xorriso”
我已经完成了您告诉我的所有事情,并且使用git和mine都得到了xorriso 1.3.2:RockRidge文件系统操纵器,libburnia项目。
驱动电流:-outdev'stdio:nextdivel.iso'
媒体当前:stdio文件,可覆盖
媒体状态:为空白
媒体摘要:0个会话,0个数据块,0个数据,1901m免费
已添加到ISO映像:目录'/'='/tmp/grub.OEqSzV'
xorriso:更新:在546秒内添加了1个文件
xorriso:失败:无法确定源文件“ / media / gaia / Jupiter1 / ShellSystem / nextroot / nextroot”的属性:没有此类文件或目录
xorriso:更新:在546秒内添加了1个文件
xorriso:正在中止:-abort_on'FAILURE'遇到'FAILURE'
和灯芯绒,我不了解我的结构是/nextroot/boot/grub/grub.cfg和nextroot / next / START.ELF
谢谢,我准备前进,一个朋友帮助了我,并告诉我我做错的是目录的组织,所以我解决了,就这样
打扰一下,您能告诉我您执行了什么步骤,因为我没有收到任何错误提示:没有这样的文件或目录
无引导设备。
干杯! 我正想问您一个忙,如果您能给我发一封电子邮件,说明您在这里的解释,我有点困惑,我需要将我的理解与您的解释进行比较,也许我不清楚的是创建grub。cfg是在终端gcc中完成的还是在什么地方完成的? 朋友,非常感谢您!
使用任何文本编辑器创建文件grub.cfg,都必须将其保存在PROJECT_FOLDER / boot / grub / grub.cfg中
您好阿德里安(Adrian),首先,祝贺您,并感谢您的贡献。
您知道我是在做练习的,我在您的辅导后开始将其组合在一起,但是开始后我发现了第一个错误
$ as -o kernel.o -c kernel.asm
bash:as:找不到命令...
类似的命令是:
'一个'
'ac'
我正在研究fedora 20,在这方面我找不到解决方案,对于您应该更改gcc还是gas的指导,我将不胜感激。
提前致谢
您必须安装GAS,这样我才能看到错误代码。 我手头没有Fedora,但从理论上讲,如果您要安装gcc-c ++,则将安装整个GCC套件和GNU,通常会附带它。
我和你在一起,我对C ++,C#有所了解(尽管这最后一点在这方面不是很有用),但坏的是我仍然缺乏经验,我从不使用C语言,您的著作很棒,如果有时间,我没什么好说的。 谢谢。
非常感谢您的大力帮助...。
我爱linux,那里是最好的区,我的Windows真相大白,我知道linux的创建者是Windows的创建者
您好我在grub中收到错误消息
错误:找不到文件/next/START.ELF
错误:您需要先加载内核
你能帮我和谷歌,但我找不到
拜托,如何让它显示消息HELLO WORLD?我是初学者,但我仍然不了解
我发生以下情况:
gcc -o START.ELF kernel.o NextKernel_Main.o -Tlink.ld -nostdlib -fPIC -ffreestand -lgcc
/usr/bin/ld:kernel.o:在创建PIE对象时,不能将R_X86_64_32相对于符号'stack'进行重定位; 用-fPIE重新编译
/ usr / bin / ld:最终链接失败:输出中的不可代表部分
collect2:错误:ld返回1退出状态