Ассемблерный код ядра
который выполняет все эти действия, строго говоря, не является функцией, потому что не возвращает управление функциям, которые его вызвали. Этот фрагмент кода имеет две точки входа: ret_from_intr о и ret_from_exception . Как следует из их названий, ядро входит в первую точку, когда завершает обработчик прерывания, и во вторую — когда завершает обработчик исключения. Далее мы будем называть эти точки входа функциями, чтобы упростить изложение.
Серые блоки обозначают ассемблерные инструкции, реализующие вытеснение в ядре .Если вы хотите разобраться, как работает ядро, откомпилированное без поддержки вытеснения, просто игнорируйте серые блоки. На ЭТОЙ блок-схеме ТОЧКИ входа ret_from_exception и ret f rom intr выглядят почти одинаково. Разница проявляется, только если при компиляции ядра была выбрана опция поддержки вытеснения. В этом случае локальные прерывания отключаются сразу после возврата из исключений.
Блок-схема
Эта блок-схема дает общее представление о действиях, которые необходимо выполнить, чтобы возобновить выполнение прерванной программы. Перейдем к деталям и обсудим ассемблерный код.
Точки входа
Точки входа ret from intr о и ret from exception
практически эквивалентны следующему фрагменту кода:
ret_f rom_exception:
cli ; отсутствует, если вытеснение в ядре не поддерживается ret_f rom__intr:
movl $-8192, ebp ; -4096, если используется несколько стеков режима ядра andl esp, ebp movl 0x30(esp), eax movb 0x2c(esp), al testl $0x00020003, eax jnz resume_userspace jpm resume_kernel
Вспомним, что при возврате из прерывания локальные прерывания отключены .Поэтому ассемблерная инструкция cli выполняется только при возврате из исключения.
Ядро загружает адрес дескриптора thread info текущего процесса в регистр ebp .
Затем значения регистров cs и efiags, которые были помещены в стек, когда произошло прерывание или исключение, используются для определения, работала ли прерванная программа в режиме пользователя, либо установлен ли флаг vm в регистре efiags. В любом случае совершается переход на метку resume userspace. Если результат проверки отрицателен, переход делается на метку resume_kernel.
Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | Следующая страница