我认为SimonJ的回答非常好,但是根据你的评论,似乎你还没有完全理解。首先,在启动操作系统时,你所做的就是将内核加载到内存中并说“从地址X开始执行”。内核,也就是那段代码,本质上只是一个程序,但当然没有其他东西被加载,因此如果它想要做任何事情,它必须知道特定硬件的确切命令。
你不必运行内核。实际上,如果你知道如何控制所有连接的硬件,你根本不需要内核。但是,早在很久以前,人们就意识到可能会面临许多类型的硬件,并且具有跨系统相同的接口来编程将使代码可移植,并通常有助于更快地完成任务。
因此,内核的功能是控制连接到系统的所有硬件并将其呈现在称为API(应用程序编程接口)的公共接口中。在系统上运行的程序的代码不直接与硬件交互,而是与内核交互。因此,用户空间程序不需要知道如何请求特定硬盘读取扇区0x213E或其他内容,但内核需要知道。
现在,SimonJ的答案中提供的关于ring 3的描述是如何实现用户空间的——具有隔离的、非特权进程,具有虚拟私有地址空间,不能相互干扰,以获得他所描述的好处。
这里还有另一种复杂性水平,即权限的概念。大多数操作系统都有某种形式的访问控制,其中“管理员”对系统拥有完全控制,“用户”只有一组受限选项。因此,在这种方法下,内核请求打开属于管理员的文件应该失败。运行程序的用户构成了程序的上下文,如果你愿意的话,程序可以做什么受到该用户能够做什么的限制。
除非你的意图是编写内核,否则你几乎可以在root/administrator用户的userland中完成你想要实现的大部分事情,内核不会拒绝任何向它发出的API请求。它仍然是一个用户空间程序。它仍然是一个ring 3程序。但是对于大多数(几乎所有)用途而言,这已经足够了。作为非root/administrative用户也可以实现很多内容。
这适用于Python解释器,以及通过扩展运行在该解释器上的所有Python代码。
让我们来处理一些不确定性:
os
和sys
的命名是因为它们是“系统”任务(与例如urllib2
不同)。它们提供了操作和打开文件的方式。但是,这些任务通过Python解释器进行,进而调用内核。
- 我不知道有任何内核模式的Python实现。因此据我所知,没有办法编写能在内核(Linux/Windows)中运行的Python代码。
- 有两种类型的特权:硬件访问方面的特权和内核提供的访问控制系统方面的特权。Python可以作为root/管理员运行(事实上,在Linux上许多管理GUI工具都是用Python编写的),因此在某种意义上它可以访问特权代码。
- 编写C扩展或将C应用程序控制到Python中,表面上意味着您正在使用添加到解释器(用户空间)的代码,或者控制另一个用户空间应用程序。然而,如果您在C中编写了一个内核模块(Linux)或驱动程序(Windows),则可以从Python加载该驱动程序并通过内核API与其交互。例如,创建C中的/proc条目,然后使您的Python应用程序通过读/写将消息传递到该/proc条目(内核模块必须通过write/read处理程序来处理)。实质上,您编写要在内核空间中运行的代码,并以多种方式之一添加/扩展内核API,以便您的程序可以与该代码交互。
- “低级”IO意味着对发生的IO类型和如何从操作系统获取数据有更多的控制。它与Python中仍然提供易于读取文件的更高级函数(以控制为代价)相比较低级。这类似于C中的
read()
调用和fread()
或fscanf()
之间的区别。
健康警告:如果编写内核模块出错,最好的情况是该模块无法正确加载;最坏的情况是您的系统会崩溃/蓝屏并且您需要重新启动。
关于机器指令的最后一点我无法在此回答。这是一个完全不同的问题,具体情况视情况而定。我相信有许多能够分析这样的代码的工具,但我不是逆向工程师。但是,我知道许多这些工具(例如gdb、valgrind)——钩入二进制代码的工具不需要内核模块即可完成其工作。
ctypes
这样的模块,允许您调用其他操作系统API。但是您的用户权限决定了API是否有效或引发异常。您是在问如何使用ctypes
吗? - S.Lott