当前位置:  开发笔记 > 编程语言 > 正文

什么样的C是写入的操作系统?

如何解决《什么样的C是写入的操作系统?》经验,为你挑选了4个好方法。

有意义的是像操作系统这样的东西会用C编写.但它有多少,以及什么样的C?我的意思是,在C中,如果你需要一些堆内存,你可以调用malloc.但是,操作系统甚至堆吗?据我所知,malloc 向操作系统询问内存,然后将其添加到链表,二叉树或其他内容.调用堆栈怎么样?操作系统负责设置其他应用程序使用的所有内容,但它是如何做到的?如果要在C中打开或创建文件,相应的函数会向操作系统询问该文件.所以...那个电话的另一边有什么样的C?或者在内存分配的另一端?

另外,实际上用C编写了多少操作系统?所有的?架构相关代码怎么样?那些更高级别的抽象怎么样?是否用高级语言编写,比如C++?

我的意思是,我只是出于纯粹的好奇而问这个问题.我现在正在下载最新的Linux内核,但这需要永远.我不确定我是否能够遵循代码 - 或者我是否会陷入一个我从未见过的不可避免的复杂网络中.



1> cygil..:

所有的优秀问题.答案是:用于编写操作系统的C语言"方言"中几乎没有标准C库可用.例如,在Linux内核中,标准内存分配函数malloc,nmalloc,free等被替换为特殊的内核 - 内部内存分配函数kmalloc和kfree,对它们的使用有特殊限制.操作系统必须提供自己的"堆" - 在Linux内核中,为内核使用而分配的物理内存页必须是不可分页的,并且通常是物理上的连接.请参阅关于kmalloc和kfree的这篇Linux期刊文章.类似地,操作系统内核维护自己的特殊调用堆栈,其使用需要来自内存的GCC编译器的特殊支持.

另外,实际上用C编写了多少操作系统?所有的?

据我所知,操作系统绝大部分是用C语言编写的.一些特定于体系结构的特性是用汇编语言编写的,但通常很少能提高可移植性和可维护性:Linux内核有一些汇编程序,但试图将其最小化.可能.

架构相关代码怎么样?那些更高级别的抽象怎么样?是否用高级语言编写,比如C++?

通常内核将使用纯C编写,但有时更高级别的框架和API是用更高级别的语言编写的.例如,MacOS上的Cocoa框架/ API是用Objective C编写的,而BeOS更高级别的API是用C++编写的.Microsoft的.NET框架大部分是用C#编写的,"公共语言运行时"是用C++和汇编语言编写的.Linux上最常用的QT小部件集是用C++编写的.当然,这引入了关于什么算作"操作系统"的哲学问题.

Linux内核绝对值得关注,但是,必须要说的是,任何人从头开始阅读都是巨大的,令人生畏的.


当你说内核通常用C语言编写时,这就省略了一个关键的操作系统,即Windows,它是一个混合的C和C++内核; 执行(NT)部分是用C语言编写的,但内核的Win32部分(主要驻留在win32k.sys中,负责字体,窗口,图形,DirectX等)主要是用C++编写的.

2> Michael Sofa..:

什么样的C?

大部分是ANSI C,很多时候都在查看它生成的机器代码.

但是,操作系统甚至有堆吗?

Malloc向操作系统询问指向允许使用的某些内存的指针.如果在OS(用户模式)上运行的程序试图访问它不拥有的内存,则会产生分段错误.允许操作系统直接访问系统上的所有物理内存,不需要malloc,不存在任何存在的地址上的seg-fault.

调用堆栈怎么样?

调用堆栈实际上通常在硬件级别上工作,具有链接寄存器.

对于文件访问,操作系统需要访问磁盘驱动程序,磁盘驱动程序需要知道如何读取磁盘上的文件系统(有很多不同类型)有时操作系统内置了一个,但我认为它更常见引导装载程序将它从一个开始,然后加载另一个(更大的).磁盘驱动程序可以访问物理磁盘的硬件IO,并从中构建.



3> amazedsaint..:

C是一种非常低级的语言,你可以直接做很多事情.需要首先实现任何C库方法(如malloc,printf,crlscr等),以便从C调用它们(例如,查看libc概念).我将在下面给出一个例子.

让我们看看C库方法是如何在幕后实现的.我们将以一个clrscr为例.实现此类方法时,您将直接访问系统设备.例如,对于clrscr(清除屏幕),我们知道视频内存驻留在0xB8000.因此,要写入屏幕或清除它,我们首先指定一个指向该位置的指针.

在video.c

void clrscr()
{

   unsigned char *vidmem = (unsigned char *)0xB8000;
   const long size = 80*25;
   long loop;

   for (loop=0; loop

现在让我们编写我们的迷你内核.当控件从引导加载程序移交给我们的"内核"时,这将清除屏幕.在main.c

void main()
{
   clrscr();
   for(;;);
}

要编译我们的'内核',您可以使用gcc将其编译为纯bin格式.

gcc -ffreestanding -c main.c -o main.o
gcc -c video.c -o video.o
ld -e _main -Ttext 0x1000 -o kernel.o main.o video.o
ld -i -e _main -Ttext 0x1000 -o kernel.o main.o video.o
objcopy -R .note -R .comment -S -O binary kernel.o kernel.bin

如果您注意到上面的ld参数,您会看到我们将内核的默认加载位置指定为0x1000.现在,您需要创建一个引导加载程序.从您的引导加载程序逻辑,您可能希望将控制权传递给您的内核,例如

jump 08h:01000h

您通常在Asm中编写引导加载程序逻辑.在此之前,您可能需要了解一下PC Boots的方式 - 点击这里.

最好从一个更小的操作系统开始探索.请参阅此自行操作系统教程

http://www.acm.uiuc.edu/sigops/roll_your_own/



4> Unknown..:

但它有多少,以及什么样的C?

某些部件必须用汇编语言编写

我的意思是,在C中,如果你需要一些堆内存,你可以调用malloc.但是,操作系统甚至有堆吗?据我所知,malloc向操作系统询问内存,然后将其添加到链表,二叉树或其他内容.

有些操作系统有堆.在最低级别,它们是被称为页面的内存块.然后,您的C库使用malloc以可变大小的方式使用自己的方案进行分区.您应该了解虚拟内存,这是现代操作系统中常见的内存方案.

如果要在C中打开或创建文件,相应的函数会向操作系统询问该文件.所以...那个电话的另一边有什么样的C?

您调用汇编例程,使用IN和OUT等指令查询硬件.对于原始内存访问,有时您会有专门用于与硬件进行通信的内存区域.这称为DMA.

我不确定我是否能够遵循代码 - 或者我是否会陷入一个我从未见过的不可避免的复杂网络中.

是的你将会.你应该先拿起一本关于硬件和操作系统的书.

推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有