亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 2392 | 回復: 9
打印 上一主題 下一主題

[內(nèi)存管理] 內(nèi)核采用 in-place 解壓縮不會覆蓋解壓縮部分代碼嗎? [復制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2013-02-24 13:54 |只看該作者 |倒序瀏覽
內(nèi)核采用 in-place 解壓縮不會覆蓋解壓縮部分代碼嗎?就是說看上去 arch/x86/boot/compressed/head_32.S 部分的代碼會被解壓的內(nèi)核覆蓋。但是似乎代碼中并沒有進行特殊處理...

論壇徽章:
0
2 [報告]
發(fā)表于 2013-02-24 16:01 |只看該作者
回復 1# JackyBsh


不知怎么描述好,再進一步解釋一下吧。

內(nèi)核壓縮部分被包圍在未壓縮部分的中間,由未壓縮部分負責解壓壓縮部分,而解壓方式采用的是 in-place 解壓,也就是說,內(nèi)核解壓后的部分將覆蓋原來的壓縮部分。顯然,也會覆蓋包圍在內(nèi)核壓縮影像外圍的非壓縮部分。但是事實上,解壓縮后,非解壓縮的代碼還有一些工作要做,最后才跳轉(zhuǎn)到解開的壓縮部分。因此,這就有一個矛盾,既然被覆蓋了,如何還能繼續(xù)執(zhí)行呢?相關(guān)代碼如下:

arch/x86/boot/compressed/head_32.S:

/*
* Do the decompression, and jump to the new kernel..
*/
    leal    z_extract_offset_negative(%ebx), %ebp
                /* push arguments for decompress_kernel: */
    pushl   %ebp        /* output address */
    pushl   $z_input_len    /* input_len */
    ...

    call    decompress_kernel
    addl    $20, %esp

#if CONFIG_RELOCATABLE
/*
* Find the address of the relocations.
*/
    leal    z_output_len(%ebp), %edi

/*
* Calculate the delta between where vmlinux was compiled to run
* and where it was actually loaded.
*/
    movl    %ebp, %ebx
    subl    $LOAD_PHYSICAL_ADDR, %ebx
    jz  2f  /* Nothing to be done if loaded at compiled addr. */
   ...
/*
* Jump to the decompressed kernel.
*/
    xorl    %ebx, %ebx
    jmp *%ebp

也就是說,表面上看,在調(diào)用decompress_kernel,本身head_32.S似乎已經(jīng)被覆蓋,那么后面的代碼,包括跳轉(zhuǎn)到解壓的內(nèi)核的代碼“jmp *%ebp”,怎么還能夠依然執(zhí)行呢?

不知問題描述清楚沒有,希望有高手能夠解答。




   

論壇徽章:
6
金牛座
日期:2013-10-08 10:19:10技術(shù)圖書徽章
日期:2013-10-14 16:24:09CU十二周年紀念徽章
日期:2013-10-24 15:41:34獅子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亞洲杯之阿聯(lián)酋
日期:2015-05-09 14:36:15
3 [報告]
發(fā)表于 2013-02-25 19:08 |只看該作者
回復 2# JackyBsh
在調(diào)用decompress_kernel,本身head_32.S似乎已經(jīng)被覆蓋

這個代碼是從哪里得出來的?
我怎么記得是,如果解壓出來的new kernel可能會覆蓋當前內(nèi)核,那么會先解壓出來放到一個地方,然后再mov過來,不會直接覆蓋的啊。
   

論壇徽章:
0
4 [報告]
發(fā)表于 2013-02-26 14:32 |只看該作者
回復 3# 瀚海書香

似乎從2.6開始就是了,最新的內(nèi)核都是采用這種壓縮方法。網(wǎng)上的文章幾乎全部是早期的,誤人子弟啊。
   

論壇徽章:
0
5 [報告]
發(fā)表于 2013-03-14 20:53 |只看該作者
2.6.11沒有變

論壇徽章:
0
6 [報告]
發(fā)表于 2013-03-15 09:34 |只看該作者
本帖最后由 aweii 于 2013-03-15 09:41 編輯

2.6.11的還是原來的思路,2.6.24已經(jīng)是LZ說的那樣了。我也不解啊。而且滑動窗口即輸出窗口,flush_window()函數(shù)中不再有從滑動窗口拷貝到輸出的代碼了。但是解壓輸出似乎是原地踏步,32K滿后就回到output,那不是先前解壓出來的數(shù)據(jù)又被覆蓋了。

------------boot\compressed\Misc_32.c
static void flush_window(void)
{
        /* With my window equal to my output buffer
         * I only need to compute the crc here.
         */
        ulg c = crc;         /* temporary variable */
        unsigned n;
        uch *in, ch;

        in = window;
        for (n = 0; n < outcnt; n++) {
                ch = *in++;   //這里不再有老版本的拷貝解壓數(shù)據(jù)到輸出區(qū)的代碼,而只計算crc
                c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> ;
        }
        crc = c;
        bytes_out += (ulg)outcnt;
        outcnt = 0;
}

簡單起見,我只分析了inflate_stored()的部分代碼,即未壓縮的塊。
while (n--)
  {
    NEEDBITS(
    slide[w++] = (uch)b;
    if (w == WSIZE)
    {
      flush_output(w);
      w = 0;
    }
    DUMPBITS(
  }
滑動窗口slide宏定義中是指向window的,而window指針指向decompress_kernel()的參數(shù)output,output是指向解壓后的內(nèi)核代碼的存放的物理內(nèi)存位置,即1MB處。這里,滑動窗口數(shù)據(jù)滿32KB后,指針w歸零,老版本的在歸零前會把32KB數(shù)據(jù)拷貝到輸出,那么歸零后原先的部分數(shù)據(jù)被覆蓋是沒問題,但是2.6.24版中滑動窗口即輸出,沒有了拷貝過程,指針歸零后繼續(xù)解壓不是覆蓋了原來的數(shù)據(jù)?

論壇徽章:
0
7 [報告]
發(fā)表于 2013-03-15 10:26 |只看該作者
我看了下,這塊代碼是從2.6.20開始變化的

論壇徽章:
0
8 [報告]
發(fā)表于 2013-03-15 14:42 |只看該作者
是奇怪啊,arch其它目錄下的misc.c中就不一樣,i386下的flush_window()著實不可思議

論壇徽章:
0
9 [報告]
發(fā)表于 2013-05-08 11:06 |只看該作者
這個問題解決了。奧妙就在編譯鏈接上。我看了下arch/x86/boot/compressed/下的vmlinux_32.lds和vmlinux_32.scr:
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(startup_32)
SECTIONS
{
        /* Be careful parts of head.S assume startup_32 is at
         * address 0.
         */
        . =  0         ;
        .text.head : {
                _head = . ;
                *(.text.head)
                _ehead = . ;
        }
        .data.compressed : {
                *(.data.compressed)
        }
        .text :        {
                _text = .;         /* Text */
                *(.text)
                *(.text.*)
                _etext = . ;
        }
        .rodata : {
                _rodata = . ;
                *(.rodata)         /* read-only data */
                *(.rodata.*)
                _erodata = . ;
        }
        .data :        {
                _data = . ;
                *(.data)
                *(.data.*)
                _edata = . ;
        }
        .bss : {
                _bss = . ;
                *(.bss)
                *(.bss.*)
                *(COMMON)
                _end = . ;
        }
}

關(guān)鍵在于.text段在.data.compressed 段的后面,所以不會被覆蓋,而head_32.S的開始部分代碼在.text_head段,當開始解壓時這部分代碼已經(jīng)運行完了就沒用了,所以被覆蓋是不要緊的,而后邊的代碼在.text段,位于壓縮代碼之后,由于和解壓代碼之間的output_len-inout_len的空隙的存在,是不會被覆蓋的

論壇徽章:
0
10 [報告]
發(fā)表于 2013-06-06 21:34 |只看該作者
回復 9# aweii


    謝謝,解決了我一個很大的疑問。
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP