在linux中是如何运行一个应用程序的?
比如我们编写好一个c文件,然后用对应的gcc编译链接成一个可执行程序a.out,这个a.out此时就处于Linux根文件系统的某个目录下面,如果我们想要执行该应用程序,直接在对应目录下./a.out即可。
注意,这个过程我们只编译了这个应用程序,并没有编译Linux内核,也就是说,该可执行程序a.out是独立于Linux内核的。linux中有大量的可执行程序,比如/bin目录下面的所有程序,这些程序一般都是我们手动去执行的,如果想要自启动,也就是linux内核启动之后就跟着启动,可以在rcs脚本中写上执行语句,这就是程序的自启动方法。类比windows下的程序,总是提醒你要不要加入开机自启动,就是这个意思。
环境变量 PATH
在Linux中,有一个与执行程序相关的环境变量PATH,非常重要。
比如,在Linux系统中,直接输入命令如
ls
而没有指定命令的绝对路径/usr/bin/ls
,系统也能正确的执行,这是因为 环境变量 PATH 的作用,它指定系统在执行命令时搜索可执行文件的路径。当用户在终端输入一个命令时,系统会在 PATH 指定的路径中查找该命令的可执行文件。如果找到了,就会执行该命令;如果没有找到,则会提示“命令不存在”的错误信息。
查看环境变量 PATH
# 输入命令 echo $PATH # 可能返回以下内容 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
例如 PATH 的值是
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
,那么 系统会首先在/usr/local/sbin
目录下查找命令,如果没找到,再到/usr/local/bin
目录下查找,以此类推。注意事项
不同身份的用户默认环境变量 PATH 不同
环境变量 PATH 是可以被修改的
在不确定的情况下,使用绝对路径来指定某个命令更为准确
在添加自定义目录前,先检查该目录下是否存在与系统命令同名的可执行文件,以免发生冲突,导致系统命令被覆盖或无法正常工作。
谨慎添加不受信任的目录到环境变量 PATH 中,特别是具有系统级权限的目录,这可能会导致恶意软件被执行或系统安全受到威胁。
试想下我们在ubuntu等linux的PC系统上开发应用程序时,都是把应用程序或者驱动程序放到根文件系统下,没有去动uboot或者kernel内核。通常,我们不要随便去操作内核,容易出问题。相对而言,根文件系统更方便操作。
再考虑嵌入式环境下,我们也可以把程序和驱动都放在根文件系统下,然后把根文件系统烧录到开发板,这种情况我们就不用动内核了。同理,如果需要自启动,就在启动脚本里写上对应的执行命令。
自启动具体方法参考:
linux驱动模块开机自动加载,以及应用程序开机自启动 - 小羊实验室 - 博客园 (cnblogs.com)
在Linux系统中,程序被放在根文件系统下的原因主要有以下几点:
启动引导的必要:根文件系统是内核启动时所挂载的第一个文件系统,它包含了系统启动所必需的目录和关键性文件。例如,init进程的应用程序、shell命令程序(如ls、cd等)以及内核代码映像文件都保存在根文件系统中。这些文件对于系统的正常启动和运行至关重要。
配置和管理的核心:根文件系统提供了根目录“/”,这是整个文件系统的起始点。此外,系统的应用层配置(如etc目录下的配置文件)、可执行程序(如/bin、/sbin目录下的命令)以及库文件(如/lib目录下的库)等也位于根文件系统中。这些文件和目录共同构成了Linux发行版的核心部分,与内核一起协同工作,使Linux系统能够正常运行。
挂载其他文件系统的基础:根文件系统不仅是自身必需的,它还是加载其他文件系统的基础。如果没有根文件系统,其他的文件系统将无法被加载。因此,根文件系统在整个文件系统结构中扮演着至关重要的角色。
综上所述,程序被放在根文件系统下是因为根文件系统是Linux系统启动和运行的基础,它包含了系统启动和运行所必需的关键文件和目录,并且是挂载其他文件系统的前提。
注意,一个可执行程序通常就是一个进程。
更多后续细节可参考:
在Linux系统中程序是如何执行的?_linux可执行程序-CSDN博客
上层的应用程序没有编译到内核还是编译成独立模块这么个说法,应用程序都是独立的模块,不过我们可以设置自启动还是手动执行启动。
应用程序理论上可以编译到内核里去,但这种做法并不常见,且存在一些限制和考虑。
应用程序通常运行在用户空间,而内核是操作系统的核心部分,负责管理硬件资源、提供系统服务等。将应用程序编译到内核中,意味着该程序将成为内核的一部分,具有更高的权限和访问能力。然而,这也带来了一些潜在的风险和问题:
安全性:内核是系统的关键部分,任何在内核中的漏洞或错误都可能导致整个系统的崩溃或安全漏洞。因此,将应用程序编译到内核中需要非常小心,确保代码的质量和安全性。
稳定性:内核需要保持高度的稳定性,因为它是整个系统的基础。如果内核频繁崩溃或出现不稳定情况,将严重影响系统的性能和用户体验。
性能:虽然将应用程序编译到内核中可能提高某些操作的性能(如减少用户态和内核态之间的切换开销),但这也可能导致内核变得庞大和复杂,从而影响整体性能。
可维护性:内核代码通常比用户空间代码更难调试和维护。将应用程序编译到内核中可能会增加开发和维护的难度。
灵活性:用户空间应用程序可以根据需要进行更新和替换,而不需要重启系统或重新编译内核。将应用程序编译到内核中将失去这种灵活性。
综上所述,尽管技术上可以将应用程序编译到内核中去,但这种做法并不推荐,除非有特殊的需求和充分的理由。在大多数情况下,应用程序应该作为独立的用户空间进程运行,通过系统调用与内核进行交互。