BlackFullMoon 1
BlackFullMoon
Mt2Hizmet 1
Mt2Hizmet
mavzermete 1
mavzermete
Vahsi Uzman 1
Vahsi Uzman
kralhakan2009 1
kralhakan2009
Hikaye Ekle

linux/arch/i386/boot/bootsect.S

  • Konuyu başlatan Konuyu başlatan badie
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 0
  • Görüntüleme Görüntüleme 277

Ayyıldız2 | 2008 TR Yapısı • 1-99 Orta Emek Destan • Oto Avsız • 10 Temmuz 21:00 HEMEN TIKLA!

Verildiği gibi bbootsect, bsetup ve bvmlinux'dan oluşan (head.o, misc.o, piggy.o),bzImage'ı yüklüyoruz. İlk floppy sektörü, bbootsect (512 bytes) linux/arch/i386/boot/bootsect.S'dan derlenmiştir. BIOS tarafından 07C0:0'a yüklenir. bzImage'ın sıfırlaması (bsetup ve bvmlinux) henüz yüklenmiş değildir.
Bootsect'i Taşı

SETUPSECTS = 4 /*vars***lan kurulum sektörü s***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 s***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;}

bbootsect INITSEG:0 (0x9000:0)'a taşınmıştır. Artık BOOTSEG'i unutabiliriz.
Disk parametrelerini Al

///////////////////////////////////////////////////////////////////////////////// yığıtı ve disk parametre tablosunu hazırlago:{ 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 s***sı 36'ya (parametre tablosunda 4. konum, 1 byte); disk parametre tablosu göstericisine (0:0078, int1E) INITSEG:3FF4 ata;}

SS kaydedicisinden hemen sonra SP'nin başlatıldığından emin olun. SS'nin tavsiye edilen değişiklik yöntemi lss komutunu kullanmaktır (IA-32 Intel Architecture Software Developer's Manual, (Vol.3. Ch.5.8.3. Masking Exceptions and Interrupts When Switching Stacks).
İtme ve çekme gibi yığıt işlemleri artık kabul edilebilir. Önce disk parametrelerinin 12 byte'ı INITSEG:3FF4'e kopyalanmıştı.
///////////////////////////////////////////////////////////////////////////////// disk sürücü parametrelerini al, özellikle sektör/iz s***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ı);}

"lodsb" DS:[SI]'dan AL'ye baytları yükler ve SI'yı otomatik olarak arttırır.
İz başına düşen sektör s***sı sectors değişkenine kaydedilir.
Kurulum Kodunu Yükle
bsetup (setup_sects sektörü) bbotsect'den hemen sonra yüklenecektir, örn. SETUPSEG:0. Dikkat ederseniz INITSEG:0200==SETUPSEG:0 ve setup_sects tools/build tarafından bsetup boyutunun linux/arch/i386/tools/build.c'dekiyle eşleşmesi için değiştirilmiştir.

///////////////////////////////////////////////////////////////////////////////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 okum*** (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);}

SI sread, head ve track değişkenlerini indekslemek için sread adresine atanmıştır. Onlar bellekte art arda bulunur. read_track() ve set_next() yöntemlerinin ayrıntıları için bakınız Diski Oku
Sıkıştırılmış İmgeyi Yükle
bvmlinux (head.o, misc.o, piggy.o) 0x100000 adresine yüklenecektir, syssize*16 bayt.

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

read_it() ayrıntıları için bakınız Diski Oku. Eğer zImage'ı yüklüyorsak, vmlinux 0x10000 (SYSSEG:0) adresine yüklenir.
bzImage (bbootsect, bsetup, bvmlinux) artık tümüyle bellekte bulunuyor.
Ayarlara Git

///////////////////////////////////////////////////////////////////////////////// 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;}

Denetimi bsetup'a geçirir. linux/arch/i386/boot/setup.S bölümündeki linux/arch/i386/boot/setup.S:start'a bakınız.
Diski Oku
Aşağıdaki işlev bsetup ve bvmlinux'u diskten yüklemek için kullanılır. Dikkat ederseniz syssize linux/arch/i386/tools/build.c içindeki tools/build tarafından değiştirilmiştir.

sread: .word 0 # geçerli iz'in (track) sektör okumasıhead: .word 0 # geçerli kafatrack: .word 0 # geçerli iz///////////////////////////////////////////////////////////////////////////////// load the system image at address SYSSEG:0read_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üklendiok1_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:}

Bootsect Yardımcısı
setup.S:bootsect_helper() sadece bootsect.S:read_it() tarafından kullanılır.
bbootsect ve bsetup yarı ayrı bağlandıkları için kendi kod/veri bölütlerine bağlı konumlar kullanırlar. Değişik bölütlerde bootsect_helper() için "call far" (lcall) çağırmak zorund***z ve "return far" dönmeli. Bu çağırma, CS!=DS durumunu yaratan CS değişikliği ile sonuçlanır ve setup.S içindeki değişkenleri belirtmek için bölütü niteleyici kullanmak zorund***z.

///////////////////////////////////////////////////////////////////////////////// bzImage yüklendiğinde bootsect yükleyici tarafından çağırılırbootsect_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, 0bootsect_src: .word 0xffffbootsect_src_base: .byte 0x00, 0x00, 0x01 # base = 0x010000 .byte 0x93 # typbyte .word 0 # limit16,base24 =0bootsect_dst: .word 0xffffbootsect_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 DSbootsect_es: .word 0bootsect_panic_mess: .string "INT15 refuses to access high mem, giving up."

type_of_loader değerinin değiştiğine dikkat edin. Bu konu Yükleyici Türünü Kontrol Et bölümünde açıklanmıştır.
Muhtelif
Kalanlar destek işlevleridir; değişkenler ve "gerçek kip çekirdek başlığı" parçaları. Dikkat ederseniz .text bölütündeki veri kod olarak bulunur, böylece yüklendiğinde uygun bir şekilde başlangıç durumuna getirilebilir.

///////////////////////////////////////////////////////////////////////////////// bazı küçük işlevlerprint_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 0disksizes: .byte 36, 18, 15, 9msg1: .byte 13, 10 .ascii "Loading"

"gerçek kip çekirdek başlığı"nın bir parçası olan bootsect taşıyıcı 497. konumdan başlar.

.org 497setup_sects: .byte SETUPSECS // tools/build tarafından üzerine yazılırroot_flags: .word ROOT_RDONLYsyssize: .word SYSSIZE // tools/build tarafından üzerine yazılırswap_dev: .word SWAP_DEVram_size: .word RAMDISKvid_mode: .word SVGA_MODEroot_dev: .word ROOT_DEV // tools/build tarafından üzerine yazılırboot_flag: .word 0xAA55

Bu "başlık" linux/Documentation/i386/boot.txt içindeki yerleşim örneğiyle uyuş***ıdır.
Konum Proto İsim Anlam/Boyut01F1/1 ALL setup_sects setup'ın sektör cinsinden boyutu01F2/2 ALL root_flags Sıfırdan farklı ise, kök dizin salt okunur olarak bağlanır01F4/2 ALL syssize KULLANMAYIN - sadece bootsect.S kullanımı için01F6/2 ALL swap_dev KULLANMAYIN - atıl oldu01F8/2 ALL ram_size KULLANMAYIN - sadece bootsect.S kullanımı için01FA/2 ALL vid_mode Video kip kontrolü01FC/2 ALL root_dev Vars***lan kök aygıt s***sı01FE/2 ALL boot_flag 0xAA55 sihirli numara
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst