|
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
|