LINUX.ORG.RU

Сообщения Cupper

 

Кольца привилегий , почему так и ни как иначе

Форум — General

Хотел бы поговорить с вами на тему колец привилегий и почему в линуксе используется только 0 и 3. Но ненужно делать из этого холивар. Приветствуется приведение цитат, ссылки и технические объяснения. Начну вот с такой цитаты

[1] http://www.xserver.ru/computer/os/winnt/16/ Windows NT против Linux, Константин Пьянзин

Тем не менее у NT и большинства разновидностей UNIX есть общая проблема. Все подобные системы задействуют только два кольца (уровня привилегий) процессора. В частности, для процессоров Intel системы используют нулевое (уровень ядра) и третье (пользовательский уровень) кольцо. Причем в нулевом кольце 'крутятся' ядро системы и драйверы устройств. В то же время процессоры Intel уже давно имеют четыре кольца. Если бы драйверы выполнялись в первом кольце, то это значительно увеличило бы надежность, поскольку некорректно работающий драйвер в этом случае не мог бы вызвать краха системы. Правда, реализация подобной концепции приводит к снижению производительности.

Также слышал о споре Торвальдса с создателем миник, в которой они бурно обсуждали эту тему, но увы оно только на англ.

И вообще каковы изначальные причины использования всего 2 колец, на тот момент просто не было реализованы 4 кольца или ему было лень или что то еще, может он так сильно переживал за производительности ?

Cupper
()

Qemu, наставить ОСь

Форум — General

Установил Qemu и Qkemu, создал жиск

qemu-img create -f raw grant.raw 4G
вставил диск с убунтоу 9, запускаю
qemu Qemu/grant.raw -cdrom /dev/cdrom -m 512 -boot d
появляется окно, начинается загрузка, появляется стандартное боот диска, выбераю язык и установку, и после того как нажимаю enter на кортанка замирает и ничего не происходит, ждал минут 40, загрузка одного ядра на 100% и ничего

PS. сразу после запуска в консоли пишет

open /dev/kvm: No such file or directory Could not initialize KVM, will disable KVM support

но эт не должно играть роли.

PPS. без kqemu пробывал, liveCD также не грузится.

Cupper
()

system_call

Форум — Development

Всем снова сдрасте. У меня новая проблема :) Мне нужно модифицировать (клонировать) обработчик 80 прерывания, она же функция system_call. Но он везде где я находил описан очень и очень хренова. Обычно все описание заключается в том что сказано: в eax передается номер вызываемой функции, он проверяется, далее запускается, если чтото не так то производются сложные действия для коректного возврата. Без каких либо подробностей. Мне нужно сделать практически аналогичный обработчик за некими маленькими отклонениями. А чтобы понять где эти маленькие поправления должны быть нужно понять как там все это работает, до последнего винтика. Прошу вашей помощи в разборе. Начнем по порядку.

Во первых сделаем для простоты такое упущение: ничего лишнего кроме как посмотреть номер вызываемой функции, вызвать ее и вернуть результат, ни надо, пока нужен самый минимум чтобы работал в идеальных условиях. И второе: нужно четко осознать те моменты где прямым образом фигурируют какие либо опоминания об пользовательском пространстве (дескрипторы GDT, DPL = 3, процесс вызвавший прерывание).

	.pushsection .kprobes.text, "ax" # это относиться к обработчику или нет ?
	# system call handler stub
ENTRY(system_call)
	RING0_INT_FRAME			# подготавливается стек ядра? Но как оно работает
	pushl %eax			# save orig_eax
	CFI_ADJUST_CFA_OFFSET 4 # не понял что это ?
	SAVE_ALL # сохраняем в стек все необходимые регистры
	GET_THREAD_INFO(%ebp) # получаем инфу о треде вызвавшем прерывание ? Но кукую и для чего она ?
					# system call tracing in operation / emulation
	testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp) # проверка чего ?) Того что из данного треда можно делать системные вызовы ?
	jnz syscall_trace_entry # сюда попадем если проверка не прошла, но в этой метке все равно может произойти вызов (см. ниже)
	cmpl $(nr_syscalls), %eax
	jae syscall_badsys # сюда прыгаем если номер системного переданный в eax неправильны, и далее возвращается ENOSYS
syscall_call:
	call *sys_call_table(,%eax,4) # самое суть
	movl %eax,PT_EAX(%esp)		# кладем результат работы обратно в eax
syscall_exit:
	LOCKDEP_SYS_EXIT # нах это ?
	DISABLE_INTERRUPTS(CLBR_ANY)	# make sure we don't miss an interrupt
					# setting need_resched or sigpending
					# between sampling and the iret
                                        # На сколько я понял это некий аналог "For DISABLE_INTERRUPTS/ENABLE_INTERRUPTS (aka "cli"/"sti")"
	TRACE_IRQS_OFF # не понял что это
	movl TI_flags(%ebp), %ecx # кладем в ecx то чем можно идентифицировать тред который запустил прерывания, или его отдельное значение
	testl $_TIF_ALLWORK_MASK, %ecx	# current->work
                                        # смотрим работаетли еще тред вызвавший прерывание ?
	jne syscall_exit_work # сюда пошли если процесс уже не работает ?

restore_all: # а сюда для выхода в прерывания при работающем процессе ?
	TRACE_IRQS_IRET # посмотрели что прерывание уже неработает ? Оо
restore_all_notrace: # подготовка в козврату в юзерспейс
	movl PT_EFLAGS(%esp), %eax	# mix EFLAGS, SS and CS
	# Warning: PT_OLDSS(%esp) contains the wrong/random values if we
	# are returning to the kernel.
	# See comments in process.c:copy_thread() for details.
	movb PT_OLDSS(%esp), %ah
	movb PT_CS(%esp), %al
	andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax # макросы однозначно образую число 20403h, оно кладеться в eax
	cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax # тут макросы образую также однозначно число 403h и эта проверка пройдет всегда, зачем она тогда О_о
	CFI_REMEMBER_STATE # ???
	je ldt_ss			# returning to user-space with LDT SS
                                        # какая то махинация со стеком
restore_nocheck:
	RESTORE_REGS 4			# skip orig_eax/error_code
                                        # восстанавливаем значения регистров (см. ниже)
	CFI_ADJUST_CFA_OFFSET -4 # этот макрос на сколько я понял что то вроде метки на стеке откудова брать куда класть значения регистров
irq_return:
	INTERRUPT_RETURN # вот тут то мы вызовем заветную инструкцию iret с помощью которой перейдем в usep space и произведем понижение привелегий (вот только я незаметил момента когда мы клали в стек необходимые ей параметры ?)
/* а все что дальше идет зачем ? */

syscall_trace_entry: # проверка не прошла прыгнули сюда и тут еще один шанс
	movl $-ENOSYS,PT_EAX(%esp)
	movl %esp, %eax
	call syscall_trace_enter # что делает функция ?
	/* What it returned is what we'll actually use.  */
	cmpl $(nr_syscalls), %eax
	jnae syscall_call # и бац все равно можем сделать то что хотели, проделав какуюто преобработку, какую ?
	jmp syscall_exit
END(syscall_trace_entry)

При таком вызове макроса

restore_nocheck:
	RESTORE_REGS 4
как он будет выполнятся ? Сначала выполнится чертвертая метка, потом 1-3 и он закончит свою работу выполнив POP_GS \pop ?
.macro RESTORE_REGS pop=0
	RESTORE_INT_REGS
1:	popl %ds
	CFI_ADJUST_CFA_OFFSET -4
	/*CFI_RESTORE ds;*/
2:	popl %es
	CFI_ADJUST_CFA_OFFSET -4
	/*CFI_RESTORE es;*/
3:	popl %fs
	CFI_ADJUST_CFA_OFFSET -4
	/*CFI_RESTORE fs;*/
	POP_GS \pop
.pushsection .fixup, "ax"
4:	movl $0, (%esp)
	jmp 1b
5:	movl $0, (%esp)
	jmp 2b
6:	movl $0, (%esp)
	jmp 3b
.section __ex_table, "a"
	.align 4
	.long 1b, 4b
	.long 2b, 5b
	.long 3b, 6b
.popsection
	POP_GS_EX
.endm

.macro POP_GS pop=0 # что оно делает ?)
	addl $(4 + \pop), %esp
	CFI_ADJUST_CFA_OFFSET -(4 + \pop)
.endm

фух, несколько часов пост делал. Простите за мноо букф и еще больше вопросов, просто нужно все это понять %) Отвечайте по возможности лучше кусочками, так проще мазайку будет сложить.

PS. И кстати если получится сложить все это в единую картину с хорошим описание то это будет очень хороший мануал, коих нету на белом свете.

Cupper
()

printk из usep space

Форум — Development

Нужно сделать возможным вызывать printk из user space (не 0-кольца). Делать собираюсь через системный вызов по вектору 80 (int 0x80). Уже подготовил почву, все изучил про системные вызовы, осталось только решить самую важную проблему.

asmlinkage int printk(const char *fmt, ...)
{
	va_list args;
	int r;

	va_start(args, fmt);
	r = vprintk(fmt, args);
	va_end(args);

	return r;
}

Проблема в том что printk принимает неопределенное число параметров, и как это передать через системные вызовы для меня остается загадкой. Вариант с передачей через стек еще рассматривается, но боюсь это может быть не безопасно и проблематично. Сегодня возникла такая идея:

Если сделать в качестве системного вызова не весь printk а только vprintk который на сколько я понял уже получает всего два параметра. Я надеюсь что так оно и работает. Но я не смог понять всей логики работы макросов va_start и va_end (Объявлены в файле /include/acpi/platform/acenv.h, правильно ?). Если честно я ваше не смог понять что и как они делают. Поэтому не знаю на сколько правдива идея.

typedef char *va_list;
...
#define va_start(ap, A)         (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))

смотрел все остальные макросы и к сожаление не понял их :( Я даже не понял что в итоге будет находится в переменных которые передаются им: args и fmt, это будут конечные переменные ? как например указатель на ограниченную строку ? или что то неопределенное ?

Если после вызова va_start в args и fmt будут выглядеть как обычные переменные то можно ли разделить вызов va_start на userspace, далее системный вызов (который я сделаю) на vprintk, получаем от него результат и далее продолжая на userspace сделать va_end ?

И кстати, я также не понял как как оно так работает

printk(KERN_ERR "bla bla bla\n");

KERN_ERR «bla bla bla\n» - это че такое ? не строка и строка вместе О_о

ЗЫ. на сколько я понял объявления printk происходит в файле /include/linux/kernel.h. Но какое из трех используется?

#ifdef CONFIG_PRINTK
asmlinkage int vprintk(const char *fmt, va_list args)
	__attribute__ ((format (printf, 1, 0)));
asmlinkage int printk(const char * fmt, ...)
	__attribute__ ((format (printf, 1, 2))) __cold;
...
#else
static inline int vprintk(const char *s, va_list args)
	__attribute__ ((format (printf, 1, 0)));
static inline int vprintk(const char *s, va_list args) { return 0; }
static inline int printk(const char *s, ...)
	__attribute__ ((format (printf, 1, 2)));
...
static inline int __cold printk(const char *s, ...) { return 0; }

Или же это не его объявления и другие приблуды ядра ?

ЗЗЫ. нужен именно printk.

Cupper
()

Тег CODE

Форум — General

[code] Тег неработает ? [/code]

раньше работал, почему перестали работать ? как теперь правильно оформлять куски кода в постах ?

Cupper
()

KERNEL_DS && addr_limit

Форум — Development

Я заводил тему про 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 указывается логические адреса. Я ошибаюсь ?

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

Cupper
()

kscope

Форум — General

Узнал о этой классной штуке, решил поставить, кучу врени потратил пока все зависимости удовлетворил, наконецтаки make install без ошибок, запускаю kscopeapp и получаю

kscopeapp: error while loading shared libraries: libkscope_core.so.1: cannot open shared object file: No such file or directory
ls /usr/local/lib/ | grep libkscope
libkscope_core.so
libkscope_core.so.1
libkscope_core.so.1.0
libkscope_core.so.1.0.0
libkscope_cscope.so
libkscope_cscope.so.1
libkscope_cscope.so.1.0
libkscope_cscope.so.1.0.0
libkscope_editor.so
libkscope_editor.so.1
libkscope_editor.so.1.0
libkscope_editor.so.1.0.0

в гугле есть всего 3 ссылки на эту ошибку, две не решенные, одна хрен пойми на каком языке. Не знаю что делать :(

Cupper
()

Debian for server

Форум — Linux-install

У меня есть вечер чтобы хотя бы в теории разобраться в процессе установки debian'a на серверную станцию (какая именно я незнаю, но предпологаю что что то вроде amd xeon, наверно и с рейд массивом :), вобщем пока могу тока гадать). Я раньше с дебианом некогда не сталкивался, только с бубунтой. Значит попытался разобраться сам, возникли вопросы, нужны ваши ответы: 1. Как я понял у дебиана весьма странная политика дистрибутивов: Internet, «полный CD/DWD» и какойто там бусинес и не какого разделения на desktop/server. «Полный CD/DWD» это что то вроде DVD инсталятора убунты (только состоит из 4-5 дисков, т.е. всевозможный софт). Internet это что то вроде обычно CD инсталяшки только куда меньше софта. В следствии чего я не знаю какой из них выбирать для установки в качестве сервера. Я склоняюсь к Internet ведь мне ничего особо не нужно, на него потом апачь, БД, ну и мелкие прибомбахи. Я правильно думаю ? 2. Я раньше не когда не работал с серверами, и тем более с рейдами, поэтому хочу узнать на каком этапе установки встает вопрос о создании/разбиении рейда ? и как это реализуется (средствами псевдографического debian'новского инстолятора или прочими примудростями) 3. Выбор архитектуры образа x86 или amd64, я в замешательстве %) и кстати я не увидел разделения на 32-х и 64-х битныю образы, или это оно и есть ? но разве x86 не бывает 64 разрядный ? 4. Если ставить Internet образ, то можно ли его ставить с флешки, и как это сделать ? просто залить iso на флшеку и сторонней прогараммой чтото там сделать, или записать образ непосредственно на флешеку как на CD (прожечь)?

Ух, заранее спасибо за все ответы и советы :)

Cupper
()

Экспортируемые ядром функции

Форум — Development

Есть ли список всех этих функций ? Не всех тех что в данные момент доступны (/proc/kallsyms) а именно список всех тех что есть в ядре?

В гугле найти не смог :(

Cupper
()

set_fs()

Форум — Development

Помогите разобраться что конкретно делает эта функция и для чего ее можно применять, а для чего нельзя. Я находил в гугле статьи про эту функцию но они все основанные на сис. вызове sys_open вследствии чего не смог понять некоторые аспекты. А именно интересует:

old_fs = get_fs()
set_fs(KERNEL_CS)
/* что именно тут произойдет, и что тут можно делать
* если например эту конструкцию заюзать из USER SPCASE неужто она
* даст доступ к данных в KERNEL SPACE ? Если даст то только к данным
* или к коду тоже (т.н. можно запускать ядровые функции)
* вызывается ли она с отличного от 0-го кольца привилегий ?
set_fs(old_fs)

Cupper
()

/proc/kallsyms

Форум — Development

Возьмем к примеру одну из строчек файла c0577150 R sys_call_table что означает идентификатор R, и все остальные (T, t, r, d, a, ...)

Второе: вроде бы как с 2.6.* таблица системных вызовов не экспортируется ядром, а тут она присутствует, возможно все дело в параметре R...?

У меня в этой файле ~85к строчек, следовательно из модуля может быть доступно 85к функций ?

Cupper
()

RSS подписка на новые темы