LINUX.ORG.RU

загрузка файла


0

0

ld для elf32_i386 устанавливает стартовый адрес в 0x08048000 (точнее в 0x08048000 + SIZEOF_HEADERS). Для разных форматов и архитектур этот адрес разный, для некоторых архитектур есть и понятный адрес -> 0x0. В тестовой программе принудительно указал линкеру использовать стартовый адрес 0x0. Никакой катастрофы не случилось, программа работала нормально. Если смотреть дальше, то выходит, что с этим адресом первые 32 entries в pgd процесса не используются, отсюда и это число 0x08048000. Так вот вопрос в том, почему они не используются.

ps: тема пробегала когда-то, но ответа в ней нет

★★★

Насколько я помню, то ядро линукса размещает виртуальное адресное пространство ниже 0x08000000.

User-mode код соотвесвенно может запускаться только ниже этой отметки, т.к. ядру надо разместить программу где-то в памяти.

Где-то в lkml это было. Году так в 2002 (если не изменяет память) это там точно обсуждалось :)

catap ★★★★★
()
Ответ на: комментарий от cobold

Да, спасибо.

Хотя смотря как смотреть. Если адреса возрастают от 0 до ..., то да, выше. У меня в голове они почему-то убывают от 0 до ... :)

catap ★★★★★
()

Утверждается (google), что адрес 0x08048000 взят из "System V Intel 386 ABI specification".

Однако, если смотреть ABI: http://www.sco.com/developers/devspecs/abi386-4.pdf то там предложена несколько другая схема --- от 0x08048000 до 0x7fffffff сегменты Text и Data, выше Dynamic, а вот стек от 0x08048000 до 0x00000000 --- типа 128 Мбайт для стека хватит...

mky ★★★★★
()
Ответ на: комментарий от mky

странно, не нашел в спецификации такого, что стек идет от 0x08048000 до нуля. Стек начинается с 0xbfffffff и идет вниз, навстречу куче. Этот адрес, насколько я понимаю, устанавливает ядро. А вот адрес 0x08048000 устанавливает ld в файле, а потом загрузчик загружает код по этому адресу. Я повторюсь, если принудительно заставить ld установить стартовый адрес в ноль, программа работает. Скриптовый файл для ld остается почти тем же. Так зачем пропускать лишние entries в pgd? Почему нельзя начинать с нуля, как это делается в других (но не всех) архитектурах. ?

Chumka ★★★
() автор топика
Ответ на: комментарий от Chumka

>странно, не нашел в спецификации такого, что стек идет от 0x08048000 до нуля.

В какой спецификации? "System V Intel 386 ABI specification" ! Там четко говорится про 0x08048000 --- page 48 (3-22 Low-Level System Information).

То есть System V Application Binary Interface для x86 платформы установил это самый адрес, а Linux его повторил, видимо для совместимости.

mky ★★★★★
()
Ответ на: комментарий от mky

да, спасибо, нашел. Непонятно, однако, linux решает вопрос совместимости с этой спецификацией. Стек располагает не по спецификации, dynamic сегмент тоже, только стартовый адрес по спецификации.

Chumka ★★★
() автор топика
Ответ на: комментарий от Chumka

Ну про стек там, ниже, на этой же странице написано, что в принципе стек может быть где угодно.

А в целом это более интересный и древний вопрос, почему System V предложила распологать стек "перед" кодом?

mky ★★★★★
()

в этом обсуждении все как-то запутано. почему вы решили, что "первые 32 entries
в pgd процесса не используются" ? они вполне могут быть использованы. например,
через mmap(MAP_FIXED). больше того, mmap() (и, соответственно malloc()) может
распределить там память и без MAP_FIXED, см arch_get_unmapped_area_topdown()->
arch_get_unmapped_area(). единственно, mmap() никогда не вернет 0 без MAP_FIXED.

ядру все равно, куда грузить процесс, лишь бы ниже PAGE_OFFSET, на адреса выше
этого отображенв физическая память, см kernel_physical_mapping_init().

откуда взялась эта константа (0x08048000 ~= 128 Mb) в ABI - не знаю.

idle ★★★★★
()
Ответ на: комментарий от idle

вопрос и был в том откуда взялась эта константа. теперь более-менее ясно. а то, что первые 32 entries не используются - это так и есть. Если, их можно потом использовать, как вы говорите через MAP_FIXED - то хорошо, но при изначальной загрузке процесса по адресу 0x08048000 они пустуют.

Chumka ★★★
() автор топика
Ответ на: комментарий от Chumka

все-таки, мне по прежнему кажется, что вы чего-то недопонимаете ...

> Если, их можно потом использовать, как вы говорите через MAP_FIXED

зря я написал про MAP_FIXED :) их и без MAP_FIXED можно использовать,
как я уже говорил.

> но при изначальной загрузке процесса по адресу 0x08048000 они пустуют.

да. но почему вас интересуют именно эти первые 32 entries? они ничем не
отличаются от других. сделайте "cat /proc/$$/maps", там полно дырок.

если вы загружаете процесс в 0, ситуация (в этом смысле) не меняется,
просто эти 32 entries "уйдут" в другое место.

idle ★★★★★
()
Ответ на: комментарий от idle

Да интересует (вернее интересовало) меня С КАКОЙ ЦЕЛЬЮ сделана эта дырка. Я понимаю, что если грузить процесс в 0, то ничего не изменится. Если вы читали, то я об этом писал выше.

Chumka ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.