Поскольку код x86 обычно не зависит от позиции, если он скомпилирован для выполнения по адресу X (__PAGE_OFFSET + 1MB), но загружен по адресу Y (1MB), все адреса внутри него должны быть уменьшены на YX (__PAGE_OFFSET +1MB - 1MB = __PAGE_OFFSET), чтобы он работал.
Например, если есть инструкция для чтения байта памяти из начала ядра, __PAGE_OFFSET + 1MB, адрес уменьшается на __PAGE_OFFSET и фактическийместо чтения становится 1 МБ, именно там, где ядро запускается в памяти.
Когда перевод страницы наконец-то включен, __PAGE_OFFSET может и, я полагаю, эффективно вычитается механизмом перевода страниц путем сопоставления диапазона виртуальных адресов сдиапазон физических адресов, которые меньше на __PAGE_OFFSET (то есть физический = виртуальный -__ PAGE_OFFSET для таблиц страниц).
Если не требуется каких-либо дополнительных перемещений ядра, 8 МБ, вероятно, просто размер диапазона отображения,достаточно отобразить весь кернель.