Похоже, проект Uniflash загнулся - полтора года без обновлений. Потому, чтобы убить сразу несколько зайцев завожу тут подобную тему, которая не только есть продолжение юнифлеша, но и разбор на его базе процесса перешивки на "атомном" уровне, которое когда-то давно предполагалось при написании статьи по перешивке.
Чтобы отличать его от проекта uniflash, но в то же время отражать прямую преемственность не напрягая фантазию назвал как runiflash.
Итак, приступим. (Скачать исходники юнифлеша можно на родном сайте или здесь.) Излагать буду в "черновом" варианте, потому исправления, дополнения и опровержения приветствуются. После все внесется в статью по перешивке биос.
Процесс перешивки с "практическо-железной" точки зрения представляет собой доступ в те области памяти, которые в "нормальном" режиме недоступны. Чтобы получить к ним доступ (здесь и далее все подразумевает то, как сделано именно в юнифлеше, даже с учетом, что это может быть не самый лучший способ и т.п.) делаются следующие вещи:
1. Переходим в линейный режим памяти. У него могут быть разные названия (Linear/UnReal/Flat), но смысл один и тот же - 32-битный доступ. (в досе, ко всей памяти).
2. "Размапливаем" северный мост (если требуется).
3. "Размапливаем" южный мост (если требуется).
4. "Размапливаем" мультик (если требуется).
5. "Размапливаем" GPIO (если требуется).
Операция "размапливания" подразумевает программирование логики на доступ к самой FlashROM. Все эти процедуры "железозависимые" и с претензиями на реальную универсальность требуют учета всех возможных вариантов использования "защиты от записи". В частности, именно поэтому "размапливание" делится на подобны градации - специфичные для северника-южника-мультика-гпио (в "стандартном" случае размапливание подразумевает лишь южник).
Далее идут процедуры уже конкретно работы с микросхемой, которые так же специфичны для различных типов-производителей флэшек.
После для возможности корректной работы при выходе нужно будет "замапить" все до этого "размапленные" пункты и вернуться в "нормальный" режим (адресации, 16 бит).
Вот коротко так выглядит работа юнифлеша для нашей темы. Главный файл, который ответственный за прошивку - PCI.pas - его и по-тихоньку начнем разбирать.
{$R-} unit PCI; { Unit to communicate with chipsets } interface
uses Award, AMIBIOS, AsusBIOS, Phoenix;
Const PCICfIdx = $CF8; PCICfData = $CFC;
Var NorthFunc, SouthFunc, LPCFunc: Word; NorthPos,SouthPos,PMUPos,CurPCIROM,PCIROMBus,PCIROMDev,PCIROMFun,LPCBase: Byte; CurrentChipset, CurrentPCICard: string; WantToUseAMI, AMIUsed, ChipsetFound, ROMEnabled, PCIROMEnabled: Boolean; WantToUseAsus, AsusUsed: Boolean; AwardUsed: Boolean; {1.42re} PhoenixUsed: Boolean;{1.43re}
PCIROMs: array[1..20] of record MaxSize : LongInt; VenID, DevID : Word; Bus, Pos : Byte; end; BIOSID: array[1..8] of Char; {v1.34}
Procedure OPortD( Prt : Word; Val : LongInt ); Function IPortD( Prt : Word ) : LongInt; Function GetPCIRegD( Bus, Dev, Func, Reg : Byte ) : LongInt; Procedure SetPCIRegD( Bus, Dev, Func, Reg : Byte; Value : LongInt ); Function LocatePIIX : {byte}Boolean; {v1.22 byte->boolean} procedure GetBIOSID; Procedure RomEnable( Map : boolean); procedure ShadowDisable_Aladdin; {v1.31} procedure ShadowRestore_Aladdin; {v1.31}
implementation Uses Tools,Flash,Crt,DMI;
{ PortD[ x ] := y } Procedure OPortD( Prt : Word; Val : LongInt ); Assembler; Asm DB 66H MOV AX,WORD PTR Val MOV DX,Prt DB 66H OUT DX,AX End;
{ y := PortD[ x ] } Function IPortD( Prt : Word ) : LongInt; Assembler; Asm MOV DX,Prt DB 66H IN AX,DX DB 66H MOV DX,AX DB 66H SHR DX,16 End;
Описание дальнейших процедур опускаю и опишу позже, дабы разбираться "от общего к частностям". Потому и переходим сразу к главной процедуре:
Begin if Port[$CFB]<>$FF then {v1.26} Port[$CFB]:=Port[$CFB] or $1; {Set PCI configuration mechanism #1}
{Locate north bridge} For Pos_ := 0 to $FF do If ( GetPCIRegD( $00, Pos_ shr 3, Pos_ and $07, $00 ) and $FFFF ) <> $FFFF then If ( GetPCIRegD( $00, Pos_ shr 3, Pos_ and $07, $08 ) shr 8 ) = $60000 then Break; If Pos_ = $FF then {v1.22} Begin LocatePIIX := False; Exit; End else LocatePIIX:=True; NorthPos := Pos_; {Get north bridge MID & DID} NorthMan := GetPCIRegD( $00, NorthPos shr 3, NorthPos and $07, $00 ); NorthId := GetPCIRegD( $00, NorthPos shr 3, NorthPos and $07, $00 ) shr 16; {Get north bridge rev ID} NorthRev := GetPCIRegD( $00, NorthPos shr 3, NorthPos and $07, $08 );
{Locate south bridge} For Pos_ := 0 to $FF do If ( GetPCIRegD( $00, Pos_ shr 3, Pos_ and $07, $00 ) and $FFFF ) <> $FFFF then If ( GetPCIRegD( $00, Pos_ shr 3, Pos_ and $07, $08 ) shr 8 ) = $60100 then Break; If Pos_ = $FF then {v1.22 for i430MX} For Pos_ := 0 to $FF do If ( GetPCIRegD( $00, Pos_ shr 3, Pos_ and $07, $00 ) and $FFFF ) <> $FFFF then If ( GetPCIRegD( $00, Pos_ shr 3, Pos_ and $07, $08 ) shr 8 ) = $68000 then Break; If Pos_ = $FF then {v1.31 for old chipsets} For Pos_ := 0 to $FF do If ( GetPCIRegD( $00, Pos_ shr 3, Pos_ and $07, $00 ) and $FFFF ) <> $FFFF then If ( GetPCIRegD( $00, Pos_ shr 3, Pos_ and $07, $08 ) shr 8 ) = $00000 then Break; SouthPos := Pos_; {Get south bridge MID & DID} SouthMan := GetPCIRegD( $00, SouthPos shr 3, SouthPos and $07, $00 ); SouthID := GetPCIRegD( $00, SouthPos shr 3, SouthPos and $07, $00 ) shr 16; {Get south bridge rev ID} SouthRev := GetPCIRegD( $00, SouthPos shr 3, SouthPos and $07, $08 );
CurrentChipset := ''; NorthFunc := 0; {No special treatment necessary} SouthFunc := 0; {Same} LPCFunc := 0; {v1.27} NorthName:=''; SouthName:=''; LPCName:='';
Определяем имя и процедуры размапления (если она нужна) северника по его ревизии.
{Id northbridge} If NorthMan = $8086 {Intel} then Begin case NorthId of {case v1.21} $4A3: if NorthRev>=$10 then NorthName:='i82433NX' else NorthName:='i82433LX'; $122D: NorthName:='i82437FX'; $1235: NorthName:='i82437MX'; $1237: NorthName:='i82441FX'; $1250: NorthName:='i82439HX'; $7030: NorthName:='i82437VX'; $7100: NorthName:='i82439TX'; $7180: NorthName:='i82443LX/EX'; $7190, $7192: NorthName:='i82443BX/ZX'; $71A0, $71A2: NorthName:='i82443GX'; $84C4: NorthName:='i82454KX/GX'; $7120: NorthName:='i82810'; $7122: NorthName:='i82810-DC100'; $7124: NorthName:='i82810E'; $1130: NorthName:='i82815'; $2500: NorthName:='i82820'; $3575: NorthName:='i82830M'; $1A21: NorthName:='i82840'; $1A30: NorthName:='i82845'; $2560: NorthName:='i82845G/P'; $2530: NorthName:='i82850'; $3580: NorthName:='i8285xGM'; $3340: NorthName:='i82855PM'; $2531: NorthName:='i82860'; $2570: NorthName:='i82865'; {v1.34} $2578: NorthName:='i82875'; $255D: NorthName:='iE7205'; $2578: NorthName:='iE7210'; {v1.39} $2588: NorthName:='iE7221'; {v1.39} $3592: NorthName:='iE7320'; {v1.39} $2540: NorthName:='iE7500'; $254C: NorthName:='iE7501'; $2550: NorthName:='iE7505'; $3590: NorthName:='iE7520'; {v1.39} $359E: NorthName:='iE7525'; {v1.39} $0500: NorthName:='iE8870'; {v1.39} $2580: NorthName:='i829xxx'; {v1.37} $2590: NorthName:='i829xxxM'; {v1.39} End; End else
If NorthMan = $1106 {VIA} then Begin case NorthId of {case v1.21} $505: Begin {v1.37} NorthFunc := $0100; {VIA A8/A9 scheme} NorthName:='VT82C505'; End; $576: Begin NorthFunc := $0100; {VIA A8/A9 scheme} NorthName:='VT82C576M'; End; $585: NorthName:='VT82C585VP/VPX'; $595: NorthName:='VT82C595/AMD-640'; $597: NorthName:='VT82C597'; $598: NorthName:='VT82C598(AT)'; $685: Begin NorthFunc := $0100; {VIA A8/A9 scheme} NorthName:='VT82C685'; End; $501: NorthName:='VT8501'; $691: NorthName:='VT82C691/693(A)/694X/T'; $693: NorthName:='VT82C693(A)'; $601: NorthName:='VT8601'; $605: NorthName:='VT8605'; $391: NorthName:='VT8371'; $305: NorthName:='VT8363(A)/8365'; $3099: NorthName:='VT8366(A)'; $3091: NorthName:='VT8633'; $3101: NorthName:='VT8653'; $3102: NorthName:='VT8662'; $3103: NorthName:='VT8615'; $3112: NorthName:='VT8361'; $3133: NorthName:='VT3133'; $3148: NorthName:='VT8751'; $3128: NorthName:='VT8753(A)/8754'; $3189: NorthName:='VT8377'; $3205: NorthName:='VT8378'; End; End else
If NorthMan = $1022 {AMD} then {v1.20} Begin case NorthId of {case v1.21} $7006: NorthName:='AMD-751'; $700E: NorthName:='AMD-761'; $700C: NorthName:='AMD-762'; $7454: NorthName:='AMD-8151'; {v1.36} End; End else
If NorthMan = $1039 {SiS} then Begin SouthFunc:=$0503; {SiS reg. 45 bits 5,2} case NorthId of $496: Begin NorthFunc := $0200; {SiS reg. D0 scheme} SouthFunc := 0; NorthName:='SiS 85C496+497'; End; $406: Begin SouthFunc := $0501; {SiS internal reg. 80h} NorthName:='SiS 501/5101/5501'; End; $5511: Begin SouthFunc := $0502; {SiS internal reg. 50h} NorthName:='SiS 5511'; End; $5571: NorthName:='SiS 5571'; $5591: NorthName:='SiS 5591/5592'; $5596: Begin NorthName:='SiS 5596'; SouthFunc := $0502; {SiS internal reg. 50h} LPCFunc:=LPCDetect; {v1.27} End; $5597: NorthName:='SiS 5597/5598/5581/5120'; $0530: NorthName:='SiS 530'; $0540: Begin SouthFunc := $0504; {SiS reg. 45 bits 7,6} NorthName:='SiS 540'; End; $5600: NorthName:='SiS 600'; $0620: NorthName:='SiS 620'; $0630: Begin NorthName:='SiS 630'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; {v1.27} End; $0635: Begin NorthName:='SiS 635'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; End; $0640: Begin NorthName:='SiS 640'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; End; $0645: Begin NorthName:='SiS 645'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; End; $0646: Begin NorthName:='SiS 645DX'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; End; $0648: Begin {v1.31} NorthName:='SiS 648'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; End; $0650: Begin NorthName:='SiS 650'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; End; $0651: Begin {v1.31} NorthName:='SiS 651'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; End; $0655: Begin {v1.31} NorthName:='SiS 655'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; End; $0730: Begin NorthName:='SiS 730'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; End; $0733: Begin {v1.31} NorthName:='SiS 733'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; End; $0735: Begin NorthName:='SiS 735'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; End; $0740: Begin NorthName:='SiS 740'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; End; $0745: Begin {v1.31} NorthName:='SiS 745'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; End; $0746: Begin {v1.31} NorthName:='SiS 746'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; End; $0748: Begin {v1.31} NorthName:='SiS 748'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; End; $0755: Begin {v1.31} NorthName:='SiS 755'; SouthFunc := $0504; {SiS reg. 45 bits 7,6} LPCFunc:=LPCDetect; End; End; End else
If NorthMan = $10B9 {ALi} then Begin case NorthId of $1451: begin NorthFunc := $0300; {ALi Aladdin} NorthName:='M1451'; end; $1489: begin NorthFunc := $0301; {ALi FinALi} NorthName:='M1489'; end; $1521: NorthName:='M1521'; $1531: NorthName:='M1531(B)'; $1541: NorthName:='M1541/1542'; $1561: NorthName:='M1561'; {v1.31} $1621: NorthName:='M1621'; $1631: NorthName:='M1631'; $1632: NorthName:='M1632M'; $1641: NorthName:='M1641'; $1647: NorthName:='M1647'; $1651: NorthName:='M1651'; {v1.31} $1671: NorthName:='M1671'; {v1.31} $1672: NorthName:='M1672'; {v1.31} End; End else
If NorthMan = $1166 {Reliance/ServerWorks} then {v1.25} Begin case NorthId of $0007: NorthName:='Reliance NB6635'; $0008: NorthName:='Reliance NB6536'; End; End else
If NorthMan = $1066 {PicoPower} then {v1.25} Begin case NorthId of $0001: NorthName:='Vesuvius V1-LS'; End; End else
If NorthMan = $1078 {Cyrix} then {v1.25} Begin case NorthId of $0001: NorthName:='MediaGX'; End; End else
If NorthMan = $1045 {OPTi} then {v1.26} Begin case NorthId of $C557: NorthName:='OPTi 82C557(M)'; {v1.37} $C567: NorthName:='OPTi 82C567'; end; End else
If NorthMan = $3388 {HiNT} then {v1.26} Begin case NorthId of $8011: NorthName:='HiNT VXPro-II North'; end; End else
If NorthMan = $1060 {UMC} then {v1.28} Begin case NorthId of $8881: NorthName:='UMC UM8881F'; end; End else
If NorthMan = $1344 {Micron} then {v1.29} Begin case NorthId of $3320: NorthName:='Micron MT8LLN21PADF'; end; End else
If NorthMan = $1080 {Contaq/Cypress} then {v1.29} Begin case NorthId of $0600: begin {CY82C599} NorthFunc := $0400; NorthName:='CY82C599'; end; $C691: NorthName:='CY82C691'; end; End else
If NorthMan = $10DE {nVidia} then {v1.30} Begin case NorthId of $1A4: NorthName:='nVidia IGP'; $1E0: NorthName:='nVidia IGP2'; $D1: NorthName:='nVidia nForce3 Host Bridge'; {v1.41re} $E1: NorthName:='nVidia nForce3 250Gb Host Bridge'; {v1.41re} end; End else
If NorthMan = $1002 {ATI} then {v1.46re} Begin case NorthId of ... тут может быть ваш чипсет ... end; End;
apple_rom - Подскажи пожалуйста, "поделиться айдишниками вашего железа" - через что его смотреть и какие параметры нужны? Думаю что что то получится найти.
По "UMC UM8886AF/UM8881F - это чипсет для 486 процов" типа пример: ZIDA TD-4IP-UMC-AIO UM8881F/UM8886BF SOCKET 3 (486-586).
... дорогу осилит идущий, если есть верный друг, отличный конь, толковый мудрец и цель...
За название респект run I flash - беги и шей(если криво перевести I)
Я хоть и не отношёсь к "знающим" но помочь могу. Вобщем чем смотреть айдишники?
Unknown Flash Type
P.S. apple_rom , спасибо что начал эту тему, прошивальщик мощный и хотелось бы чтобы он жил... =D>
... дорогу осилит идущий, если есть верный друг, отличный конь, толковый мудрец и цель...
Смотреть можно чем угодно, даже в свойствах винды (Пуск->Настройка->Панель управления->Свойства системы->Диспетчер устройств->Системные устройства->Свойства ХХХ-чипсет (ваш) CPU - PCI мост->Сведения->Коды (ID) оборудования->строчка PCI\VEN_xxxx&DEV_yyyy&REV_zz - эти XXXX|YYYY|ZZ и нужны). Хотя есть куча других способов, я лично всегда пользуюсь стареньким wpcredit).
По этому "уникуму" с ходу и не скажу - позже, может чего вспомню или кто подскажет сам.
По сему поводу имеется такое:
HiNT HB1 Zero-Clock-Latency PCI-PCI Bridge
Preliminary Data sheet, Rev 1.1, Aug 4, 1999
Достоверно известна одна-единственная плата PCChips на этом чипсете, поэтому, если о нем забыть, то ровным счетом ничего не произойдет...
Открытая книга: icbook.com.ua
Продолжим. Дальше идет детект южников. Смысл последовательности понятен - детектируем само железо, чтобы знать как "добраться" ("размапить") до флэшки.
Для старых ("нехабовых") южников назначаем первую процедуру, хабовым - вторую. Начиная с ICH6 (приходом PCIe) процедура размапливания изменилась, потому им даем 17-ую процедуру.
Здесь и дальше номера берутся из самого унифлеша, стиль не изменяется, даже если он имеет "неоптимизированный ("кривой" ) вид. В том числе и изменения, типа:
if Hi(SouthId)=$27 then SouthFunc := $1700; {v1.46re}
if Hi(SouthId)=$28 then SouthFunc := $1700; {v1.46re}
... продолжают такой "неуклюжий" код, чтобы проще были видны изменения.
В частности, не изменились ли процедуры размапления в добавленных 7 и 8-м ICH я еще не смотрел - разберемся вместе по ходу.
Виашке назначаем 3-ю функцию. С приходом Vlink (первые DDR-платы) изменилась процедура - даем 10-ю подфункцию.
Подтверждение ранее сказанного о процессе разработок небогатой коллекции чипсетов АМД, которые "вытекали" из продуктов от VIA. Идентичные процедуры размапливания (та же 3-я функция) лишнее подтверждение тому.
Внимательный читатель заметит - у сисов нет назначенных функций для южных мостов. Сначала это может показаться странным, но если вспомнить, что в первое время своей деятельности южники не были в почете (известный упор на одночиповые решения), потому и все нужные процедуры были перененены в вышеописанные процедуры размапливания для северников (т.е. см. выше SiS и станет понятно).
Алишкам - 4-ю функцию.
Далее идет экзотика. Шестая функция...
Седьмая...
Восьмая...
Девятая...
Десятая...
Одиннадцатая...
Тоже одиннадцатая. Кто застал-видел Сайриксы (цыриксы, куриксы и куча других словообразований ) - поймут, почему. Все просто - один другого купили.
Продолжение экзотики - двенадцать...
Тринадцать...
Четырнадцать...
Настолько древнее, что даже функции не досталось.
Пятнадцать.
У нВидии - шестнадцатая. В 1.40 для нее не было подфункций, что не есть правильно, ибо размапливание с nForce2 изменилось (потому в моих версиях сделано разделение на первую для nForce(1) и вторую для остальных).
Мне, честно говоря, не до конца понятно, даже почему работает для первого nForce, т.к. размапливание делается не совсем точно "как надо", но для всех случае, что лично сталкивался - оно четко срабатывает. Потому по закону программизма и не стал "трогать то, что работает".
В будущем посмотрим и внесем добавления по пятому нФорсу.
Так же в будущем добавим раздел для атишек.
apple_rom, к сожалению, виндовс уже давно не пользуюсь.
Гм. lspci вот что выводит на примере моего i865PE:
(только интересные строчки)
00:00.0 Host bridge: Intel Corporation 82865G/PE/P DRAM Controller/Host-Hub Interface (rev 02)
00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev c2)
00:1f.0 ISA bridge: Intel Corporation 82801EB/ER (ICH5/ICH5R) LPC Interface Bridge (rev 02)
00:1f.3 SMBus: Intel Corporation 82801EB/ER (ICH5/ICH5R) SMBus Controller (rev 02)
Что тут надо?
Затем делаю lspci -n (опция показа численных id'ов)
00:00.0 Class 0600: 8086:2570 (rev 02)
00:1e.0 Class 0604: 8086:244e (rev c2)
00:1f.0 Class 0601: 8086:24d0 (rev 02)
00:1f.3 Class 0c05: 8086:24d3 (rev 02)
И ещё бы хорошо было, если бы посоветовали утилитку для доса.
Unknown Flash Type
Далее идет кусок не относящийся конкретно к прошивке, но он имеет важное значение в определении самого "чипсетного набора", как практической функции идентификации неизвестных плат, потому несмотря на его объемность последовательно пройдемся по всем пунктам.
Все достаточно понятно, опять же, уточнения приветствуются. И дополнения - по новым наборам, чтобы внести в нашу новую версию.
Аналогично - ищем новое, уточняем старое.
Тут - только уточняем старое, в виду отсутствия нового.
Снова - аналогично.
Сис - он и в африке сис. Простой как шланг - при желании можно даже написать одну общую процедуру для всех названий, теперешних и будущих.
Одним словом - экзотика и артефакты.
А вот эту часть нужно дописать.
И написать - для атишек.
Просто для отображения названия чипсетной логики - если иденцифицирован хотя бы один из мостов - выводим его название, иначе - выводим их айдишники. Плюс вывод названия мультика в случае его наличия-определения.
Определения типа биоса, что в будущем позволяет выбрать способ "размапливания" - "классический" (универсальный), который мы здесь и рассматриваем. Или специальная процедура из конкретного биоса под свою плату. Чтобы не уходить от темы пока опустим "неклассический" вариант, подразумевая именно универсальный способ.
Для знающих аварбиос все просто - получаем его BIOSID.
Запуск самой процедуры "размапливания". Ну и, как видно, "замапливания" перед выходом.
Возможности и варианты для "биос-специфичных" вариантов (неуниверсальных) пока по-прежнему не рассматриваем.
Далее идет наш главный код по размапливанию.
Добавлено спустя 7 минут 54 секунды:
Gordon01 и др.
Интересуют "реально" новые платы. Для интелов, это "минимум" с ICH6 (а лучше 7), для nVidia - от nForce4, АТИшки интересуют все, сисы от 76х и т.п. - смотреть самые последние строчки в соответствующих вашему железу разделах (которые здесь в сообщениях я писал), если ваше железо там есть, интересно лишь, ежели ваши данные отличаются от указанных в юнифлеше.
Добавлено спустя 53 минуты 22 секунды:
Сначала идет код, "специфичный" для северников.
Здесь, видимо, стоит уточнить. В реальном коде (как это сделано в биосе) нет "отдельных" процедур - для северника, южника и т.д. Ибо это и бессмысленно делить в коде и даже некорректно где-то по определению. Но для написания именно _универсального_ прошивальщика нужно было "стандартизировать" подход размапливания и "классифицировать" его для всего многообразия "защиты от записи". Потому авторы юнифлеша, думаю, совершенно оправданно его так поделили (NB/SB/SIO/GPIO). И, в частности, именно поддержка совсем древнего железа потребовала "специфичных" для северника процедур размапливания. Потому и указанную "северную" часть стоит рассматривать лишь с точки зрения "было же время"...
Итак, первая функция для северника - для артефактных виашек. Если сейчас размапливаем (Map = TRUE), то в порт 0A8h закидываем 11h, после чего считываем байт управления (скорей всего - если захотите убедиться - сами поищите и почитайте эти древние папирусы по инициализиции подобного железа ) и после устанавливаем в нем бит, ответственный за ROM_WE (Write Enable).
иначе (процедура замапливания - Map = TRUE):
В байт управления загоняем ранее предварительно сохраненное в PIIXReg предыдущее состояние (что было до размапливания).
Думая понятно, но замечу - здесь и далее PIIXReg (и аналогичные) - просто банальные переменные для временного хранения.
Теперь для артефактных сисов.
***************************************************************
Здесь стоит подробней остановится на постоянно используемых функциях GetPCIRegD/SetPCIRegD.
Без четкого понимания механизма программирования PCI понять это невозможно. Сам алгоритм несложный, описание можно найти, например, здесь:
support.mdl.ru/PC_COMPL/doc/IndespPC.Bok/chapt24/chapt24.6.html
support.mdl.ru/PC_COMPL/doc/IndespPC.Bok/chapt24/chapt24.7.html
***************************************************************
Так вот, для сисов нужно установить разрешающие биты в RxD0 (что читается как регистр PCI по смещению 0D0h в конфигурационном пространстве северного моста в нашем случае). При "замапливании" - их (биты) нужно сбросить (установить в 0).
Много непонятного и сложного для восприятия в случае старых алишек. Пропускаю этот момент, ибо, честно говоря - нет никакого желания разбираться. Хоть и буду признателен, ежели кто объяснит смысл такой "хитровывернутой" инициализации.Сходное с виашной раз северников у экзотичного "контака".
Далее идет "специфичные" процедуры для южников - основной смысл нашего разбора, потому на каждой будем останавливаться максимально подробно.
по поводу PCI ID:
pciids.sourceforge.net/
members.datafast.net.au/~dft0802/downloads/pcidevs.txt
в этих ресурсах уже есть такой "свежак" как NF4
Аццкий ромбовод {:€
Я пока не волшебник - я только учусь! :-P
Все эти ссылки (точней - много больше) у меня есть. Потому просьба не "понтоваться" ссылками, а указать конкретные ID.
А еще лучше - прямо написать код (на паскале), чтобы соблюсти взятый стиль изложения (и мне легче будет ).
п.с. Думаю, после первых же попыток решить это "простую" задачу (найти PCI ID, особенно с учетом их разных значений и названий в разных источниках) станет понятно, почему я попросил "помощи клуба".
Добавлено спустя 2 часа 36 минут 37 секунд:
Итак, главная часть - размапливание южников.
Итак, подробненько разберем, чего здесь понаписано.
Код реально шибко неудобный, но мы решили от него отталкиваться, потому и на будущее не будем возмущаться и предлагать все переписать, а просто "переведем на нормальный".
Одна из главных неудобностей следующая.
Например, у нас в коде фигурирует Rx4C. И если мы глянем даташит на старенькие нехабовые южники (например, PIIX4 от i430TX/i440LX), как известно, флешка "сидит" на функции "PCI to ISA Bridge", в которой регистр 4С
обозначает "IORT—ISA I/O RECOVERY TIMER REGISTER" --- в результате мы долго будем чесать тыковку, каким боком он тут затесался.
А ларчик открывается просто - нужно учитывать факт работы юнифлешных функций с 32-битными данными для общения по PCI. В результате, если обратить внимание, то видно, что в маске идет работа только с двумя старшими байтами. С учетом 32-битных обращений 00440000h обозначает работу с регистром 4С плюс два байта (пропускаем два младших, что не используются - к ним всегда операция "OR 0"): 4Ch + 2 = 4Eh и 4Dh. Смотрим в даташите:
Rx 4E-4F: X-BUS CHIP SELECT REGISTER (FUNCTION 0)
This register enables or disables accesses to an external RTC, keyboard controller, I/O APIC, a secondary controller, and BIOS. Disabling any of these bits prevents the device’s chip select and X-Bus output enable control signal (XOE#) from being generated. This register also provides coprocessor error and mouse functions.
То что нам и нужно. Потому размапливание для нехабовых интелов осуществляется работой с этими двумя регистрами (Rx4E и Rx4F), устанавливая биты:
bit 2: BIOSCS# Write Protect Enable (от маски 00440000), при установке в 1 снимается защита от записи.
bit 6: Lower BIOS Enable. (от маски 00440000), при установке в 1 разрешается доступ к 1Мбитным биосам (объем флэши = 1Мбит = 128кБайт).
bit 7: Extended BIOS Enable. (от Mask or $800000;), при установке в 1 разрешается доступ к 2-4Мбитным биосам (объем флэши = 2Мбит и 4Мбит = 256кБайт и 512кБайт).
bit 9: 1-Meg Extended BIOS Enable. (от Mask or $С00000;), при установке в 1 разрешается доступ к 8Мбитным биосам (объем флэши = 8Мбит = 1МБайт).
Это и есть характерный показатель, в нем и заключается главный момент "размапливания" флэшки, а значит и основа для ее корректной прошивки - найти нужные битики, которые отвечают за подобные характерные области адресов - доступ к "верхнему" (а значит - флэшка) мегабиту, двум, четырем, восьми (в самых новых - шестнадцати и больше). После этого (установки данных битов) при обращении по ним (адресам) мы будем иметь дело именно с флэшкой и дальше уже нужно будет, используя специфичные для разных флэшей команды, осуществить ее детект/чтение/запись.
Отправить комментарий