LINUX.ORG.RU

KERNEL_DS && addr_limit


0

0

Я заводил тему про set_fs http://www.linux.org.ru/forum/development/4535285 с ней все понятно, но встает другой вопрос: как работает этот самый addr_limit который задается через set_fs ? Как все уже поняли KERNEL SPACE (KERNEL_DS) это от 3 до 4Gb, USER SPACE (USER_DS) это от 0 до 3 Gb. Но это голые слова, на практике же мы имеем

KERNEL_DS = 4294967295 = 0xFFFFFFFF = 4Gb

USER_DS = 3221225472 = 0xC0000000 (задается в конфиге) = 3Gb

с юсер спейсом предположим все понятно, адреса идут от 0 и до < USER_DS (addr_limit) а как это работает в случае с KERNEL_DS Oo ? Откуда процессу известно что оно должно начинать нумеровать адреса не с 0 а с 3Gb ?

А еще я не могу понять следующего: в GDT в десктрипторах __KERNEL_CS, __KERNEL_DS, USER_CS, USER_DS есть поля отвечающие за начало (base) и конец (linux) адресного пространства, и в них оно во всех от 0x00000000 до 0xffffffff. Тобишь от 0Gb до 4Gb. А адресное адресное пространство процесса подчиняется выше описанному правилу (от 0 до 3, от 3 до 4). Но здесь я пиняю на то что процессы использую виртуальное адресное пространство а в GDT указывается логические адреса. Я ошибаюсь ?

Буду рад любым ответам, советам, посылваниям :) Боветте и чезатти я читал, читаю. Это как раз от тудова такие вопросы и возникают.


Откуда процессу известно что оно должно начинать нумеровать адреса не с 0 а с 3Gb ?

Нумеруется всегда с нуля. Различие между юзерспейсом и кернельспейсом эфемерное. mmap, brk, sbrk не могут юзерспейсному процессу память сделать выше USER_DS, чтобы процессу, когда он в сисколле, была доступна одновременно память ядра и своя, юзерская, память. Из сисколла свободно читается любая память, даже без copy_from_user и copy_to_user (они чисто для обработки GPF нужны).

А еще я не могу понять следующего: в GDT в десктрипторах __KERNEL_CS, __KERNEL_DS, USER_CS, USER_DS есть поля отвечающие за начало (base) и конец (linux) адресного пространства, и в них оно во всех от 0x00000000 до 0xffffffff. Тобишь от 0Gb до 4Gb.

Это flat-модель памяти.

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

сурово и непонятно :)

1. вы сказали про USER_DS, я в вопросе и так с казал что с ним все понятно. Непонятно с KERNEL_DS. Или же это намек на то что у кернел спейса адресное пространстно не от 3до4 Гб а от 0до4 Гб ?

2. шикарно, но как мне ее интепретировать на мой вопрос?)

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

1. На x86 начальные физические адреса от 0 до 896Мб отображаются в виртуальные
адреса, начиная с 0xC0000000. Это как раз тот самый PAGE_OFFSET.
Смотри функцию phys_to_virt. Такая договоренность.

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

Хотя, вроде как это можно перенастроить, конфигурируя EMBEDED ядро.
2/2, 1/3 - я что-то такое видел.

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

от оно как. Следовательно это можно представить следующим образом: образно говоря, у нас есть отрезок от 0 до 4, в его пределах есть разделитель который отделяет юзер спейс от кернел спейса, двигая этот разделитель туды-сюды мы меняем соотношение первого ко второму ? Так ?)

И эта функция как раз вызывается где то на этапе разметки/выделения памяти?

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

>двигая этот разделитель туды-сюды мы меняем соотношение первого ко второму ?

Ничего не двигаем, как раз решили поделить, так все время и пользуемся.

И эта функция как раз вызывается где то на этапе разметки/выделения памяти?


Функция вызывается практически постоянно. Тогда, когда нужно совершить
это преобразование. Она ничего не делает - только прибавляет PAGE_OFFSET
к переданному тобой адресу. Смотри обязательно исходники ядра.

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

Ты чем для просмотра исходников пользуешься? ctags/cscope знаешь или
мучаешься где-нибудь в midnight commander?

ttnl ★★★★★
()

есть патч от Ingo 4G/4G
тогда и ядру и процессу доступно виртуальное пространство в 4G

я плохо разбираюсь как работает gate call через прерывание и через переключение, но в статье ещё упоминается сброс tlb для каждого переключения из юзерспайса в кернелспейс, а так нет никаких препятствий, чтобы в таблице страниц процесса описать все 4 гига виртуальных адресов

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

> Ничего не двигаем, как раз решили поделить, так все время и пользуемся.

да я не имел в виду что прям взять и туда сюда ее мотать, я имел в виду что можно изменить параметр PAGE_OFFSET, пересобрать ядро, и тогда кернел спейс будет не от 0xC000000 а от того что будет задано в конфиге, и юзерспейс будет не до 0xC0000000 а до того куда мы его выставили. Я имел в виду то что если это сделать система не хряпнеться при старте в следствии того что где то просто жестко используются соотношения от 0до3 и от 3до4?

Ты чем для просмотра исходников пользуешься

mc, vim, http://tomoyo.sourceforge.jp/cgi-bin/lxr/ident?i=, както меня консольные утилиты для прохождения десятков враперов не привлекают :( щас пытаюсь нормально установить kscope, но то что я собрал с сурсфожа сильно урезано, и то что из репов после установки не не запускается.

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

А ты каким нибуть задротским vi теги просматриваешь ? mc давно научили бродить по тэгам ctags.

anonymous
()
Ответ на: комментарий от Cupper

Да, можно. arch/x86/Kconfig:

1047 choice
1048 depends on EXPERIMENTAL
1049 prompt «Memory split» if EMBEDDED
1050 default VMSPLIT_3G
1051 depends on X86_32
1052 ---help---
1053 Select the desired split between kernel and user memory.
1054
1055 If the address range available to the kernel is less than the
1056 physical memory installed, the remaining memory will be available
1057 as «high memory». Accessing high memory is a little more costly
1058 than low memory, as it needs to be mapped into the kernel first.
1059 Note that increasing the kernel address space limits the range
1060 available to user programs, making the address space there
1061 tighter. Selecting anything other than the default 3G/1G split
1062 will also likely make your kernel incompatible with binary-only
1063 kernel modules.
1064
1065 If you are not absolutely sure what you are doing, leave this
1066 option alone!
1067
1068 config VMSPLIT_3G
1069 bool «3G/1G user/kernel split»
1070 config VMSPLIT_3G_OPT
1071 depends on !X86_PAE
1072 bool «3G/1G user/kernel split (for full 1G low memory)»
1073 config VMSPLIT_2G
1074 bool «2G/2G user/kernel split»
1075 config VMSPLIT_2G_OPT
1076 depends on !X86_PAE
1077 bool «2G/2G user/kernel split (for full 2G low memory)»
1078 config VMSPLIT_1G
1079 bool «1G/3G user/kernel split»
1080 endchoice
1081
1082 config PAGE_OFFSET
1083 hex
1084 default 0xB0000000 if VMSPLIT_3G_OPT
1085 default 0x80000000 if VMSPLIT_2G
1086 default 0x78000000 if VMSPLIT_2G_OPT
1087 default 0x40000000 if VMSPLIT_1G
1088 default 0xC0000000
1089 depends on X86_32

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

>А ты каким нибуть задротским vi теги просматриваешь ?

Почему vi?! VIM же.

mc давно научили бродить по тэгам ctags.


Встать на функцию и перейти к её описанию поддерживается? Даже если
описаний несколько? И назад переходит?


Хотя даже если это все есть, то смысла в такой навигации особо нет.
В mc очень неудобно активно править исходники. В частности, нельзя
навесить всех тех горячих клавиш, что есть в VIM.

Но если конкретно тебе нравится - пользуйся. Я не имею ничего против,
поверь.

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

И ещё - mc часто путается при подсветке синтаксиса. А так - хорошая
программа, предназначенная для других нужд. Файловый менеджер она.

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

Как раз разгребать тонны исходников mc лучший из лучших. Сам я мало пишу с нуля. Мне как-то пришлось в реале пересечся с линуксоидом по одному общему интересу, он на своем буке долго что-то тыкал в консольке, мне было жутко не удобно перед ним что я плохо знаком с работой в шелл, но преодолев страх открыл мс и сделал все раз в 10 бытсрей его.

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

Исходники, в отличие от файлопомойки, семантически связаны. Если нужно долго и нудно шариться по исходникам большого проекта, то ctags роляет.

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

1. вы сказали про USER_DS, я в вопросе и так с казал что с ним все понятно. Непонятно с KERNEL_DS. Или же это намек на то что у кернел спейса адресное пространстно не от 3до4 Гб а от 0до4 Гб ?

Аппаратно - да (flat-модель). Программно ядро не мапит старницы для своих нужд ниже TASK_SIZE.

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

а TASK_SIZE в х86_32 определено как PAFE_OFFSET. И того имеем: KERNEL_DS = 0xffffffff USER_DS = PAGE_OFFSET = TASK_SIZE = 0xc0000000 функция phys_to_virt(x) которая возвращает x+PAGE_OFFSET. Теперь хотелось бы собрать все это вместе: Страницы для юзерспейса адресуются от 0х00000000 и в проверяются что они < USER_DS(может кто еще подскажет функцию где это происходит ?) Страницы для кернелспейса адресуются от PAGE_OFFSET (исходя из функции phys_to_virt) и проверяются что они меньше 0xffffffff.

Очень важный вопрос о том где и какие макросы используются, а не посредственно зачем сразу три макроса со значением 0xc0000000? Еще более важный вопрос о том для каких целей каждый из них используется.

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

Читаю, вроде все по-русски написано но мысли не могу уловить :) phys_to_virt - очевидно используется для обращения к некотрой области физической памяти. Процессор в защищенном режиме работает с _виртуальными_ адресами, поэтому известный физический адрес нужно вначале преобразовать в виртуальный и уже потом можно по нему обратиться или передать как аргумент какой-то ф-ции.

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

Естественно что эта ф-ция или макрос работает только в режиме ядра. Для пользовательских задач отводится нижняя память, для ядра верхняя часть виртуальной памяти. При созании нового процесса системные страницы коипруются во вновь созданную pgd нового потока, при выделении виртуальной памяти процессу мапится физическая память в нижнюю часть виртуальной памяти, при этом и проверяеся чтобы она не перекрылась с системными адресами.

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

ну да я как раз про это, но я просто хотел конкретизировать, перейти от просто логики к тому как и где это происходит в ядре

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

Мне кажется тебе нужно начинать не с linux а вообще с изучения основ - устройство процессора (mmu), управление памятью в современных ос. Начинать с linux - не лучший вариант, кода наворочено много, разобраться трудно а сами принципы далеко не уникальны, в итоге разгребая кучу частных вопросов общая картина непонятна. На русском есть масса переводов, начинать имхо лучше с них - намного эффективней чем тужиться с пониманием технических деталей на непонятном языке, со временем (надо сказать это достаточно быстро и незаметно происходит) сам начнешь лазить в первоисточники.

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

проблема в том что я не начинаю, я уже во всю в процессе :)

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