(ffffffffad4033a0 - ffffffffad402940) = 0xa60 = 2656
即系统调用表的大小是2656字节
2656 / 8 = 332
系统调用表数组中的成员数量是332,即该版本系统调用的数目是332。
(4)内核数据段:
/\*\*
\* core\_kernel\_data - tell if addr points to kernel data
\* @addr: address to test
\*
\* Returns true if @addr passed in is from the core kernel data
\* section.
\*
\* Note: On some archs it may return true for core RODATA, and false
\* for others. But will always be true for core RW data.
\*/
int core\_kernel\_data(unsigned long addr)
{
if (addr >= (unsigned long)_sdata &&
addr < (unsigned long)_edata)
return 1;
return 0;
}
"D/d" The symbol is in the initialized data section.
(5)内核BSS段:
"B/b" The symbol is in the BSS data section. This section typically contains zero-initialized or uninitialized data, although the exact behavior is system dependent.
(6)
其中"D/d" -> “B/b” 之间有一部分内核启动时,内核退出时所用到的代码段,内核正常运行后,不会在调用这一部分内核代码段。
这一部分也属于内核段,并且属于内核代码段,但是这部分是内核启动,内核退出时用到的代码段,内核正常运行时并不会调用,这部分内核代码段没有在 _text 到 _etext 之间。
_sinittext到_einittext是内核初始化时运行的代码,内核正常运行时并不会调用。
system_state == SYSTEM_BOOTING
/\* Values used for system\_state \*/
extern enum system\_states {
SYSTEM_BOOTING,
SYSTEM_RUNNING,
SYSTEM_HALT,
SYSTEM_POWER_OFF,
SYSTEM_RESTART,
} system_state;
static inline int init\_kernel\_text(unsigned long addr)
{
if (addr >= (unsigned long)_sinittext &&
addr <= (unsigned long)_einittext)
return 1;
return 0;
}
int core\_kernel\_text(unsigned long addr)
{
if (addr >= (unsigned long)_stext &&
addr <= (unsigned long)_etext)
return 1;
if (
&&
init\_kernel\_text(addr))
return 1;
return 0;
}
ffffffff9dd68000 D __init_begin
ffffffff9dd68000 D __per_cpu_load
ffffffff9dd85000 T early_idt_handler_array
ffffffff9dd85000 T _sinittext
ffffffff9dd85120 t early_idt_handler_common
ffffffff9dd851d7 t is_nmi
ffffffff9dd851f0 T startup_xen
ffffffff9dd85205 t copy_bootdata
ffffffff9dd853c1 t reset_early_page_tables
ffffffff9dd85496 T __early_make_pgtable
ffffffff9dd856e8 T early_make_pgtable
ffffffff9dd8570b T x86_64_start_reservations
ffffffff9dd85731 T x86_64_start_kernel
ffffffff9dd858a8 T reserve_ebda_region
ffffffff9dd85904 t set_reset_devices
ffffffff9dd85919 t debug_kernel
ffffffff9dd8592b t quiet_kernel
ffffffff9dd8593d t init_setup
ffffffff9dd85965 t rdinit_setup
ffffffff9dd8598d t loglevel
ffffffff9dd859e1 t do_early_param
ffffffff9dd85a6f t initcall_blacklist
ffffffff9dd85b1f t repair_env_string
ffffffff9dd85b7b t unknown_bootoption
ffffffff9dd85d04 T parse_early_options
ffffffff9dd85d2c T parse_early_param
ffffffff9dd85d69 W smp_setup_processor_id
ffffffff9dd85d6f W thread_info_cache_init
ffffffff9dd85d7b T start_kernel
ffffffff9dd861e7 t kernel_init_freeable
ffffffff9dd86406 T load_default_modules
ffffffff9dd86411 t rootwait_setup
.......
ffffffff8a7eea46 t packet_init
ffffffff8a7eea88 t wireless_nlevent_init
ffffffff8a7eeac1 T netlbl_netlink_init
ffffffff8a7eeade t netlbl_init
ffffffff8a7eeb61 T netlbl_domhsh_init
ffffffff8a7eec18 T netlbl_mgmt_genl_init
ffffffff8a7eec2a T netlbl_unlabel_genl_init
ffffffff8a7eec3c T netlbl_unlabel_init
ffffffff8a7eed03 T netlbl_unlabel_defconf
ffffffff8a7eed9d T netlbl_cipsov4_genl_init
ffffffff8a7eedaf t dcbnl_init
ffffffff8a7eedfc T net_sysctl_init
ffffffff8a7eee4b t mpls_gso_init
ffffffff8a7eee79 T _einittext
......
ffffffff9df3be81 t nvmem_exit
ffffffff9df3be93 t vmd_drv_exit
ffffffff9df3bea5 t sock_diag_exit
ffffffff9df3beb7 t exit_cgroup_netprio
ffffffff9df3bf1d t exit_cgroup_cls
ffffffff9df3bf3b t xt_fini
ffffffff9df3bf59 t tcpudp_mt_exit
ffffffff9df3bf70 t ipv4_netfilter_fini
ffffffff9df3bf82 t cubictcp_unregister
ffffffff9df3bf94 t xfrm_user_exit
ffffffff9df3bfb2 t af_unix_exit
ffffffff9df3bfda t inet6_exit
ffffffff9df3c0b8 t packet_exit
ffffffff9df3c0ec t dcbnl_exit
ffffffff9df3c162 t mpls_gso_exit
ffffffff9df3d000 R __smp_locks
ffffffff9df3d000 R __init_end
ffffffff9df44000 D in_suspend
ffffffff9df44000 D __nosave_begin
ffffffff9df44000 R __smp_locks_end
ffffffff9df45000 B empty_zero_page
ffffffff9df45000 B __bss_start
ffffffff9df45000 D __nosave_end
ffffffff9df46000 b dummy_mapping
ffffffff9df47000 b level3_user_vsyscall
ffffffff9df48000 B idt_table
ffffffff9df49000 B debug_idt_table
ffffffff9df4a000 B trace_idt_table
ffffffff9df4b000 b bm_pte
ffffffff9df4c000 B initcall_debug
ffffffff9df4c004 B reset_devices
ffffffff9df4c008 B saved_command_line
ffffffff9df4c020 b msgbuf
(7)
通过读取vmlinux文件也可以发现,vmlinux 内核镜像 除了 _text到 _etext 这一块代码段之外,还有几块代码段:
[root@localhost ~]# readelf -S vmlinux
There are 36 section headers, starting at offset 0x13451a0:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .text PROGBITS ffffffff81000000 00200000
000000000077c25f 0000000000000000 AX 0 0 4096
[ 2] .notes NOTE ffffffff8177c260 0097c260
000000000000017c 0000000000000000 AX 0 0 4
[ 3] __ex_table PROGBITS ffffffff8177c3e0 0097c3e0
0000000000002050 0000000000000000 A 0 0 8
[ 4] __mc_table PROGBITS ffffffff8177e430 0097e430
0000000000000024 0000000000000000 A 0 0 4
[ 5] .rodata PROGBITS ffffffff81800000 00a00000
000000000030777e 0000000000000000 A 0 0 128
[ 6] __bug_table PROGBITS ffffffff81b07780 00d07780
0000000000006318 0000000000000000 A 0 0 1
[ 7] __unwind_end_of_s PROGBITS ffffffff81b0da98 00d0da98
0000000000000068 0000000000000000 A 0 0 1
[ 8] __unwind_unsafe_s PROGBITS ffffffff81b0db00 00d0db00
00000000000001d0 0000000000000000 A 0 0 1
[ 9] .pci_fixup PROGBITS ffffffff81b0dcd0 00d0dcd0
00000000000038b8 0000000000000000 A 0 0 8
[10] .tracedata PROGBITS ffffffff81b11588 00d11588
000000000000003c 0000000000000000 A 0 0 1
[11] __ksymtab PROGBITS ffffffff81b115d0 00d115d0
0000000000011f20 0000000000000000 A 0 0 16
[12] __ksymtab_gpl PROGBITS ffffffff81b234f0 00d234f0
000000000000df80 0000000000000000 A 0 0 16
[13] __kcrctab PROGBITS ffffffff81b31470 00d31470
0000000000008f90 0000000000000000 A 0 0 8
[14] __kcrctab_gpl PROGBITS ffffffff81b3a400 00d3a400
0000000000006fc0 0000000000000000 A 0 0 8
[15] __ksymtab_strings PROGBITS ffffffff81b413c0 00d413c0
00000000000261c0 0000000000000000 A 0 0 1
[16] __init_rodata PROGBITS ffffffff81b67580 00d67580
00000000000000e8 0000000000000000 A 0 0 32
[17] __param PROGBITS ffffffff81b67668 00d67668
0000000000001d80 0000000000000000 A 0 0 8
[18] __modver PROGBITS ffffffff81b693e8 00d693e8
0000000000000c18 0000000000000000 A 0 0 8
[19] .data PROGBITS ffffffff81c00000 00e00000
0000000000166200 0000000000000000 WA 0 0 8192
[20] .vvar PROGBITS ffffffff81d67000 00f67000
00000000000000f0 0000000000000000 WA 0 0 16
[21] .data..percpu PROGBITS 0000000000000000 01000000
000000000001d000 0000000000000000 WA 0 0 4096
[22] .init.text PROGBITS ffffffff81d85000 01185000
0000000000069e79 0000000000000000 AX 0 0 16
[23] .init.data PROGBITS ffffffff81df0000 011f0000
0000000000124020 0000000000000000 WA 0 0 8192
[24] .x86_cpu_dev.init PROGBITS ffffffff81f14020 01314020
0000000000000018 0000000000000000 A 0 0 8
[25] .parainstructions PROGBITS ffffffff81f14038 01314038
000000000001d92c 0000000000000000 A 0 0 8
[26] .altinstructions PROGBITS ffffffff81f31968 01331968
00000000000069d8 0000000000000000 A 0 0 1
[27] .altinstr_replace PROGBITS ffffffff81f38340 01338340
000000000000217e 0000000000000000 AX 0 0 1
[28] .iommu_table PROGBITS ffffffff81f3a4c0 0133a4c0
00000000000000f0 0000000000000000 A 0 0 8
[29] .apicdrivers PROGBITS ffffffff81f3a5b0 0133a5b0
0000000000000028 0000000000000000 WA 0 0 8
[30] .exit.text PROGBITS ffffffff81f3a5d8 0133a5d8
0000000000001ba8 0000000000000000 AX 0 0 1
[31] .smp_locks PROGBITS ffffffff81f3d000 0133d000
0000000000007000 0000000000000000 A 0 0 4
[32] .data_nosave PROGBITS ffffffff81f44000 01344000
0000000000001000 0000000000000000 WA 0 0 4
[33] .bss NOBITS ffffffff81f45000 01345000
000000000030c000 0000000000000000 WA 0 0 4096
[34] .brk NOBITS ffffffff82251000 01345000
0000000000429000 0000000000000000 WA 0 0 1
[35] .shstrtab STRTAB 0000000000000000 01345000
000000000000019b 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
l (large), p (processor specific)
其中的下面几个 section 都不属于内核 text section,但都是vmlinux 镜像中的代码段:
[ 2] .notes NOTE ffffffff8177c260 0097c260
000000000000017c 0000000000000000 AX 0 0 4
[22] .init.text PROGBITS ffffffff81d85000 01185000
0000000000069e79 0000000000000000 AX 0 0 16
[27] .altinstr_replace PROGBITS ffffffff81f38340 01338340
000000000000217e 0000000000000000 AX 0 0 1
[30] .exit.text PROGBITS ffffffff81f3a5d8 0133a5d8
0000000000001ba8 0000000000000000 AX 0 0 1
X (execute),表示可执行,也就是代码段。
总结
内核段的符号从代码段的符号_text 到 BSS段的符号_end,之后就是模块的相关符号了。模块的符号肯定大于内核段中的符号。
备注:模块的符号大于内核段中的符号这是相对于x86_64,对于ARM64,在Linux 4.6 中 将内核镜像移到vmalloc的区域了。因此在ARM64,Linux 4.6 以上的版本内核段中的符号都大于模块的符号。
比如:
5.4.18-74-generic aarch64 GNU/Linux
ffffffc010080000 T _text
......
ffffffc0117f4000 B _end
ffffffc0092dc380 d $d [virt_wifi]
ffffffc0092da024 r $d [virt_wifi]
ffffffc0092da024 r _note_6 [virt_wifi]
......
内核段的地址都大于模块的地址。
ARM64在Linux 4.6 中 将内核镜像移到vmalloc的区域的原因:
arm64: move kernel image to base of vmalloc area
最全的Linux教程,Linux从入门到精通
======================
-
linux从入门到精通(第2版)
-
Linux系统移植
-
Linux驱动开发入门与实战
-
LINUX 系统移植 第2版
-
Linux开源网络全栈详解 从DPDK到OpenFlow
第一份《Linux从入门到精通》466页
====================
内容简介
====
本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。
本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。
需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!