Суббота, 04.05.2024
Королевство Delphi
Главное меню
Статьи
Наш опрос
Нужен форум на сайте?
Всего ответов: 90
Статистика
Онлайн всего: 1
Гостей: 1
Пользователей: 0
Форма входа
Главная » Статьи » Система » Железо

Играем с CMOS, или Проснись и пой, компьютер мой

Недавно наконец-то сбылась моя давняя мечта: в моем доме завелось разумное детище человеческого разума — компьютер. В порядке жизни семьи произошел качественный скачок. Целыми днями не смолкает музыка собранной мною коллекции из лучшего, что есть у знакомых и друзей. Пересмотрены все лучшие фильмы, только появляющиеся в прокате («хай живе пиратський ринок» — это можете не печатать, я знаю, что это нехорошо, но ничего не могу с собой поделать). Долгие тоскливые вечера превратились в череду яростных напряженных баталий на полях виртуального мира. Жену, ранее относившуюся к идее покупки компьютера скептически и допустившую трату значительной суммы, потакая моей блажи, теперь могут оторвать от экрана монитора только силы материнского инстинкта, вызываемые настойчивыми изъявлениями недовольства нашей маленькой дочери. При этом ее рейтинги почти во всех играх уже обогнали мои (мне еще и на службу ходить надо).

Но у меня лично особый восторг вызывают такие «способности» компьютера, как возможность планирования заданий и управления включением-выключением питания компа, что вкупе с детальным анализом своей деятельности, а также правильной настройкой планировщика и шедулера приближают поведение нашего железного друга к уровню «разумного», пунктуального, ничего и никогда не забывающего, верного помощника-секретаря. Мой duron’чик подсказывает мне каждый час время. По приходу с работы на обед проигрывает пару моих любимых песен и ставит последний фильм, напоминает про незавершенные дела, назначенные встречи и т. д. Для этого я использую всем известные программы Планировщик заданий, входящий в начинку windows 98, и outlook из пакета ms office.

А теперь к сути проблемы. Наше сказочное совместное сосуществование с компом омрачало маленькое неудобство. Как и для большинства горожан, самое тяжелое время дня для меня — утро. И для того чтобы скрасить мучительный процесс перехода из сладких объятий сна в железные тиски реальности, я ставлю на включение минут за 15 до момента, когда надо вставать, парочку композиций любимой музыки (кидаю ярлыки композиций в автозагрузку). Пятнадцати минут как раз хватает на то, чтобы свыкнуться с мыслью, что я — человек с планеты Земля, представитель не самой ее богатой части, и если не отнесу сейчас свое тело на работу, то потеряю какие-то деньги и это кое кого расстроит. Последняя композиция своим хорошим энергичным драйвом придает непослушному телу необходимую скорость для преодоления земного притяжения и отрыва его от постели. Как «попросить» комп проснуться в нужное время? Просто, скажете вы, зайди в setup и измени настройки соответствующей опции. Фу, как грубо. Ведь это просто неудобно — необходимо перезагружать компьютер, чтобы войти в setup, потом выключать компьютер в процессе загрузки или ждать запуска системы и выключать заново. И это всякий раз, когда необходимо изменить какие либо параметры, т. е. практически каждый день. А программ, «умеющих» программировать будильник, к своему сожалению и недоумению, я не нашел. Пришлось напрягать извилину. Вникнув в вопрос, я понял причину отсутствия таких программ. Рассудим логически — время будильника, как и множество других параметров, доступных нам из встроенной программы setup (например, частота разгона процессора или пароль), являются настройками bios’a, bios же пишется под конкретный стандарт конкретного железа. Числовые значения этих параметров хранятся в энергонезависимой (т. е. на своей батарейке) памяти cmos. Естественным выводом из этого будет то, что и структура cmos у таких машин тоже может быть разная, т. е. значения одних и тех же параметров (час включения машины, например) у разных компьютеров могут храниться по разным адресам. Стандарт Плуга и Плэя регулирует правила движения в области, находящейся между bios’ом и дровами ОС, а нужные нам примочки находятся на уровень ниже — под bios’ом. Так, проведя ряд экспериментов над машинами друзей, я пока что выявил закономерность зависимости system bios и, соответственно, структуры cmos от используемого чипсета материнской платы, вид которого в свою очередь диктуется типом процессора — это могут быть продукты amd под слот socket a, intel под socket 370 или другими менее известными и распространенными. Но как мне кажется, в самом общем случае следует ожидать, что у материнок разных производителей, или даже одного производителя, но с разными характеристиками (наличие/отсутствие isa, тип чипсета, наконец, и т. д.) структура cmos будет разной. «Проклятые покемоны», — пробурчите вы и махнете рукой на идею найти такие необходимые нам программы. И правильно сделаете, скажу я вам, мы их напишем сами. Подумайте — даже ведущие программисты шарашки Макрософт, фамилии которых светятся в пасхальных яйцах почему-то таких дорогих софтин, когда-то, как и мы, пачкали пеленки и одно время даже не умели говорить. А значит, они не лучше нас и, что уж точно, мы не хуже их. Просто мы привыкли, что за нас уже кто-то все сделал, надо только порыться в закромах Сети. Выходим из режима поиска и начинаем творить.

Хочу сразу оговорить: все нижеизложенное реализовано мною на языке delfi. Полного листинга программ не предоставляю, т. к. основной целью этой статьи считаю довести саму идею, которая сама по себе несложна, а также основные моменты ее реализации.

Для начала, что такое cmos? С точки зрения программиста, это специальная область энергонезависимой памяти, в которой хранятся значения параметров настроек bios’a, например пароль (читайте цикл статей «bios и его настройки»). Даже в выключенном состоянии комп «помнит» пароль и кучу других настроек, которые вы задали, когда последний раз заходили в setup, или выставленных по умолчанию, если вы даже не подозреваете об их существовании. (держим клавишу delete при старте). Размер cmos — 128 байт, при этом не все адреса обязательно используются.

Для начала нам необходима функция, с помощью которой мы могли бы прочитать значение, хранящееся по заданному адресу cmos. Процедуры извлечения и записи параметров из cmosa я написал в виде ассемблерных вставок. Ваше право — выполнить их как вам угодно, лично я до сих пор не нашел в delphi стандартных процедур доступа к портам.

Функция чтения значения параметра cmos и rts, находящегося по адресу i:

function tform1.readcmos(i:byte):byte;
var zn:byte;
begin
//входные параметры
//i — адрес ячейки, чтение значения которой производится
//выходные параметры
//zn — прочтенное значение
asm //ассемблерная вставка
mov al,i //номер ячейки, из которой производится чтение
out 70h,al //заносим это значние в порт cmos rts
wait
xor ax,ax //очистка регистра ax
in al,71h //вводим в регистр al из порта значение ячейки smoc rts
wait
mov zn,al //присваеваем zn значение ячейки
end;
result:=zn;
end;

Для того чтобы просмотреть все содержимое cmos, создадим цикл по і =0..127, в котором последовательно будем извлекать значение по адресу і и запоминать . Для этого кинем на форму объекты button1 и memo1. В обработчике события onclick объекта button1 зададим цикл, в котором к свойству lines:tstrings (список строк) объекта memo1 будем прибавлять строку, состоящую из адреса и значения по этому адресу в десятичном и шестнадцатеричном виде:

procedure tform1.button1click(sender: tobject);
begin
memo1.lines.clear; //удаляет все строки из списка
for i:=0 to 127 do
//прибавление к списку строки
memo1.lines.add(inttostr(i) + ' = ' + inttostr(readcmos(i))+ ' = ' + format('%0x',
[readcmos(i)]));
end;

Нам придется запоминать созданный «образ» cmos. Кинем на форму второй button2 и в обработчике события onclick зададим сохранение списка строк memo1.lines в файле:

procedure tform1.button2click(sender: tobject);
begin
//сохранение "образа” cmos в файле ff.ff на диске С
memo1.lines.savetofile('c:ff.ff');
end;

Теперь главное. Как узнать, по какому адресу находится нужный нам параметр? А в данном случае нас интересует день, час и минута будильника. Перезагрузите компьютер, войдите в setup, пункт ..., опцию ...... и выставьте эти значения в ноль (так легче проследить изменения). Загрузитесь. Просмотрите cmos и запомните его в файле (можете сразу обратить внимание на адреса, по которым записаны нули, но это не обязательно то, что мы ищем). Перезагрузитесь снова. Меняете значение параметра, допустим, часа на произвольную величину, например, три. Загружаетесь. Просматриваете cmos и сравниваете с сохраненным. Сравнение реализуем следующим образом: кинем на форму еще один объект memo2 и button3. В обработчике события объекта button3 onclick загрузим из файла (созданного нами при прошлом сохранении «образа» cmos) свойство memo2.lines (список строк). Затем в цикле i = 0..127 будем сравнивать строки memo1.lines (текущие настройки) и memo2.lines (настройки до перезагрузки и изменения). Если строки не совпадают, конкатенируем (присоединим, по-нашему) к соответствующей строке memo2.lines[i] три восклицательных знака:

procedure tform1.button3click(sender: tobject);
begin
//загрузка "образа” cmos, сохраненного до перезагрузки
memo2.lines.loadfromfile('c:ff.ff');
//сравнение строк и пометка несовпадающих; по окончании цикла у нас будут стоять 
//восклицательные знаки напротив адресов и значений, которые изменились
for i:=0 to 127 do
if memo1.lines.strings[i]<>memo2.lines.strings[i] then
memo2.lines.strings[i]:=memo2.lines.strings[i]+ ' !!!';
end;

Теперь внимание! По адресам 0,2.4 находятся значения секунд, минут и часов системного времени (слава Богу, это стандартизировано), поэтому, естественно, значения по этим адресам всегда могут отличаться от сохраненных ранее. Также каждую секунду, прыгает значение по адресу 12. Исключите эти адреса из рассмотрения. Главное — ищите адрес, по которому значение параметра изменилось на три (было 0, стало 3) — это и есть адрес, по которому хранится час будильника. Далее читай внимательно. На три изменилось еще одно значение. Дело в том, что значения параметров всех адресов, начиная с некоторого, суммируются, и эта сумма хранится в двух байтах cmos где то в области последних адресов, которые нам тоже необходимо выяснить. Это так называемая контрольная сумма. После включения питания комп тестирует cmos путем его суммирования и сравнения полученной суммы с контрольной суммой. Поэтому если ты не дочитал статью, а кинулся и сам уже написал процедуру записи значения в cmos и проделал это без соответствующего изменения контрольной суммы, то при следующей перезагрузке комп только жалобно пискнет, выдаст сообщение, что у него что-то с головой, тьфу, с cmos’ом не в порядке и выставит все настройки по умолчанию (не самый лучший вариант). Так что набирайся терпения и читай дальше. Вот таким образом изменения происходят по двум адресам:


79 = 3 =3 !!! значение часа

123 = 12 = С два байта
124 = 35 = 23 !!! контрольной суммы

Учти, что младший байт контрольной суммы хранится по большему адресу (у меня по 124), а старший по меньшему (у меня — по 123). Также учти, что измениться может только младший байт, но может и старший, если младший увеличится больше чем на 256 (ff — максимум содержимого одного байта), и тогда произойдет перенос единицы в старший.

Чтобы избежать случайностей, проделай все это с одним только параметром и неизменными другими, и потом то же самое с другими параметрами. Таким образом ты выяснишь, по каким адресам у тебя находится то, что тебе нужно, в нашем случае час, минута и день будильника. Обрати внимание на поведение контрольной суммы — когда значение по более старшему адресу достигает 256, оно обнуляется, и увеличивается содержимое по более младшему адресу )происходит перенос единицы) — мы это будем учитывать при записи значения в cmos, к чему сейчас и приступим.

Напишем две процедуры — одну только для записи значения по адресу, другую для записи значения по адресу с соответствующим изменением контрольной суммы:

procedure form1.writetocmos(i:byte;zn:byte);
begin
//процедура записи значения zn по адресу i
asm
mov al,i // Установка адреса cmos
out 70h,al
wait
mov dx,71h
mov al,zn
out dx,al //запись знечения в адрес adress
end;
end;

Получить ссылку на материал

Категория: Железо | Добавил: Барон (10.12.2011)
Просмотров: 802 | Теги: cmos | Рейтинг: 0.0/0
[ Пожертвования для сайта ] [ Пожаловаться на материал ]

Если вам помог материал сайта кликните по оплаченной рекламе размещенной в центре

Поиск
Категории раздела
ActiveX [10]
CORBA и COM [16]
Kol и MCK [23]
WinAPI [28]
Компоненты [27]
Работа с Bluetooth [4]
Железо [8]
Текст [18]
Разное [98]
Королевство Delphi © 2010-2024
Яндекс цитирования