Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Системные часы: прошедшее время и таймеры





2 98 case RTC_UIE_OFF: /* отключение прерываний от обновлений RTC. */

3 02 case RTC_UIE_ON: /* включение прерываний от обновлений RTC. */

3 05 case RTC_RD_TIME: /* Чтение времени/даты из RTC */
306

307 memset (& wtime, 0, sizeof (wtime) );

308 get_rtc_time(& wtime); 309

310 return copy_to_user ( (void *) arg, & wtime, sizeof (wtime) )? -EFAULT: 0;
311

312 case RTC_SET_TIME: /* Set the RTC */

313 return -EINVAL;

314 }

353 static int gen_rtc_open(struct inode *inode, struct file *file)

354 {

3 55 if (gen_rtc_status & RTC_IS_OPEN)

3 56 return -EBUSY;

3 57 gen_rtc_status |= RTC_IS_OPEN;

Этот код реализует тот же набор команд ioctl. Так как мы выполняем вызов ioctl из проверочной программы пользовательского пространства с флагом RTC_RD_TIME, управление передается на строку 305. Следующий вызов в строке 308 - это get_rtc_time(& wtime) из rtc.h (см. соответствующий код). Перед тем как оста­вить этот блок кода, обратите внимание на строку 353. Она позволяет получать доступ к драйверу только для одного пользователя зараз с помощью open (), устанавливающей состояние драйвера в RTC_IS_OPEN:

include/asm-ppc/rtc.h

45 static inline unsigned int get_rtc_time(struct rtc_time *time)

46 {

047 if (ppc_md.get_rtc_time) {

048 unsigned long nowtime;
049

050 nowtime = (ppc_md.get_rtc_time)();

052 to_tm(nowtime, time);

054 time-> tm_year -= 1900;

055 time-> tm_mon -= 1; /* Make sure userland has a 0-based month */

056 }



Глава 7 • Планировщик и синхронизация ядра


057 return RTC_24H;

058 }

Встроенная функция get_rtc_time () вызывает функцию, устанавливающую переменную-указатель в значение ppc_md. get_rtc_time на строке 50. Ранее при ини­циализации ядра эта переменная устанавливалась в chrp_setup. с:

arch/ppc/platforms/chrp_setup.c

447 chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,

448 unsigned long r6, unsigned long r7)

449 {

 

477 ppc_md.time_init = chrp_time_init;

478 ppc_md.set__rtc_time = chrp_set_rtc_time;

479 ppc_md.get_rtc_time = chrp_get_rtc_time;

480 ppc_md.calibrate_decr = chrp_calibrate_decr;

Функция chrp_get_rtc_time () (в строке 479) определена в chrp__time.c в следующем блоке кода. Так как информация о времени в памяти CMOS обновляется на периодической основе, блокировка кода чтения включена в цикл for, который пересчитывает обновляемые в прогрессе блоки:

arch/ppc/platforms/chrp_time.с

122 unsigned long _ chrp chrp_get__rtc_time(void)

123 {

 

124 unsigned int year, mon, day, hour, min, sec;

125 int uip, i;

141 for ( i = 0; i< 1000000; i++) {

142 uip = chrp_cmos_clock_read(RTC_FREQ_SELECT);

143 sec = chrp_cmos__clock_read(RTC_SECONDS);

144 min = chrp_cmos_clock__read(RTC_MINUTES);

145 hour = chrp_cmos_clock_read(RTC_HOURS);

146 day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH);

147 mon = chrp_cmos_clock_read(RTC_MONTH);

148 year = chrp_cmos_clock_read(RTC_YEAR);

149 uip |= chrp_cmos_clock_read(RTC_FREQ_SELECT);

150 if ((uip & RTC_UIP)==0) break;

 

151 }

152 if (! (chrp_cmos_clock_read(RTC_CONTROL)

153 & RTC_DM_BINARY) || RTC_ALWAYS_BCD)

154 {


7.4 Системные часы: прошедшее время и таймеры



155 BCD_TO_BIN(sec);

156 BCD_TO_BIN(min);

157 BCD_TO_BIN(hour);

158 BCD_TO_BIN(day);

159 BCD_TO_BIN(mon);

160 BCD_TO_BIN(year);

161 }

54 int __ chrp chrp_cmos_clock_read(int addr)

55 { if (nvram_asl! = 0)

 

56 outb(addr»8/ nvram_asl);

57 outb(addr, nvram_as0);

58 return (inb(nvram_data));

059 }

Наконец, в chrp_get_rtc_time () значения отдельных компонентов структуры времени считываются с устройства RTC с помощью функции chrp_cmos_clock_ read. Эти значения форматируются и возвращаются в структуру rtc_tm, передаваемую в обратном вызове ioctl в пространство проверочной программы.

Чтение из часов реального времени на х86

Метод чтения RTC на платформе х86 довольно похож, но немного более компактен и удобен по сравнению с методом на РРС. Еще раз мы открываем драйвер /dev/rtc, но на этот раз при сборке компилируется файл rtc. с для архитектуры х86. Далее обсу­ждается вариант исходного кода для х86.

drivers/char/rtc.с

352 static int rtc_do_ioctl(unsigned int cmd,

unsigned long arg, int kernel)

353 {

switch (cmd) {

482 case RTC_RD_TIME: /* Read the time/date from RTC */

483 {

 

484 rtc_get_rtc_time (ScWtime);

485 break;

486 }

1208 void rtc_get_rtc_tinie (struct rtc_time *rtc_tm)

1209 {



Глава 7 • Планировщик и синхронизация ядра


123 8 spin_lock_irq(& rtc_lock);

1239 rtc_tm-> tm_sec = CMOS_READ(RTC_SECONDS);

1240 rtc_tm-> tm_min = CMOS_READ(RTC_MINUTES);

1241 rtc_tm-> tm_hour = CMOS_READ(RTC_HOURS);

1242 rtc_tm-> tm_mday = CMOS_READ(RTC_DAY_OF_MONTH);

1243 rtc_tm-> tm_mon = CMOS_READ(RTC_MONTH);

1244 rtc_tm-> tm__year = CMOS_READ(RTC_YEAR);

1245 Ctrl = CMOS_READ(RTC_CONTROL);

1249 spin_unlock_irq(& rtc_lock);

12 51 if (! (ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD)

1252 {

1253 BCD_TO_BIN(rtc_tm-> tm_sec);

1254 BCD_TO_BIN(rtc_tm-> tm_min);

1255 BCD_TO_BIN(rtc_tm-> tm_hour);

1256 BCD_TO_BIN(rtc_tm-> tm_mday);

1257 BCD_TO_BIN(rtc_tm-> tm_mon);

1258 BCD_TO_BIN(rtc_tm-> tm_year);

1259 }

Программа проверки использует флаг RTC_RD_TIME в вызове ioctl () драйвера в rtc.c; ioctl переключает состояние и затем заполняет структуру из памяти CMOS для RTC. Далее приведена реализация аппаратного чтения из RTC для х86.

include/asm-i38б/mcl46818rtc.h

018 #define CMOS_READ(addr) ({ \

019 outb_p((addr), RTC_PORT(0)); \
02 0 inb_p (RTC_PORT(1)); \

021 })

Резюме

В этой главе описаны планировщик Linux, приоритетное прерывание обслуживания, сис­темные часы и таймер Linux.

Точнее говоря, мы обсудили следующие темы:

• мы представили вашему вниманию новый планировщик Linux 2.6 и рассмотрели его особенности;

• мы обсудили, как планировщик выбирает новую задачу из множества задач и как используется алгоритм работы планировщика и т. д.;


Упражнения



• мы обсудили переключение контекста, используемого планировщиком для переключения процессов, и проследили соответствующие функции до уровня аппаратно-специфического кода;

• мы описали, как процессы в Linux могут передавать управление процессором другому процессу с помощью вызова schedule () и как ядро маркирует процессы, требующие «перепланировки»;

• мы углубились в подсчет ядром Linux динамических приоритетов на основе преды­дущего поведения отдельного процесса и в то, как процесс удаляется из очереди планировщика;

• далее мы перешли к описанию явных приоритетных прерываний обслуживания пользовательского уровня и уровня ядра и их реализации в ядре Linux 2.6;

• и наконец, мы рассмотрели таймеры, системные часы и реализацию системных часов на архитектурах х86 и РРС.

Упражнения

1. Как Linux сообщает планировщику, чтобы тот периодически запускался?

2. Опишите различие между интерактивными и неинтерактивными процессами.

3. С точки зрения планировщика какими отличиями обладают процессы реального времени?

4. Что происходит, когда у процесса заканчиваются запланированные тики?

5. В чем преимущество 0(1)-планировщика?

6. Какие структуры данных использует планировщик для управления приоритетами запущенных в системе процессов?

7. Что произойдет, если вы вызовите schedule () во время циклической блокировки?

8. Как ядро решает, возможно ли выполнить неявное приоритетное прерывание обработки задачи?


Глава



Загрузка ядра

В этой главе:

? 8.1 BIOS и Open Firmware

? 8.2 Загрузчики

? 8.3 Архитектурно-зависимая инициализация памяти

? 8.4 Диск инициализации в памяти

? 8.5 Начало: start_kernel()

? 8.6 Поток init (или процесс 1)

? Резюме

? Вопросы для самопроверки



Глава 8 • Загрузка ядра


Н

а данный момент мы рассмотрели подсистемы ядра Linux и используемые в их операциях структуры. Каждая глава подразумевала, что подсистема была на­строена и запущена, а мы фокусировались на типичном управлении подсистемами ядра и обработке их операций. Тем не менее каждая из подсистем должна быть ини­циализирована перед использованием. Эта инициализация происходит во время загрузки ядра, после того как загрузчик завершит загрузку образа ядра в память и передаст ему управление.

Мы выбрали путь следования процессу инициализации ядра в линейном поряд­ке. Начнем мы с обсуждения того, что при этом происходит, начиная с включения и вызова первой архитектурно-зависимой функции, start_kernel (), и заканчивая вызовом процесса инициализации /sbin/init. Рис. 8.1 иллюстрирует порядок со­общений начиная с включения и заканчивая выключением.

 

    /--------- ^ч /*---- " " х /*------ " " ч. /^ ^\ /^---- " \ f------- \    
  Включение ^..вюз^з^^-гЛУ £ szz. V *~ \(ysrУ Выключение  
    \------- --------- --------- S \^^ ^у/ ^------- \----------- */    

Рис. 8.1. Старт ядра и процесс загрузки

Мы начнем с обсуждения BIOS и Open Firmware, являющихся первым кодом, запус­каемым на системах х86 и РРС при включении соответственно. Далее мы обсудим наибо­лее распространенные загрузчики, используемые в Linux, и то, как они загружают ядро и передают ему управление. После этого мы подробно обсудим шаги инициализации ядра (kernel initialization), во время которой инициализируются все подсистемы. В конце инициализация ядра происходит вызов /sbin/init как процессом 1. Программа init продолжается тем, что называется инициализацией системы (system initialization), с по­мощью включения процессов, необходимых перед регистрацией пользователя в системе.

Вскоре станет ясно, что часть инициализации ядра состоит из вложенных инициали­заций подсистем. Это затрудняет попытки проследить непрерывный процесс инициализа­ции подсистем с начала и до конца. Тем не менее дальнейший линейный порядок загрузки ядра Linux позволяет проследить настройку подсистем ядра и по мере их появления и ил­люстрирует сложность процесса загрузки.

Мы коснемся многих структур, представленных в предыдущих главах, по мере их за­грузки и инициализации. Мы начнем с рассмотрения первого шага: BIOS и Open Firmware.

BIOS и Open Firmware

При включении процессор сначала получает доступ к адресам, которые обычно находят­ся в доступной для чтения области памяти. Эта доступная только для чтения память обычно располагается в Flash ROM (или просто Flash). Там располагается первый код,


Загрузчики



который выполняется при каждом запуске системы. Этот код отвечает за включение ми­нимума систем, необходимых для загрузки ядра.

На х86-системах он полностью находится в BIOS (Basic Inpit Output System)1 -блоке аппаратно-зависимого кода инициализации системы, загружающего систему. На системах х86 загрузчик, и соответственно Linux, зависит от BIOS, приводящего систе­му в определенное состояние. Интерфейс BIOS составляет унифицированный набор функций, известных как npepbmaHHH(interrupts). Во время загрузки Linux использует эти прерывания для запроса доступных ресурсов системы. После того как BIOS закончит инициализацию, он копирует первые 512 байт с устройства загрузки (описываемого в сле­дующем разделе) в адрес 0х7с00 и переходит в него. Несмотря на то что в некоторых случаях BIOS загружает операционную систему через сетевое соединение, мы будем рас­сматривать процесс загрузки Linux с жесткого диска. После загрузки Linux BIOS все равно находится в памяти и его функции доступны через прерывания.

На PowerPC тип кода инициализации зависит от возраста соответствующей архитек­туры PowerPC. Старые системы IBM используют PowerPC Reference Platform (PreP)2, тогда как более новые системы IBM используют Common Hardware Reference Platform (CHRP)3. Системы G4 и позднейшие называются «Новым миром» и используют Open Firmware(OF) в границах реализации конкретной архитектуры. (Более подробную ин­формацию об этих процессорах и системно-зависимом загрузочном firmware, а также со­вместимости их форматов вам стоит получить с домашней страницы Open Firmware на www. openf irmware. org.)

Загрузчики

Загрузчики - это программы, находящиеся на загрузочном диске компьютера. Первым устройством загрузки обычно является первый жесткий диск системы. Загрузчик вызыва­ется BIOS (x86) или firmware (PPC) после того, как инициализация системы обеспечит поддержку памяти, прерываний и ввода-вывода, требуемых для загрузки ядра. После за­грузки ядро инициализируется и конфигурируется операционной системой.

Для систем х86 BIOS позволяет пользователю установить последовательность устройств загрузки для его системы. Такими устройствами загрузки обычно являются флоппи-дисководы, CD-ROM и жесткие диски. Форматирование диска (например, с помо­щью f disk) создает на диске Master Boot Record (MBR)4, располагающуюся в первом секторе (сектор 0, цилиндр 0, головка 0) загрузочного диска. MBR содержит небольшую программу и таблицу разделов из четырех элементов. Конец загрузочного сектора помеча-

L Базовая система ввода-вывода. Примеч. пер.

2 Эталонная платформа PowerPC. Примеч. пер.

3 Простая эталонная аппаратная платформа. Примеч. пер.

4 Главная загрузочная запись. Примеч. пер.



Глава 8 • Загрузка ядра


ется шестнадцатеричных значением 0хАА55 в позиции 510. Табл. 8.1 демонстрирует ком­поненты MBR.

Таблица 8.1. Компоненты MBR
Отступ Длина Назначение

 

0x00 Oxbd Код программы MBR
Oxlbe 0x40 Таблица разделов
Oxlfe 0x2 Шестнадцатиричный маркер сигнатуры

Таблица разделов MBR хранит информацию, относящуюся к каждому из главных разделов жестких дисков. Табл. 8.2 демонстрирует, как выглядит каждая 16-битовая за­пись в разделе MBR.

Таблица 8.2. 16-битовые записи MBR

Отступ Длина Назначение


 


Поделиться:



Популярное:

  1. C1 (повышенный уровень, время – 30 мин)
  2. Past Perfect - прошедшее совершенное время
  3. Present Continuous - настоящее длительное время
  4. The Present Simple Tense (настоящее простое время)
  5. V). Фотосъёмки, произведённые 21 декабря 1944 во время полета 15SG/994 для оценки причинённого бомбардировкой ущерба.
  6. V. Bыпишите из 1-ro aбзацa npeдложение с глаголомв пассивной форме, назовите время глагола. Предложение переведите.
  7. VI. ВСЕРОССИЙСКИЙ ПАТРИАРХ ТИХОН И ЕГО ВРЕМЯ
  8. VI. Выпишите из 2-го абзаца предложения с глаголом в пассивной форме, назовите время глагола. Предложения переведите.
  9. VIII. Выпишитеиз 4-roабзацапредложениесместоименнымглаголом. Переведите его. Укажите время, в котором стоит глагол. Напишите его инфинитив.
  10. Августин, И. Ньютон, Г. Лейбниц, Э. Мах: Время как философская категория
  11. Быть мягкими к себе во время горя.
  12. В каких случаях работникам предоставляются специальные перерывы для обогревания и отдыха, которые включаются в рабочее время (ст.109 ТК РФ)?


Последнее изменение этой страницы: 2016-03-25; Просмотров: 741; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.041 с.)
Главная | Случайная страница | Обратная связь