| ||||||
SETUPSECTS = 4 /*varsayılan kurulum sektörü sayısı*/
BOOTSEG = 0x07C0 /*önyükleme sektörünün orjinal adresi*/
INITSEG = DEF_INITSEG (0x9000) /*önyüklemeyi buraya taşıyoruz;yolun dışına*/
SETUPSEG = DEF_SETUPSEG (0x9020) /*kurulum buradan başlar*/
SYSSEG = DEF_SYSSEG (0x1000) /*sistem 0x10000 (65536) adresine yüklendi*/
SYSSIZE = DEF_SYSSIZE (0x7F00) /*sistem boyutu: 16-bayt sayısı*/
/*yüklenecek*/
ROOT_DEV = 0 /*ROOT_DEV şimdi "build" tarafından yazıldı*/
SWAP_DEV = 0 /*SWAP_DEV şimdi "build" tarafından yazıldı*/
.code16
.text
///////////////////////////////////////////////////////////////////////////////
_start:
{
// kendimizi 0x7C00'den 0x90000'e taşıdık ve oraya sıçradık.
move BOOTSEG:0 to INITSEG:0 (512 bytes);
goto INITSEG:go;
}
///////////////////////////////////////////////////////////////////////////////
// yığıtı ve disk parametre tablosunu hazırla
go:
{
SS:SP = INITSEG:3FF4; // yığıtı INITSEG:0x4000-12'ye koy
/* 0x4000 keyfi bir değerdir >=
* bootsect boyutu + setup boyutu + yığıt için oda;
* 12 disk parametre boyutudur. */
disk parametresini (0:0078'deki gösterici) \
INITSEG:3FF4 adresine kopyala (12 bytes);
// int1E: SYSTEM DATA - DISKETTE PARAMETERS
yama sektör sayısı 36'ya (parametre tablosunda 4. konum, 1 byte);
disk parametre tablosu göstericisine (0:0078, int1E) INITSEG:3FF4 ata;
}
///////////////////////////////////////////////////////////////////////////////
// disk sürücü parametrelerini al, özellikle sektör/iz sayısı.
char disksizes[] = {36, 18, 15, 9};
int sectors;
{
SI = disksizes; // i = 0;
do {
probe_loop:
sectors = DS:[SI++]; // sectors = disksizes[i++];
if (SI>=disksizes+4) break; // if (i>=4) break;
int13/AH=02h(AL=1, ES:BX=INITSEG:0200, CX=sectors, DX=0);
// int13/AH=02h: DISK - READ SECTOR(S) INTO MEMORY
} while (sektör okuma hatası);
}
///////////////////////////////////////////////////////////////////////////////
got_sectors:
word sread; // geçerli iz için sektörlerin okunması
char setup_sects; // tools/build tarafından üzerine yazılmış
{
print out "Loading";
/* int10/AH=03h(BH=0): VIDEO - İMLEÇ KONUMUNU VE BOYUTUNU AL
* int10/AH=13h(AL=1, BH=0, BL=7, CX=9, DH=DL=0, ES:BP=INITSEG:$msg1):
* VIDEO - DİZGEYİ YAZ */
// kurulum-sektörlerini taşınan (0x90200 adresine) önyükleme bloğundan
// (bootblock) sonra doğrudan yükle.
SI = &sread; // sread, head ve track indekslemek için SI kullanımı
sread = 1; // önyükleme sektörü okundu
int13/AH=00h(DL=0); // reset FDC
BX = 0x0200; // bsetup'ı bbootsect'den (512 bytes) hemen sonra oku
do {
next_step:
/* silindir çapraz okumayı (cylinder crossing reading) engellemek için,
* bu sefer kaç tane sektörün oknacağını hesapla */
uint16 pushw_ax = AX = MIN(sectors-sread, setup_sects);
no_cyl_crossing:
read_track(AL, ES:BX); // AX değiştirilmez
// ES:BX, sread, head and track'e read_track()için değer ata
set_next(AX);
setup_sects -= pushw_ax; // kalanlar - sonraki adım
} while (setup_sects);
}
///////////////////////////////////////////////////////////////////////////////
// vmlinux/bvmlinux'u yükle (head.o, misc.o, piggy.o)
{
read_it(ES=SYSSEG);
kill_motor(); // disket sürücü motorunu kapat
print_nl(); // CR LF yazar
}
///////////////////////////////////////////////////////////////////////////////
// hangi kök aygıtın kullanılacağına bak ve setup.S'e sıçra
int root_dev; // tools/build tarafından üzerine yazılır
{
if (!root_dev) {
switch (sectors) {
case 15: root_dev = 0x0208; // /dev/ps0 - 1.2Mb
break;
case 18: root_dev = 0x021C; // /dev/PS0 - 1.44Mb
break;
case 36: root_dev = 0x0220; // /dev/fd0H2880 - 2.88Mb
break;
default: root_dev = 0x0200; // /dev/fd0 - auto detect
break;
}
}
// önyükleme bloğundan sonra doğrudan yüklenen ayar yordamına sıçra
goto SETUPSEG:0;
}
sread: .word 0 # geçerli iz'in (track) sektör okuması
head: .word 0 # geçerli kafa
track: .word 0 # geçerli iz
///////////////////////////////////////////////////////////////////////////////
// load the system image at address SYSSEG:0
read_it(ES=SYSSEG)
int syssize; /* 16-bayt türünden sistem boyutu
* tools/build tarafından üzerine yazıldı */
{
if (ES & 0x0fff) die; // hizalama 64KB değil
BX = 0;
for (;;) {
rp_read:
#ifdef __BIG_KERNEL__
bootsect_helper(ES:BX);
/* INITSEG:0220==SETUPSEG:0020 - bootsect_kludge,
* SETUPSEG:bootsect_helper() gösterici içerir.
* Bu işlev bazı veriyapılarını başlangıç durumuna getirir
* ilk sefer çağırımda,
* ve SYSSEG:0'dan 0x100000'a taşır, her seferinde 64KB,
* aşağıdaki çağırımda.
* Bakınız Bootsect Yardımcısı. */
#else
AX = ES - SYSSEG + ( BX >> 4); // kaç tane 16-bayt okuma
#endif
if (AX > syssize) return; // herşey yüklendi
ok1_read:
/* bu sefer uygun AL (okunacak sektörler) al
* çapraz silindir okumasını ve BX taşmasını önlemek için. */
AX = sectors - sread;
CX = BX + (AX << 9); // 1 sector = 2^9 bytes
if (CX overflow && CX!=0) { // > 64KB
AX = (-BX) >> 9;
}
ok2_read:
read_track(AL, ES:BX);
set_next(AX);
}
}
///////////////////////////////////////////////////////////////////////////////
// diski parametrelerle oku (sread, track, head)
read_track(AL sektörler, ES:BX hedef)
{
for (;;) {
printf(".");
// int10/AH=0Eh: VIDEO - TELETYPE ÇIKTI
// sread, track, head) değerlerine göre CX, DX değerlerini ata
DX = track;
CX = sread + 1;
CH = DL;
DX = head;
DH = DL;
DX &= 0x0100;
int13/AH=02h(AL, ES:BX, CX, DX);
// int13/AH=02h: DISK - SEKTÖRLERİ BELLEĞE OKU
if (disk okuma başarılı) return;
// "addw $8, %sp" önceki 4 "pushw" işlemini iptal etmek için.
bad_rt:
print_all(); // yazma hata kodu, AX, BX, CX ve DX
int13/AH=00h(DL=0); // reset FDC
}
}
///////////////////////////////////////////////////////////////////////////////
// set ES:BX, sread, head and track for next read_track()
set_next(AX sectors_read)
{
CX = AX; // sektörleri oku
AX += sread;
if (AX==sectors) {
head = 1 ^ head; // head'i 0 ve 1 arasında değiştir
if (head==0) track++;
ok4_set:
AX = 0;
}
ok3_set:
sread = AX;
BX += CX && 9;
if (BX overflow) { // > 64KB
ES += 0x1000;
BX = 0;
}
set_next_fn:
}
///////////////////////////////////////////////////////////////////////////////
// bzImage yüklendiğinde bootsect yükleyici tarafından çağırılır
bootsect_helper(ES:BX)
bootsect_es = 0; // setup.S içinde tanımlı
type_of_loader = 0; // setup.S içinde tanımlı
{
if (!bootsect_es) { // ilk sefer için çağırılır
type_of_loader = 0x20; // bootsect-yükleyici, version 0
AX = ES >> 4;
*(byte*)(&bootsect_src_base+2) = AH;
bootsect_es = ES;
AX = ES - SYSSEG;
return;
}
bootsect_second:
if (!BX) { // 64KB full
// SYSSEG:0'dan hedefe taşı, her seferinde 64KB
int15/AH=87h(CX=0x8000, ES:SI=CS:bootsect_gdt);
// int15/AH=87h: SİSTEM - GENİŞLETİLMİŞ BELLEĞE KOPYALA
if (kopyalama hatası) {
bootsect_panic() {
prtstr("INT15 refuses to access high mem, giving up.");
bootsect_panic_loop: goto bootsect_panic_loop; // never return
}
}
ES = bootsect_es; // ES'i daima 0x10000 noktasına ata
*(byte*)(&bootsect_dst_base+2)++;
}
bootsect_ex:
// AX içindeki taşınmış çerçeveler (16-bayt)
AH = *(byte*)(&bootsect_dst_base+2) << 4;
AL = 0;
}
///////////////////////////////////////////////////////////////////////////////
// data used by bootsect_helper()
bootsect_gdt:
.word 0, 0, 0, 0
.word 0, 0, 0, 0
bootsect_src:
.word 0xffff
bootsect_src_base:
.byte 0x00, 0x00, 0x01 # base = 0x010000
.byte 0x93 # typbyte
.word 0 # limit16,base24 =0
bootsect_dst:
.word 0xffff
bootsect_dst_base:
.byte 0x00, 0x00, 0x10 # base = 0x100000
.byte 0x93 # typbyte
.word 0 # limit16,base24 =0
.word 0, 0, 0, 0 # BIOS CS
.word 0, 0, 0, 0 # BIOS DS
bootsect_es:
.word 0
bootsect_panic_mess:
.string "INT15 refuses to access high mem, giving up."
///////////////////////////////////////////////////////////////////////////////
// bazı küçük işlevler
print_all(); /* hata kodu yaz, AX, BX, CX and DX */
print_nl(); /* CR LF yaz*/
print_hex(); /* SS:BP tarafından gösterilen kelimeyi onaltılık olarak yaz*/
kill_motor() /* disket sürücü motorunu kapat */
{
#if 1
int13/AH=00h(DL=0); // reset FDC
#else
outb(0, 0x3F2); // outb(val, port)
#endif
}
///////////////////////////////////////////////////////////////////////////////
sectors: .word 0
disksizes: .byte 36, 18, 15, 9
msg1: .byte 13, 10
.ascii "Loading"
.org 497 setup_sects: .byte SETUPSECS // tools/build tarafından üzerine yazılır root_flags: .word ROOT_RDONLY syssize: .word SYSSIZE // tools/build tarafından üzerine yazılır swap_dev: .word SWAP_DEV ram_size: .word RAMDISK vid_mode: .word SVGA_MODE root_dev: .word ROOT_DEV // tools/build tarafından üzerine yazılır boot_flag: .word 0xAA55
Konum Proto İsim Anlam /Boyut 01F1/1 ALL setup_sects setup'ın sektör cinsinden boyutu 01F2/2 ALL root_flags Sıfırdan farklı ise, kök dizin salt okunur olarak bağlanır 01F4/2 ALL syssize KULLANMAYIN - sadece bootsect.S kullanımı için 01F6/2 ALL swap_dev KULLANMAYIN - atıl oldu 01F8/2 ALL ram_size KULLANMAYIN - sadece bootsect.S kullanımı için 01FA/2 ALL vid_mode Video kip kontrolü 01FC/2 ALL root_dev Varsayılan kök aygıt sayısı 01FE/2 ALL boot_flag 0xAA55 sihirli numara
| |||||||||