linux内核是否有main函数

服务器   发布日期:2024年05月06日   浏览次数:914

本篇内容主要讲解“linux内核是否有main函数”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“linux内核是否有main函数”吧!

linux内核有main函数;main函数是程序的入口,main是应用程序和操作系统之间约定好的一个接口名,所以linux中每个应用程序的第一个函数必须是main。

linux内核源码之main函数解析

这几天一直在纠结:

main函数是程序的入口,一个程序启动后,经过bootloader的初始化就该经main函数进入C语言的世界,但是linux中每个应用程序的开始都是从main函数开始的。linux下有多个应用程序,岂不是有很多个main。那bootloader会知道跳到哪个main?多个main编译怎么不冲突?

在网上搜索了很久,渐渐的有些明白了:

1、main函数是C语言的入口,这句话没错;但是这句话仅仅是一个约定,而非一个亘古不变的铁律!从程序的更为本质的汇编代码来看,只是大家约定汇编初始化完了后,跳到一个名字叫"main"的标号处;言外之意就是这个标号也是可以改名的,比如linux的C语言入口就是start_kernel();从这个标号地址后就是C语言的天下了。用main这个名字仅仅是因为大家的约定而已,不遵守约定能玩的转也行啊,就像苹果充电线啥的都和别人不一样。

2、在编译时是不存多个main函数的!每个应用程序虽说都有一个main函数(从应用程序来看应用程序的入口是main函数哦);但是应用程序都是独立编译的,不会一起编译,操作系统内核就更不可能和应用程序一起编译了!所以根本不存在多个main冲突的!!可能是统一操作系统与应用程序之间的接口,亦或是侧面影响下main是程序入口的说法,main是应用程序和操作系统之间约定好的一个接口名!所以linux中每个应用程序的第一个函数必须是main。除非你改掉了内核调度的接口地方。

3、linux的应用程序的安装启动也可以类比下我们每天都在用的Windows。Windows应用程序的安装其实也是把一些执行文件拷贝到指定的文件夹里(从绿色软件看),点击就可以运行。linux下也是这样。编译好的bin文件放到指定的文件夹目录下,然后用命令启动执行。

  1. /*
  2. * linux/init/main.c
  3. *
  4. * Copyright (C) 1991, 1992 Linus Torvalds
  5. *
  6. * GK 2/5/95 - Changed to support mounting root fs via NFS
  7. * Added initrd & change_root: Werner Almesberger & Hans Lermen, Feb '96
  8. * Moan early if gcc is old, avoiding bogus kernels - Paul Gortmaker, May '96
  9. * Simplified starting of init: Michael A. Griffith <grif@acm.org>
  10. * start_kernel->rest_init->kernel_init创建用户init pid=1
  11. ->kthreadd管理内核线程 pid=x
  12. ->pid=0,是idle线程
  13. 在rest_init中,会创建kernel_init线程,它负责创建用户init进程,完成工作后,自己
  14. 化身为idle线程
  15. */
  16. #include <linux/types.h>
  17. #include <linux/module.h>
  18. #include <linux/proc_fs.h>
  19. #include <linux/kernel.h>
  20. #include <linux/syscalls.h>
  21. #include <linux/stackprotector.h>
  22. #include <linux/string.h>
  23. #include <linux/ctype.h>
  24. #include <linux/delay.h>
  25. #include <linux/ioport.h>
  26. #include <linux/init.h>
  27. #include <linux/initrd.h>
  28. #include <linux/bootmem.h>
  29. #include <linux/acpi.h>
  30. #include <linux/tty.h>
  31. #include <linux/percpu.h>
  32. #include <linux/kmod.h>
  33. #include <linux/vmalloc.h>
  34. #include <linux/kernel_stat.h>
  35. #include <linux/start_kernel.h>
  36. #include <linux/security.h>
  37. #include <linux/smp.h>
  38. #include <linux/profile.h>
  39. #include <linux/rcupdate.h>
  40. #include <linux/moduleparam.h>
  41. #include <linux/kallsyms.h>
  42. #include <linux/writeback.h>
  43. #include <linux/cpu.h>
  44. #include <linux/cpuset.h>
  45. #include <linux/cgroup.h>
  46. #include <linux/efi.h>
  47. #include <linux/tick.h>
  48. #include <linux/interrupt.h>
  49. #include <linux/taskstats_kern.h>
  50. #include <linux/delayacct.h>
  51. #include <linux/unistd.h>
  52. #include <linux/rmap.h>
  53. #include <linux/mempolicy.h>
  54. #include <linux/key.h>
  55. #include <linux/buffer_head.h>
  56. #include <linux/page_cgroup.h>
  57. #include <linux/debug_locks.h>
  58. #include <linux/debugobjects.h>
  59. #include <linux/lockdep.h>
  60. #include <linux/kmemleak.h>
  61. #include <linux/pid_namespace.h>
  62. #include <linux/device.h>
  63. #include <linux/kthread.h>
  64. #include <linux/sched.h>
  65. #include <linux/signal.h>
  66. #include <linux/idr.h>
  67. #include <linux/kgdb.h>
  68. #include <linux/ftrace.h>
  69. #include <linux/async.h>
  70. #include <linux/kmemcheck.h>
  71. #include <linux/sfi.h>
  72. #include <linux/shmem_fs.h>
  73. #include <linux/slab.h>
  74. #include <linux/perf_event.h>
  75. #include <asm/io.h>
  76. #include <asm/bugs.h>
  77. #include <asm/setup.h>
  78. #include <asm/sections.h>
  79. #include <asm/cacheflush.h>
  80. #ifdef CONFIG_X86_LOCAL_APIC
  81. #include <asm/smp.h>
  82. #endif
  83. static int kernel_init(void *);
  84. extern void init_IRQ(void);
  85. extern void fork_init(unsigned long);
  86. extern void mca_init(void);
  87. extern void sbus_init(void);
  88. extern void prio_tree_init(void);
  89. extern void radix_tree_init(void);
  90. #ifndef CONFIG_DEBUG_RODATA
  91. static inline void mark_rodata_ro(void) { }
  92. #endif
  93. #ifdef CONFIG_TC
  94. extern void tc_init(void);
  95. #endif
  96. /*
  97. * Debug helper: via this flag we know that we are in 'early bootup code'
  98. * where only the boot processor is running with IRQ disabled. This means
  99. * two things - IRQ must not be enabled before the flag is cleared and some
  100. * operations which are not allowed with IRQ disabled are allowed while the
  101. * flag is set.
  102. */
  103. bool early_boot_irqs_disabled __read_mostly;
  104. enum system_states system_state __read_mostly;
  105. EXPORT_SYMBOL(system_state);
  106. /*
  107. * Boot command-line arguments
  108. */
  109. #define MAX_INIT_ARGS CONFIG_INIT_ENV_ARG_LIMIT
  110. #define MAX_INIT_ENVS CONFIG_INIT_ENV_ARG_LIMIT
  111. extern void time_init(void);
  112. /* Default late time init is NULL. archs can override this later. */
  113. void (*__initdata late_time_init)(void);
  114. extern void softirq_init(void);
  115. /* Untouched command line saved by arch-specific code. */
  116. char __initdata boot_command_line[COMMAND_LINE_SIZE];
  117. /* Untouched saved command line (eg. for /proc) */
  118. char *saved_command_line;
  119. /* Command line for parameter parsing */
  120. static char *static_command_line;
  121. static char *execute_command;
  122. static char *ramdisk_execute_command;
  123. /*
  124. * If set, this is an indication to the drivers that reset the underlying
  125. * device before going ahead with the initialization otherwise driver might
  126. * rely on the BIOS and skip the reset operation.
  127. *
  128. * This is useful if kernel is booting in an unreliable environment.
  129. * For ex. kdump situaiton where previous kernel has crashed, BIOS has been
  130. * skipped and devices will be in unknown state.
  131. */
  132. unsigned int reset_devices;
  133. EXPORT_SYMBOL(reset_devices);
  134. static int __init set_reset_devices(char *str)
  135. {
  136. reset_devices = 1;
  137. return 1;
  138. }
  139. __setup("reset_devices", set_reset_devices);
  140. static const char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
  141. const char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
  142. static const char *panic_later, *panic_param;
  143. extern const struct obs_kernel_param __setup_start[], __setup_end[];
  144. static int __init obsolete_checksetup(char *line)
  145. {
  146. const struct obs_kernel_param *p;
  147. int had_early_param = 0;
  148. p = __setup_start;
  149. do {
  150. int n = strlen(p->str);
  151. if (parameqn(line, p->str, n)) {
  152. if (p->early) {
  153. /* Already done in parse_early_param?
  154. * (Needs exact match on param part).
  155. * Keep iterating, as we can have early
  156. * params and __setups of same names 8( */
  157. if (line[n] == '

以上就是linux内核是否有main函数的详细内容,更多关于linux内核是否有main函数的资料请关注九品源码其它相关文章!