chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

細(xì)說vDSO機(jī)制原理

Linux愛好者 ? 來源:hsqstephenzhang.github.io ? 2023-06-14 12:33 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1. 什么是 vDSO

眾所周知,操作系統(tǒng)為我們管理硬件資源,并以系統(tǒng)調(diào)用的方式對(duì)用戶進(jìn)程提供 API,但是syscall很慢,涉及陷入內(nèi)核以及上下文切換。對(duì)于少量頻繁調(diào)用的系統(tǒng)調(diào)用(比如獲取當(dāng)期系統(tǒng)時(shí)間)來說,是否可以某種安全的方式開放到用戶空間,讓用戶直接訪問而不需要經(jīng)過syscall呢?

vDSO就是用來解決這個(gè)問題的。

vDSO全稱為virtual dynamic shared object,dynamic shared object 這個(gè)名詞大家應(yīng)該有所耳聞,就是 Linux 下的動(dòng)態(tài)庫的全稱,而 virtual 表明,這個(gè)動(dòng)態(tài)庫是通過某種手段虛擬出來的,并不真正存在于 Linux 文件系統(tǒng)中。

要驗(yàn)證這點(diǎn)也很簡單,只需要通過 ldd 命令,查看一些可執(zhí)行文件所依賴的動(dòng)態(tài)庫即可,

$ldd/bin/ls
linux-vdso.so.1(0x00007ffe4e4ce000)
libcap.so.2=>/usr/lib/libcap.so.2(0x00007f7bf818e000)
libc.so.6=>/usr/lib/libc.so.6(0x00007f7bf7fc2000)
/lib64/ld-linux-x86-64.so.2=>/usr/lib64/ld-linux-x86-64.so.2(0x00007f7bf81e8000)

可以明顯看出,在ls 這個(gè)可執(zhí)行文件依賴的動(dòng)態(tài)庫列表中,除了 linux-vdso.so.1 都有明確的路徑,同時(shí)還可以通過 proc 文件系統(tǒng)中進(jìn)程的內(nèi)存映射(memory map)情況來映射這一點(diǎn):

$cat/proc/1/maps
....
7fd37e90f000-7fd37e911000rw-p0002f000103:0213244335/usr/lib/ld-2.33.so
7ffc2f7ce000-7ffc2f7ef000rw-p0000000000:000[stack]
7ffc2f7f7000-7ffc2f7fb000r--p0000000000:000[vvar]
7ffc2f7fb000-7ffc2f7fd000r-xp0000000000:000[vdso]
ffffffffff600000-ffffffffff601000--xp0000000000:000[vsyscall]

可以看出,vDSO 確實(shí)是以共享庫的形式存在于每一個(gè)進(jìn)程當(dāng)中的。

通過 vDSO,進(jìn)程訪問一些系統(tǒng)提供的 API,就可以直接在自己的地址空間訪問,而不需要進(jìn)行用戶-內(nèi)核態(tài)的狀態(tài)切換了

2. vDSO 實(shí)現(xiàn)原理

linux-vdso.so.1既然不是一個(gè)實(shí)實(shí)在在的文件,那其中的內(nèi)容就應(yīng)該直接保存在內(nèi)存中,Linux 使用vdso_image來表示

2.1 vDSO image

在arch/x86/entyr/vdso/vdso-image-64.c文件中,定義了下面的vdso_image:

staticunsignedcharraw_data[8192]__ro_after_init__aligned(PAGE_SIZE)={
0x7F,0x45,0x4C,0x46,0x02,0x01,0x01,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x3E,0x00,
...
};

conststructvdso_imagevdso_image_64={
.data=raw_data,
.size=8192,
.alt=3013,
.alt_len=91,
.sym_vvar_start=-16384,
.sym_vvar_page=-16384,
.sym_pvclock_page=-12288,
.sym_hvclock_page=-8192,
.sym_timens_page=-4096,
};

vdso_image.raw_data對(duì)應(yīng)的就是 vDSO 提供的所有系統(tǒng)調(diào)用的二進(jìn)制指令,一共有 8192 字節(jié),相當(dāng)于下面的結(jié)構(gòu):

staticstructpage*pages[2];

vdso_iamge_64自然需要保存到全局變量中才能發(fā)揮作用,這就涉及接下來要提到的 vDSO 初始化。

2.2 vDSO 初始化

vDSO 通過init_vdso()函數(shù)來初始化,通過條件編譯對(duì) 32/64 bit 的 image 進(jìn)行選擇。同時(shí)也需要通過subsys_initcall(init_vdso)將init_vdso()放到initcall列表中。

init_vdso_image()這里不過多介紹,主要是用來優(yōu)化指令,畢竟 vdso_image 中提供的二進(jìn)制指令是手動(dòng)放在一個(gè)數(shù)組中的,還有相當(dāng)大的優(yōu)化空間

staticint__initinit_vdso(void)
{
BUILD_BUG_ON(VDSO_CLOCKMODE_MAX>=32);

init_vdso_image(&vdso_image_64);

#ifdefCONFIG_X86_X32_ABI
init_vdso_image(&vdso_image_x32);
#endif

return0;
}
subsys_initcall(init_vdso);

2.3 vDSO 和 可執(zhí)行程序

如果你對(duì) Linux 可執(zhí)行程序的 加載-執(zhí)行機(jī)制有所研究,就知道對(duì)于 elf 格式的可執(zhí)行程序而言,最終調(diào)用了load_elf_binary()這個(gè)回調(diào)函數(shù),在這個(gè)函數(shù)中,會(huì)根據(jù) elf 文件頭中的描述,設(shè)置好新進(jìn)程的各個(gè)段,并將 elf 文件中的內(nèi)容拷貝到相應(yīng)位置。

為什么好端端的,要提到可執(zhí)行程序加載呢?這是因?yàn)?,在系統(tǒng)初始化完成之后,vdso_image已經(jīng)設(shè)置完畢,只需要在每次加載二進(jìn)制可執(zhí)行程序的時(shí)候,分配一塊內(nèi)存空間,將vdso_image加載到該位置即可。

這就是arch_setup_additional_pages()函數(shù)所要完成的任務(wù)了:

intarch_setup_additional_pages(structlinux_binprm*bprm,intuses_interp)
{
if(!vdso64_enabled)
return0;
returnmap_vdso_randomized(&vdso_image_64);
}

map_vdso_randomized()會(huì)通過stack protect機(jī)制,選擇一個(gè)隨機(jī)的加載地址,并調(diào)用map_vdso完成 mapping 工作,該函數(shù)內(nèi)容較多,這里不贅述。

最終,vDSO 會(huì)向用戶提供四個(gè)系統(tǒng)調(diào)用:

__vdso_clock_gettime()
__vdso_getcpu()
__vdso_gettimeofday()
__vdso_time()

你還別不信,可以自行驗(yàn)證一下:

使用命令cat /proc/1/maps找到[vdso]對(duì)應(yīng)的內(nèi)存位置。

通過 dd 命令將內(nèi)存的影像 dump 到文件中,如:dd if=/proc/1/mem of=/tmp/linux-vdso.so skip=140728627781632 ibs=1 count=4096,其中 skip 的值為 vdso 的內(nèi)存起始地址,count 為這塊內(nèi)存的大小。

使用objdump命令查看linux-vdso.so中所有符號(hào)objdump -T /tmp/linux-vdso.so,最終結(jié)果如下。

linux-vdso.so:fileformatelf64-x86-64

DYNAMICSYMBOLTABLE:
0000000000000740wDF.text000000000000015dLINUX_2.6clock_gettime
0000000000000600gDF.text0000000000000127LINUX_2.6__vdso_gettimeofday
00000000000008a0wDF.text0000000000000044LINUX_2.6clock_getres
00000000000008a0gDF.text0000000000000044LINUX_2.6__vdso_clock_getres
0000000000000600wDF.text0000000000000127LINUX_2.6gettimeofday
0000000000000730gDF.text0000000000000010LINUX_2.6__vdso_time
0000000000000730wDF.text0000000000000010LINUX_2.6time
0000000000000740gDF.text000000000000015dLINUX_2.6__vdso_clock_gettime
0000000000000000gDO*ABS*0000000000000000LINUX_2.6LINUX_2.6
00000000000008f0gDF.text0000000000000025LINUX_2.6__vdso_getcpu
00000000000008f0wDF.text0000000000000025LINUX_2.6getcpu

審核編輯:湯梓紅
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11511

    瀏覽量

    213840
  • 操作系統(tǒng)
    +關(guān)注

    關(guān)注

    37

    文章

    7152

    瀏覽量

    125604
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1620

    瀏覽量

    64059
  • 命令
    +關(guān)注

    關(guān)注

    5

    文章

    737

    瀏覽量

    22882

原文標(biāo)題:細(xì)說|vDSO機(jī)制原理

文章出處:【微信號(hào):LinuxHub,微信公眾號(hào):Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    求3525電路詳細(xì)說

    求3525電路詳細(xì)說明,越詳細(xì)越好,謝謝!
    發(fā)表于 04-18 08:21

    spi總線協(xié)議詳細(xì)說

    本帖最后由 eehome 于 2013-1-5 09:52 編輯 spi總線協(xié)議詳細(xì)說
    發(fā)表于 08-18 21:28

    圖表細(xì)說電子元器件

    本帖最后由 eehome 于 2013-1-5 09:57 編輯 84404844058440684407圖表細(xì)說電子元器件
    發(fā)表于 09-06 16:30

    hex文件格式詳細(xì)說

    hex文件格式詳細(xì)說
    發(fā)表于 11-13 12:36

    hex文件格式詳細(xì)說

    hex文件格式詳細(xì)說
    發(fā)表于 11-13 12:37

    stc下載燒錄詳細(xì)說

    stc下載燒錄詳細(xì)說
    發(fā)表于 01-05 16:28

    細(xì)說Android 4.0NDK編程源碼

    本帖最后由 richthoffen 于 2019-7-19 16:39 編輯 細(xì)說Android 4.0NDK編程源碼
    發(fā)表于 07-19 08:39

    Linux內(nèi)核詳細(xì)說

    Linux_內(nèi)核詳細(xì)說
    發(fā)表于 03-28 09:46 ?35次下載

    linux內(nèi)存管理機(jī)制淺析

    本內(nèi)容介紹了arm linux內(nèi)存管理機(jī)制,詳細(xì)說明了linux內(nèi)核內(nèi)存管理,linux虛擬內(nèi)存管理,arm linux內(nèi)存管理等方面的知識(shí)
    發(fā)表于 12-19 14:09 ?73次下載
    linux內(nèi)存管理<b class='flag-5'>機(jī)制</b>淺析

    圖表細(xì)說電路回路法識(shí)圖_圖表細(xì)說系列叢書—胡斌編著

    電子發(fā)燒友網(wǎng)站提供《圖表細(xì)說電路回路法識(shí)圖_圖表細(xì)說系列叢書—胡斌編著.txt》資料免費(fèi)下載
    發(fā)表于 03-30 16:31 ?0次下載

    SPI接口詳細(xì)說

    SPI接口詳細(xì)說
    發(fā)表于 12-23 02:11 ?8次下載

    使用AT89S51單片機(jī)制作紅外遙控器的資料和源代碼詳細(xì)說

    本文檔的主要內(nèi)容詳細(xì)介紹的是使用AT89S51單片機(jī)制作紅外遙控器的資料和源代碼詳細(xì)說明。
    的頭像 發(fā)表于 05-30 09:26 ?6680次閱讀

    使用單片機(jī)制作密碼鎖的電路圖和程序與流程圖的詳細(xì)說

    本文檔的主要內(nèi)容詳細(xì)介紹的是使用單片機(jī)制作密碼鎖的電路圖和程序與流程圖的詳細(xì)說明。
    發(fā)表于 09-09 16:08 ?47次下載
    使用單片<b class='flag-5'>機(jī)制</b>作密碼鎖的電路圖和程序與流程圖的詳<b class='flag-5'>細(xì)說</b>明

    Memory芯片的測(cè)試資料詳細(xì)說

    本文檔的主要內(nèi)容詳細(xì)介紹的是Memory芯片的測(cè)試資料詳細(xì)說明包括了:Memory芯片的重要性,Memory類型和結(jié)構(gòu)特點(diǎn), Memory失效機(jī)制, Memory測(cè)試標(biāo)識(shí)縮寫, Memory故障模型
    發(fā)表于 11-30 08:00 ?0次下載
    Memory芯片的測(cè)試資料詳<b class='flag-5'>細(xì)說</b>明

    細(xì)說Linux Out Of Memory機(jī)制

    有時(shí)候我們會(huì)發(fā)現(xiàn)系統(tǒng)中某個(gè)進(jìn)程會(huì)突然掛掉,通過查看系統(tǒng)日志發(fā)現(xiàn)是由于 OOM機(jī)制 導(dǎo)致進(jìn)程被殺掉。
    的頭像 發(fā)表于 02-12 09:57 ?1197次閱讀