這樣得到的兩個地址都是虛擬地址(不是物理地址)。雖然虛擬地址是48位的但是儲存這個地址的指標和載入這個地址的暫存器都是64位的,簡單來說就是邏輯上只使用48位但是實際儲存的時候是將一個虛擬地址當成64位來看,這樣多餘的16位(bit 63-48)實際上是不表示地址的。x86_64規定了一個合法的虛擬地址中這些多出來的位必須和第47位一致,所以就將地址空間分出了兩個部分:0-0x00007FFFFFFFFFFF(bit 63-48都為0)以及從0xFFFF800000000000-0xFFFFFFFFFFFFFFFF(bit 63-48都為1)。Linux將處在地址空間低端分的第一部分分給使用者,處在高階的第二部分作為核心自己的空間。所以你在使用者態取一個變數的地址和在核心態取一個變數的地址就會有這樣的差別,他們分別落在了地址空間中的兩個區域當中。
如果想要獲得對應的物理地址,對於一個核心空間的虛擬地址(就是你提到的第二個)可以直接在核心態中用宏,如果是一個使用者空間的虛擬地址 (就是你提到的第一個)就只能透過對使用者程序的page table做一次page table walk得到了。
這樣得到的兩個地址都是虛擬地址(不是物理地址)。雖然虛擬地址是48位的但是儲存這個地址的指標和載入這個地址的暫存器都是64位的,簡單來說就是邏輯上只使用48位但是實際儲存的時候是將一個虛擬地址當成64位來看,這樣多餘的16位(bit 63-48)實際上是不表示地址的。x86_64規定了一個合法的虛擬地址中這些多出來的位必須和第47位一致,所以就將地址空間分出了兩個部分:0-0x00007FFFFFFFFFFF(bit 63-48都為0)以及從0xFFFF800000000000-0xFFFFFFFFFFFFFFFF(bit 63-48都為1)。Linux將處在地址空間低端分的第一部分分給使用者,處在高階的第二部分作為核心自己的空間。所以你在使用者態取一個變數的地址和在核心態取一個變數的地址就會有這樣的差別,他們分別落在了地址空間中的兩個區域當中。
如果想要獲得對應的物理地址,對於一個核心空間的虛擬地址(就是你提到的第二個)可以直接在核心態中用宏,如果是一個使用者空間的虛擬地址 (就是你提到的第一個)就只能透過對使用者程序的page table做一次page table walk得到了。