Normal kullanıcıların yönetici haklarına sahip bir uygulamayı çalıştırmasını sağlayan bir kısayol nasıl oluşturulur. UAC'yi devre dışı bırakmadan Windows'ta uygulamaları yönetici olarak çalıştırmayı kolaylaştırma

Ya bir programı çalıştırmanız gerekiyorsa ancak yüklemek istemiyorsanız? Kurtarmak için Sıfır Kurulum!

Dünya çapında milyarlarca insan bilgisayar veya dizüstü bilgisayar kullanıyor. işletim sistemi Pencereler. Genellikle programları yükleriz, ardından boş disk alanı kaplar ve kullanırlar. Veri deposu... Bu, bilgisayarın hızını yavaşlatır.

Bugün size bilgisayarınızın performansını nasıl artırabileceğinizi ve bellek yükünü nasıl azaltabileceğinizi göstereceğiz. Bunu yapmak için, gerekli programları yüklemeden çalıştırmanız gerekir.

Program kurulum olmadan nasıl çalıştırılır?

1. Zero Install'u indirin.

Öncelikle, programları bilgisayarınıza kurmanıza gerek kalmadan çalıştırmanızı sağlayacak Zero Install yazılımını indirin.

2. Sıfır Kurulumu kurun.

Zero Install'u indirdikten sonra, yüklemek için dosyaya çift tıklayın. O zaman koş yeni program bilgisayarınızda.

3. tıklayın"Katalog" duvarcılık.

Bilgisayarda Zero Install başlatılır başlatılmaz veya Windows dizüstü bilgisayar, "Katalog" sekmesine gitmelisiniz. Burada mevcut programların listesini güncellemek için "Listeyi yenile" düğmesine tıklayın.

4. Çalıştırmak için bir program seçin.

İyice bak tam liste mevcut programlar. İhtiyacınız olan programı bulursanız, seçin ve "Çalıştır" ı tıklayın. Bazı programlar seçebilir Firefox tarayıcısı veya çalıştırmak için Mozilla. Tamamen yüklenene kadar bekleyin yazılım, bundan sonra yüklemeden bilgisayarınızda çalıştırabilirsiniz.


Özetleme

Bilgisayarınızda programı çalıştırmak için yeterli boş bellek veya güç yoksa Sıfır Kurulum kullanabilirsiniz. Bence bu, bilgisayarınızı aynı anda ihtiyaç duyduğunuz programlarla karıştırmaktan kaçınmanın harika bir yolu.

Ayrıca bilgisayarınızda Eclipse IDE, JetBrains, NetBeans vb. gibi belirli programları çalıştırmak için yeterli güç olmayabilir. Bunlar, tüketen gerçekten ağır geliştirici programlarıdır. çok sayıda rasgele erişim belleği.

Sıfır Kurulum, bunları ve diğer birçok programı bilgisayarınıza kurmadan çalıştırmanıza yardımcı olacaktır.

En önemli şey yeterince ayrıntılı anlatılmamış: Bu kod gerçek donanımda nasıl çalıştırılır? Kendiniz nasıl oluşturulur önyükleme diski? Bu makalede, tüm bu soruları ayrıntılı olarak cevaplayacağız (bu soruların bir kısmı önceki makalede ele alındı, ancak okuma kolaylığı için kendimize materyalin biraz tekrarlanmasına izin vereceğiz).

İnternette kendi mini işletim sisteminizi nasıl yazacağınızla ilgili çok sayıda açıklama ve eğitim var, hatta yüzlerce hazır küçük hobi işletim sistemi var. Bu konuda altını çizmek istediğim en değerli kaynaklardan biri de osdev.org portalıdır. PCI ile ilgili önceki makaleyi (ve herhangi bir modern işletim sisteminde bulunan çeşitli işlevler hakkında sonraki makaleleri yazma yeteneği) tamamlamak için açıklayacağız. adım adım talimatlar C dilinde tanıdık bir programla önyüklenebilir bir disk oluşturma hakkında Her şeyi kendi başınıza çözebilmeniz için mümkün olduğunca fazla ayrıntı yazmaya çalıştık.

Yani amaç: mümkün olduğunca az çaba harcayarak, kendinizinkini yaratın önyüklenebilir USB sürücü, bu sadece klasik "Merhaba Dünya" yı bilgisayar ekranına yazdırır.

Daha kesin olmak gerekirse, devre dışı çağrı ve kesintilerle korumalı moda "girmemiz" gerekiyor - basit bir konsol programı için olağan davranışa sahip işlemcinin en basit modu. Böyle bir hedefe ulaşmanın en akıllı yolu, çoklu önyükleme biçimini destekleyen bir çekirdek oluşturmak ve onu popüler önyükleyici Grub... Bu çözüme bir alternatif, yazılı kendi yükleyiciyi (yükleyiciyi) yükleyecek olan kendi birim önyükleme kaydınızı (VBR) yazmaktır. İyi bir önyükleyici, en azından bir diskle, bir dosya sistemiyle çalışabilmeli ve elf görüntülerini ayrıştırabilmelidir. Bu, çok fazla montaj kodu ve çok fazla C kodu yazmanız gerektiği anlamına gelir.Kısacası, yapmanız gereken her şeyi nasıl yapacağınızı zaten bilen Grub'u kullanmak daha kolaydır.

Başlangıç ​​olarak, diğer eylemler belirli bir dizi derleyici ve yardımcı program gerektirir. En kolay yol, bir tür Linux (örneğin Ubuntu) kullanmaktır, çünkü önyüklenebilir bir USB flash sürücü oluşturmak için ihtiyacınız olan her şeyi zaten içerir. Windows'ta çalışmaya alışkınsanız, yapılandırabilirsiniz. sanal makine Linux ile (Sanal Kutu veya VMware Workstation kullanarak).

kullanıyorsanız Linux Ubuntu'su, sonra her şeyden önce birkaç yardımcı program yüklemeniz gerekir:
1. Grub. Bunu yapmak için şu komutu kullanın:

Sudo apt-get kurulum grubu

2. Kemu. Her şeyi hızlı bir şekilde test etmek ve hata ayıklamak için gereklidir (Hata ayıklayıcıyla ilgili makaleye bağlantı), bunun için komut benzer:

Sudo apt-get install qemu

Şimdi planımız şuna benziyor:
1. Ekrana bir dize yazdıran bir C programı oluşturun.
2. GRUB kullanılarak önyükleme için kullanılabilir olması için ondan mini önyükleme biçiminde bir görüntü (kernel.bin) oluşturun.
3. Önyüklenebilir bir disk görüntü dosyası oluşturun ve biçimlendirin.
4. Grub'u bu görüntüye yükleyin.
5. Oluşturulan programı (kernel.bin) diske kopyalayın.
6. Resmi fiziksel ortama yazın veya qemu'da çalıştırın.

ve sistem önyükleme işlemi:

Bunu yapmak için birkaç dosya ve dizin oluşturmanız gerekecek:

Adım 1. Hedef program (çekirdek) kodunun oluşturulması:

Ekrana bir mesaj yazdırmak için aşağıdaki kodu içeren bir kernel.c dosyası oluşturun:

#include "printf.h" #include "screen.h" #include "types.h" void main (void) (clear_screen (); printf ("n >>> Merhaba Dünya! n");)

Burada her şey tanıdık ve basit. printf ve clear_screen işlevlerinin eklenmesi daha sonra tartışılacaktır. Bu arada, Grub tarafından yüklenebilmesi için bu kodu gerekli her şeyle tamamlamamız gerekiyor.
Çekirdeğin çoklu önyükleme biçiminde olması için, çekirdek görüntüsünün ilk 8 kilobaytında aşağıdaki yapı gereklidir:

Belirtilen tüm koşullar karşılanırsa, Grub, sırasıyla % eax ve % ebx kayıtları aracılığıyla çoklu önyükleme Bilgi yapısına ve 0x1BADB002 değerine bir işaretçi iletir. Çoklu önyükleme Bilgi yapısı şunları içerir: çeşitli bilgiler, daha fazla sistem yüklemesi için gerekli olabilecek yüklü modüllerin ve konumlarının bir listesi dahil.
Programın bulunduğu dosyanın gerekli imzaları içermesi için aşağıdaki içeriklerle bir dosya yükleyici.s oluşturacağız:

Metin .global loader # giriş noktasının bağlayıcıya görünür hale getirilmesi # Multiboot başlığının ayarlanması - ayrıntılar için GRUB belgelerine bakın .set FLAGS, 0x0 # bu Multiboot "flag" alanıdır .set MAGIC, 0x1BADB002 # "sihirli sayı" önyükleyicinin bulmasını sağlar başlık .set CHECKSUM, - (MAGIC + FLAGS) # checksum gerekli .align 4 .long MAGIC .long FLAGS .long CHECKSUM # ilk çekirdek yığın alanını rezerve eder .set STACKSIZE, 0x4000 # yani, 16k. .lcomm stack, STACKSIZE #rezerv 16k stack .comm mbd, 4# bunu kmain .comm magic'te kullanacağız, 4# kmain loader'da kullanacağız: movl $ (stack + STACKSIZE),% esp# stack'i kur movl% eax, magic # Çoklu önyükleme sihirli numarası movl% ebx, mbd # Çoklu önyükleme veri yapısı ana çağrı # çağrı C kodu cli askıda kal: hlt # makineyi durdur jmp askıda kalmalıdır

Kodu daha yakından inceleyelim. Bu kod neredeyse değişmeden wiki.osdev.org/Bare_Bones adresinden alınmıştır. Derleme için gcc kullanıldığı için GAS sözdizimi kullanılır. Şimdi bu kodun ne yaptığına daha yakından bakalım.

Sonraki tüm kodlar yürütülebilir bölüm .text içine düşecektir.

Küresel yükleyici

Yükleyici sembolünün bağlayıcı tarafından görülebileceğini bildiririz. Bağlayıcı, yükleyiciyi bir giriş noktası olarak kullanacağından bu gereklidir.

Set FLAGS, 0x0 # assign FLAGS = 0x0 .set MAGIC, 0x1BADB002 # assign MAGIC = 0x1BADB002 .set CHECKSUM, - (MAGIC + FLAGS) # assign CHECKSUM = - (MAGIC + FLAGS) .align 4 # sonraki verileri 4 bayt hizalayın. long MAGIC # MAGIC değerini geçerli adrese yerleştirin .long FLAGS # FLAGS değerini geçerli adrese yerleştirin .long CHECKSUM # CHECKSUM değerini geçerli adrese yerleştirin

Bu kod, bir Çoklu Önyükleme biçimi imzası oluşturur. .set yönergesi, bir karakterin değerini virgülün sağındaki bir ifadeye ayarlar. .align 4 yönergesi, sonraki içeriği 4 bayt ile hizalar. .long yönergesi, değeri sonraki dört baytta saklar.

STACKSIZE'ı ayarlayın, 0x4000 # STACKSIZE ata = 0x4000 .lcomm yığını, STACKSIZE # yedek STACKSIZE bayt. yığın comm mbd aralığını ifade eder, 4 # ORTAK alandaki mdb değişkeni için 4 bayt rezerve .comm magic, 4 # ORTAK alandaki sihirli değişken için 4 # yedek 4 bayt

Sırasında önyükleme grubu yığını yapılandırmaz ve çekirdeğin yapması gereken ilk şey yığını yapılandırmaktır, bunun için 0x4000 (16Kb) bayt ayırıyoruz. .lcomm yönergesi, .bss bölümünde virgülden sonraki bayt sayısını saklı tutar. Yığın adı yalnızca derlenmiş dosyada görünür. ..comm yönergesi, .lcomm ile aynı şeyi yapar, ancak simge adı genel olarak bildirilecektir. Yani C koduna aşağıdaki satırı yazarak kullanabiliriz.
dış büyü

Ve şimdi son kısım:

Yükleyici: movl $ (yığın + STACKSIZE), % esp # yığını başlat movl% eax, sihirli # % write% eax to magic movl% ebx, mbd # ebx'ten mbd'ye ana çağrı # ana işlevi çağır cli # donanım askıda kalan kesintileri devre dışı bırak : hlt # kesinti gerçekleşene kadar işlemciyi durdur jmp hang # hang to hang etiketine atla

İlk talimat, yığının en üstündeki değeri % esp kaydında saklamaktır. Yığın aşağı doğru büyüdükçe, % esp, yığın için ayrılan aralığın sonunun adresini depolar. Sonraki iki komut, Grub'un % eax, % ebx kayıtlarında geçtiği değerleri önceden ayrılmış 4 baytlık aralıklarda saklar. Ardından, zaten C'de yazılmış olan ana işlev çağrılır. Bu prosedür dönerse, işlemci bir döngüye girer.

Adım 2. Program için ek kod hazırlayın (sistem kitaplığı):

Tüm program sıfırdan yazıldığı için printf fonksiyonu sıfırdan yazılmalıdır. Bunu yapmak için birkaç dosya hazırlamanız gerekir.
Ortak bir klasör oluşturalım ve klasör ekleyelim:

Mkdir ortak mkdir içerir

Bilinen printf işlevinin uygulamasını içerecek bir commonprintf.c dosyası oluşturalım. Dosyanın tamamı www.bitvisor.org/ projesinden alınabilir. Bitvisor kaynaklarındaki dosyanın yolu: core / printf.c. Bitvisor'dan kopyalanan printf.c dosyasında, hedef programda kullanmak için satırları değiştirmeniz gerekir:

#include "initfunc.h" #include "printf.h" #include "putchar.h" #include "spinlock.h"

satır başına:

#include "types.h" #include "stdarg.h" #include "screen.h"

Ardından, printf_init_global işlevini ve bu dosyadaki tüm referanslarını kaldırın:

Statik void printf_init_global (void) (spinlock_init (& printf_lock);) INITFUNC ("global0", printf_init_global);

Ardından printf_lock değişkenini ve bu dosyadaki tüm referansları kaldırın:

Statik spinlock_t printf_lock; … Spinlock_lock (& ​​printf_lock); ... spinlock_unlock (& ​​printf_lock);

printf işlevi, yazılması gereken putchar işlevini kullanır. Bunu yapmak için aşağıdaki içeriğe sahip bir commonscreen.c dosyası oluşturun:

#include "types.h" #define GREEN 0x2 #define MAX_COL 80 // Maksimum sütun sayısı #define MAX_ROW 25 // Maksimum satır sayısı #define VRAM_SIZE (MAX_COL * MAX_ROW) // Ekran boyutu, kısaca "s # define DEF_VRAM_BASE 0xb8000 // Video belleği için varsayılan taban statik imzasız karakter curr_col = 0; statik imzasız karakter curr_row = 0; // Karakteri geçerli ekran konumuna yaz #define PUT (c) (((işaretsiz kısa *) (DEF_VRAM_BASE)) [ (curr_row * MAX_COL) + curr_col] = (YEŞİL<< 8) | (c)) // Place a character on next screen position static void cons_putc(int c) { switch (c) { case "t": do { cons_putc(" "); } while ((curr_col % 8) != 0); break; case "r": curr_col = 0; break; case "n": curr_row += 1; if (curr_row >= MAX_ROW) (curr_row = 0;) ara; durum "b": if (curr_col> 0) (curr_col - = 1; PUT ("");) break; varsayılan: PUT (c); curr_col + = 1; if (curr_col> = MAX_COL) (curr_col = 0; Curr_row + = 1; if (curr_row> = MAX_ROW) (curr_row = 0;))); ) void putchar (int c) (if (c == "n") cons_putc ("r"); cons_putc (c);) void clear_screen (void) (curr_col = 0; curr_row = 0; int i; for (i) = 0; ben< VRAM_SIZE; i++) cons_putc(" "); curr_col = 0; curr_row = 0; }

Yukarıdaki kod, metin modunda ekrana karakterleri yazdırmak için basit bir mantık içerir. Bu modda, 0xB8000 adresinden başlayarak, doğrudan ekranda görüntülenen video belleğine yazılan bir karakter (biri karakter koduyla, diğeri nitelikleriyle birlikte) yazmak için iki bayt kullanılır. Ekran çözünürlüğü 80x25 karakterdir. Bir sembolün doğrudan yazdırılması, PUT makrosu kullanılarak gerçekleştirilir.
Şimdi yalnızca birkaç başlık dosyası eksik:
1. includescreen.h dosyası. printf işlevinde kullanılan putchar işlevini bildirir. Dosya içeriği:

#ifndef _SCREEN_H #define _SCREEN_H void clear_screen (void); geçersiz putchar (int c); #endif

2. Dosya dahilprintf.h. main içinde kullanılan printf işlevini bildirir. Dosya içeriği:

#ifndef _PRINTF_H #define _PRINTF_H int printf (const char * biçimi, ...); #endif

3. includetdarg.h dosyası. Sayısı önceden bilinmeyen bağımsız değişkenler üzerinde yineleme işlevleri bildirir. Dosyanın tamamı www.bitvisor.org/ projesinden alınmıştır. Bitvisor proje kodundaki dosyanın yolu includecorestdarg.h'dir.
4. Dosya includetypes.h. NULL ve size_t bildirir. Dosya içeriği:

#ifndef _TYPES_H #define _TYPES_H #define NULL 0 typedef unsigned int size_t; #endif

Böylece, içerme ve ortak klasörler, herhangi bir programın ihtiyaç duyduğu minimum sistem kitaplığı kodunu içerir.

Adım 3. Bağlayıcı için bir komut dosyası oluşturun:

Bağlayıcı tarafından hedef program dosyasını (kernel.bin) oluşturmak için kullanılacak bir linker.ld dosyası oluşturun. Dosya aşağıdakileri içermelidir:

GİRİŞ (yükleyici) LMA = 0x00100000; BÖLÜMLER (. = LMA; .multiboot ALIGN (0x1000): (loader.o (.text)) .text ALIGN (0x1000): (* (. Text)) .rodata ALIGN (0x1000): (* (. Rodata *) ) .data ALIGN (0x1000): (* (. veri)) .bss: (* (ORTAK) * (. bss)) / İPTAL /: (* (. yorum)))

Yerleşik ENTRY () işlevi, çekirdeğimiz için giriş noktasını belirlememizi sağlar. Bu adreste grub, çekirdek yüklendikten sonra kontrolü aktaracaktır. Bağlayıcı, bir ELF ikili dosyası oluşturmak için bu komut dosyasını kullanacaktır. Bir ELF dosyası bir dizi segment ve bölümden oluşur. Bölümlerin listesi Program başlık tablosunda, bölümlerin listesi Bölüm başlık tablosunda bulunur. Bağlayıcı bölümlerle, görüntü yükleyici (bizim durumumuzda GRUB'dur) bölümlerle çalışır.


Şekilde de görebileceğiniz gibi, segmentler bölümlerden oluşur. Bölümü açıklayan alanlardan biri, yürütme sırasında bölümün bulunması gereken sanal adrestir. Aslında, bir segmentin konumunu tanımlayan 2 alanı vardır: segmentin sanal adresi ve segmentin fiziksel adresi. Segmentin sanal adresi, kod yürütme sırasında segmentin ilk baytının sanal adresidir, segmentin fiziksel adresi, segmentin yüklenmesi gereken fiziksel adrestir. Uygulama programları için bu adresler her zaman aynıdır. Grub, görüntü segmentlerini fiziksel adreslerine yükler. Grub sayfalamayı yapılandırmadığından, segmentin sanal adresi, programımızda olduğu için fiziksel adresiyle eşleşmelidir. sanal bellek ayrıca yapılandırılamaz.

LMA;

Bu ifade, bağlayıcıya, sonraki tüm bölümlerin LMA adresinden sonra olduğunu söyler.

HİZALA (0x1000)

Yukarıdaki yönerge, bölümün 0x1000 bayt hizalı olduğu anlamına gelir.

Çoklu Önyükleme HİZALAMA (0x1000): (loader.o (.text))

Yükleyici.o dosyasından .text bölümünü içeren ayrı bir çoklu önyükleme bölümü, çoklu önyükleme biçimi imzasının çekirdek görüntüsünün ilk 8 kb'sine girmesini sağlamak için yapılmıştır.

Bss: (* (ORTAK) * (. Bss))

* (ORTAK) .comm ve.lcomm komutları tarafından belleğin ayrıldığı alandır. .bss bölümüne yerleştiriyoruz.

/ İPTAL /: (* (. Yorum))

DISCARD olarak işaretlenen tüm bölümler görüntüden kaldırılır. Bu durumda, linker sürümü hakkında bilgi içeren.comment bölümünü siliyoruz.

Şimdi kodu aşağıdaki komutlarla bir ikili dosyada derleyelim:

as -o loader.o loader.s gcc -Iinclude -Wall -fno-builtin -nostdinc -nostdlib -o kernel.o -c kernel.c gcc -Iinclude -Wall -fno-builtin -nostdinc -nostdlib -o printf.o -c common / printf.c gcc -Iinclude -Wall -fno-builtin -nostdinc -nostdlib -o screen.o -c common /screen.c ld -T linker.ld -o kernel.bin kernel.o screen.o printf .o yükleyici.o

Objdump kullanarak, bağladıktan sonra çekirdek görüntüsünün nasıl göründüğünü görelim:

Objdump -ph ./kernel.bin



Gördüğünüz gibi, görüntüdeki bölümler, linker betiğinde açıklananlarla aynıdır. Bağlayıcı, açıklanan bölümlerden 3 bölüm oluşturmuştur. İlk segment multiboot, .text, .rodata bölümlerini içerir ve 0x00100000 sanal ve fiziksel adrese sahiptir. İkinci segment .data ve .bss bölümlerini içerir ve 0x00104000'de bulunur. Yani bu dosyayı Grub ile indirmeye hazırsınız.

Adım 4. Grub önyükleyicisini hazırlayın:
Grub klasörü oluşturun:

mkdir grubu

Görüntüye yüklemek için gerekli olan birkaç Grub dosyasını bu klasöre kopyalayın (sistemde Grub yüklüyse aşağıdaki dosyalar bulunur). Bunu yapmak için aşağıdaki komutları çalıştırmanız gerekir:

Cp / usr / lib / grub / i386-pc / aşama1 ./grub/ cp / usr / lib / grub / i386-pc / aşama2 ./grub/ cp / usr / lib / grub / i386-pc / fat_stage1_5 ./grub /

Aşağıdaki içeriğe sahip bir grub / menu.lst dosyası oluşturun:

Zaman aşımı 3 varsayılan 0 başlık mini_os kök (hd0,0) çekirdek /kernel.bin

Adım 5. Önyüklenebilir bir görüntüyü otomatikleştirin ve oluşturun:

Oluşturma sürecini otomatikleştirmek için make yardımcı programını kullanacağız. Bunu yapmak için, derleme kaynak kodu oluşturacak, bir çekirdek oluşturacak ve bir önyükleme görüntüsü oluşturacak bir makefile oluşturacağız. Makefile aşağıdaki içeriğe sahip olmalıdır:

CC = gcc CFLAGS = -Wall -fno-builtin -nostdinc -nostdlib LD = ld OBJFILES = loader.o common / printf.o common / screen.o kernel.o image: @echo "hdd.img ..." oluşturuluyor @ dd if = / dev / zero of =. / hdd.img bs = 512 count = 16065 1> / dev / null 2> & 1 @echo "Önyüklenebilir ilk FAT32 bölümü oluşturuluyor ..." @losetup / dev / loop1 ./ hdd .img @ (yankı c; yankı u; yankı n; yankı p; yankı 1; yankı; yankı; yankı a; yankı 1; yankı t; yankı c; yankı w;) | fdisk / dev / loop1 1> / dev / null 2> & 1 || true @echo "Bölüm / dev / loop2'ye monte ediliyor ..." @losetup / dev / loop2 ./hdd.img --offset `echo` fdisk -lu / dev / loop1 | sed -n 10p | awk "($$ 3 yazdırın)" `* 512 | bc` --sizelimit `echo` fdisk -lu / dev / loop1 | sed -n 10p | awk "($$ 4 yazdırın)" `* 512 | bc` @losetup -d / dev / loop1 @echo "Bölümü biçimlendir ..." @mkdosfs / dev / loop2 @echo "Çekirdek ve grup dosyalarını bölüme kopyalayın ..." @mkdir -p tempdir @mount / dev / loop2 tempdir @mkdir tempdir / boot @cp -r grub tempdir / boot / @cp kernel.bin tempdir / @sleep 1 @umount / dev / loop2 @rm -r tempdir @losetup -d / dev / loop2 @echo "GRUB yükleniyor. .. "@echo" cihazı (hd0) hdd.img n root (hd0,0) n kurulum (hd0) n çıkış "| grub --batch 1> / dev / null @echo "Bitti!" tümü: kernel.bin yeniden: hepsini temizle .s.o: as -o [e-posta korumalı] $< .c.o: $(CC) -Iinclude $(CFLAGS) -o [e-posta korumalı]-c $< kernel.bin: $(OBJFILES) $(LD) -T linker.ld -o [e-posta korumalı]$ ^ temiz: rm -f $ (OBJFILES) hdd.img kernel.bin

Dosya iki ana hedefi bildirir: tümü - çekirdeği derler ve bir önyükleme diski oluşturan görüntü. Tüm hedef, her zamanki makefile gibi, * .s ve * .c dosyalarını nesne dosyalarında (* .o) derleyen .so ve .co alt amaçlarını ve ayrıca çağıran kernel.bin oluşturma hedefini içerir. daha önce oluşturulan komut dosyasına sahip bağlayıcı. Bu hedefler, 3. adımda belirtilen komutların tam olarak aynısını gerçekleştirir.
Burada en büyük ilgi, yaratılış önyükleme görüntüsü hdd.img (hedef görüntü). Bunun nasıl olduğunu aşamalı olarak ele alalım.

Dd if = / dev / sıfır of =. / Hdd.img bs = 512 sayı = 16065 1> / dev / null 2> & 1

Bu komut, daha fazla çalışmanın gerçekleştirileceği bir görüntü oluşturur. Sektör sayısı rastgele seçilmemiştir: 16065 = 255 * 63. Varsayılan olarak fdsik, diskle CHS geometrisine sahipmiş gibi çalışır, burada Başlıklar (H) = 255, Sektörler (S) = 63 ve Silindirler © bağlıdır. disk boyutunda ... Böylece, fdsik yardımcı programının varsayılan geometriyi değiştirmeden çalışabileceği minimum disk boyutu 512 * 255 * 63 * 1 = 8225280 bayttır, burada 512 sektör boyutu ve 1 silindir sayısıdır.
Ardından, bir bölüm tablosu oluşturulur:

Losetup / dev / loop1 ./hdd.img (eko c; yankı u; yankı n; yankı p; yankı 1; yankı; yankı; yankı a; yankı 1; yankı t; yankı c; yankı w;) | fdisk / dev / loop1 1> / dev / null 2> & 1 || NS

İlk komut, hdd.img dosyasını / dev / loop1 blok aygıtına bağlar ve dosyanın bir aygıt gibi ele alınmasına izin verir. İkinci komut, cihaz / dev / loop1 üzerinde 1 birincil içeren bir bölüm tablosu oluşturur. önyükleme bölümü FAT32 dosya sistemi ile etiketlenmiş, tüm diski kaplayan disk.
Daha sonra oluşturulan bölümü formatlıyoruz. Bunu yapmak için, onu bir blok cihaz olarak monte etmeniz ve biçimlendirme yapmanız gerekir.

Losetup / dev / loop2 ./hdd.img --offset `echo` fdisk -lu / dev / loop1 | sed -n 10p | awk "($$ 3 yazdırın)" `* 512 | bc` --sizelimit `echo` fdisk -lu / dev / loop1 | sed -n 10p | awk "($$ 4 yazdırın)" `* 512 | bc`lostup -d / dev / loop1

İlk komut, önceden oluşturulmuş bölümü / dev / loop2 aygıtına bağlar. –offset seçeneği bölümün başlangıcını, –sizelimit ise bölümün sonunu belirtir. Her iki parametre de fdisk komutu kullanılarak elde edilir.

Mkdosfs / dev / loop2

mkdosfs yardımcı programı, bölümü şu şekilde biçimlendirir: dosya sistemi FAT32.
Çekirdeği doğrudan oluşturmak için, klasik makefile sözdiziminde daha önce tartışılan komutlar kullanılır.
Şimdi GRUB'u bir bölüme nasıl kuracağımızı görelim:

Mkdir -p tempdir # geçici bir dizin oluşturur mount / dev / loop2 tempdir # bölümü mkdir dizinine bağlar tempdir / boot # cp bölümünde bir / boot dizini oluşturur -r grub tempdir / boot / # grub klasörünü / dizinine kopyalar boot cp kernel.bin tempdir / # çekirdeği bölümün kök dizinine kopyalar sleep 1 # Ubuntu için bekle umount / dev / loop2 # geçici klasörün bağlantısını kes rm -r tempdir # geçici klasörü sil Lostup -d / dev / loop2 # bölümün bağlantısını kes

Yukarıdaki komutları yürüttükten sonra görüntü GRUB'u kurmaya hazır olacaktır. Aşağıdaki komut, GRUB'u hdd.img disk görüntüsünün MBR'sine yükler.

Echo "cihaz (hd0) hdd.img n kök (hd0,0) n kurulum (hd0) n çık" | grub --batch 1> / dev / boş

Test için her şey hazır!

6. Adım: Başlatın:

Derlemek için şu komutu kullanın:

Hepsini yapmak

Bundan sonra kernel.bin dosyası görünmelidir.
Önyüklenebilir bir disk görüntüsü oluşturmak için şu komutu kullanın:

Sudo resmi yap

Sonuç olarak hdd.img dosyası görünmelidir.
Artık hdd.img disk görüntüsünden önyükleme yapabilirsiniz. Bunu aşağıdaki komutla kontrol edebilirsiniz:

Qemu -hda hdd.img -m 32

Qemu-system-i386 -hda hdd.img




Gerçek bir makineyi kontrol etmek için bu görüntüyü bir flash sürücüye eklemeniz ve ondan önyükleme yapmanız gerekir. Örneğin aşağıdaki komutla:

Sudo dd if =. / Hdd.img = / dev / sdb

Özetle, yapılan işlemler sonucunda sistem programlama alanında çeşitli deneyler yapmanızı sağlayan bir dizi kaynak ve komut dosyası elde edildiğini söyleyebiliriz. Hipervizörler ve işletim sistemleri gibi sistem yazılımları oluşturmaya yönelik ilk adımı atmak.

En önemli şey yeterince ayrıntılı anlatılmamış: Bu kod gerçek donanımda nasıl çalıştırılır? Kendi önyüklenebilir diskimi nasıl oluşturabilirim? Bu makalede, tüm bu soruları ayrıntılı olarak cevaplayacağız (bu soruların bazıları önceki makalede ele alındı, ancak okuma kolaylığı için kendimize materyalin biraz tekrarlanmasına izin vereceğiz).

İnternette kendi mini işletim sisteminizi nasıl yazacağınızla ilgili çok sayıda açıklama ve eğitim var, hatta yüzlerce hazır küçük hobi işletim sistemi var. Bu konuda altını çizmek istediğim en değerli kaynaklardan biri de osdev.org portalıdır. PCI ile ilgili önceki makaleyi (ve herhangi bir modern işletim sisteminde bulunan çeşitli işlevler hakkında sonraki makaleleri yazma yeteneği) desteklemek için, C'de tanıdık bir programla önyüklenebilir bir disk oluşturmak için adım adım talimatları açıklayacağız. Her şeyi kendi başınıza çözebilmeniz için mümkün olduğunca ayrıntılı yazmaya çalıştım.

Yani amaç: mümkün olduğunca az çaba harcayarak, bilgisayar ekranına klasik "Merhaba Dünya"yı yazdıran kendi önyüklenebilir USB flash sürücünüzü oluşturun.

Daha kesin olmak gerekirse, devre dışı çağrı ve kesintilerle korumalı moda "girmemiz" gerekiyor - basit bir konsol programı için olağan davranışa sahip işlemcinin en basit modu. Bunu başarmanın en akıllı yolu, çoklu önyüklemeli bir çekirdek oluşturmak ve onu popüler Grub önyükleme yükleyicisini kullanarak başlatmaktır. Bu çözüme bir alternatif, yazılı kendi yükleyiciyi (yükleyiciyi) yükleyecek olan kendi birim önyükleme kaydınızı (VBR) yazmaktır. İyi bir önyükleyici, en azından bir diskle, bir dosya sistemiyle çalışabilmeli ve elf görüntülerini ayrıştırabilmelidir. Bu, çok fazla montaj kodu ve çok fazla C kodu yazmanız gerektiği anlamına gelir.Kısacası, yapmanız gereken her şeyi nasıl yapacağınızı zaten bilen Grub'u kullanmak daha kolaydır.

Başlangıç ​​olarak, diğer eylemler belirli bir dizi derleyici ve yardımcı program gerektirir. En kolay yol, bir tür Linux (örneğin Ubuntu) kullanmaktır, çünkü önyüklenebilir bir USB flash sürücü oluşturmak için ihtiyacınız olan her şeyi zaten içerir. Windows'ta çalışmaya alışkınsanız, bir Linux sanal makinesi (Virtual Box veya VMware Workstation kullanarak) kurabilirsiniz.

Linux Ubuntu kullanıyorsanız, öncelikle birkaç yardımcı program yüklemeniz gerekir:
1. Grub. Bunu yapmak için şu komutu kullanın:
sudo apt-get kurulum grubu

2. Kemu. Her şeyi hızlı hale getirmek gerekiyor, bunun için komut benzer:
sudo apt-get install qemu

Şimdi planımız şuna benziyor:
1. Ekrana bir dize yazdıran bir C programı oluşturun.
2. GRUB kullanılarak önyükleme için kullanılabilir olması için ondan mini önyükleme biçiminde bir görüntü (kernel.bin) oluşturun.
3. Önyüklenebilir bir disk görüntü dosyası oluşturun ve biçimlendirin.
4. Grub'u bu görüntüye yükleyin.
5. Oluşturulan programı (kernel.bin) diske kopyalayın.
6. Resmi fiziksel ortama yazın veya qemu'da çalıştırın.

Ve sistem önyükleme işlemi:

Bunu yapmak için birkaç dosya ve dizin oluşturmanız gerekecek:

Adım 1. Hedef program (çekirdek) kodunun oluşturulması:

Ekrana bir mesaj yazdırmak için aşağıdaki kodu içeren bir kernel.c dosyası oluşturun:

#include "printf.h" #include "screen.h" #include "types.h" void main (void) (clear_screen (); printf ("\ n >>> Merhaba Dünya! \ n");)

Burada her şey tanıdık ve basit. printf ve clear_screen işlevlerinin eklenmesi daha sonra tartışılacaktır. Bu arada, Grub tarafından yüklenebilmesi için bu kodu gerekli her şeyle tamamlamamız gerekiyor.
Çekirdeğin çoklu önyükleme biçiminde olması için, çekirdek görüntüsünün ilk 8 kilobaytında aşağıdaki yapı gereklidir:

Belirtilen tüm koşullar karşılanırsa, Grub, sırasıyla % eax ve % ebx kayıtları aracılığıyla çoklu önyükleme Bilgi yapısına ve 0x1BADB002 değerine bir işaretçi iletir. Çoklu önyükleme Bilgi yapısı, yüklenen modüllerin listesi ve sistemi daha fazla başlatmak için gerekebilecek konumları dahil olmak üzere çeşitli bilgiler içerir.
Programın bulunduğu dosyanın gerekli imzaları içermesi için aşağıdaki içeriklerle bir dosya yükleyici.s oluşturacağız:

Metin .global loader # giriş noktasının bağlayıcıya görünür hale getirilmesi # Multiboot başlığının ayarlanması - ayrıntılar için GRUB belgelerine bakın .set FLAGS, 0x0 # bu Multiboot "flag" alanıdır .set MAGIC, 0x1BADB002 # "sihirli sayı" önyükleyicinin bulmasını sağlar başlık .set CHECKSUM, - (MAGIC + FLAGS) # checksum gerekli .align 4 .long MAGIC .long FLAGS .long CHECKSUM # ilk çekirdek yığın alanını rezerve eder .set STACKSIZE, 0x4000 # yani, 16k. .lcomm stack, STACKSIZE #rezerv 16k stack .comm mbd, 4# bunu kmain .comm magic'te kullanacağız, 4# kmain loader'da kullanacağız: movl $ (stack + STACKSIZE),% esp# stack'i kur movl% eax, magic # Çoklu önyükleme sihirli numarası movl% ebx, mbd # Çoklu önyükleme veri yapısı ana çağrı # çağrı C kodu cli askıda kal: hlt # makineyi durdur jmp askıda kalmalıdır

Kodu daha yakından inceleyelim. Bu kod neredeyse değişmeden wiki.osdev.org/Bare_Bones adresinden alınmıştır. Derleme için gcc kullanıldığı için GAS sözdizimi kullanılır. Şimdi bu kodun ne yaptığına daha yakından bakalım.
.Metin
Sonraki tüm kodlar yürütülebilir bölüm .text içine düşecektir.
.global yükleyici
Yükleyici sembolünün bağlayıcı tarafından görülebileceğini bildiririz. Bağlayıcı, yükleyiciyi bir giriş noktası olarak kullanacağından bu gereklidir.
.set FLAGS, 0x0 # assign FLAGS = 0x0 .set MAGIC, 0x1BADB002 # assign MAGIC = 0x1BADB002 .set CHECKSUM, - (MAGIC + FLAGS) # assign CHECKSUM = - (MAGIC + FLAGS) .align 4 # sonraki verileri 4 bayt hizalayın .long MAGIC # MAGIC değerini geçerli adrese yerleştirin .long FLAGS # BAYRAK değerini geçerli adrese yerleştirin .long CHECKSUM # CHECKSUM değerini geçerli adrese yerleştirin
Bu kod, bir Çoklu Önyükleme biçimi imzası oluşturur. .set yönergesi, bir karakterin değerini virgülün sağındaki bir ifadeye ayarlar. .align 4 yönergesi, sonraki içeriği 4 bayt ile hizalar. .long yönergesi, değeri sonraki dört baytta saklar.
.set STACKSIZE, 0x4000 # STACKSIZE ata = 0x4000 .lcomm stack, STACKSIZE # yedek STACKSIZE bayt. yığın comm mbd aralığını ifade eder, 4 # ORTAK alandaki mdb değişkeni için 4 bayt rezerve .comm magic, 4 # ORTAK alandaki sihirli değişken için 4 # yedek 4 bayt
Önyükleme sırasında grub yığını yapılandırmaz ve çekirdeğin yapması gereken ilk şey yığını yapılandırmaktır, bunun için 0x4000 (16Kb) bayt ayırıyoruz. .lcomm yönergesi, .bss bölümünde virgülden sonraki bayt sayısını saklı tutar. Yığın adı yalnızca derlenmiş dosyada görünür. ..comm yönergesi, .lcomm ile aynı şeyi yapar, ancak simge adı genel olarak bildirilecektir. Yani C koduna aşağıdaki satırı yazarak kullanabiliriz.
dış büyü

Ve şimdi son kısım:
yükleyici: movl $ (yığın + STACKSIZE), % esp # yığını başlat movl% eax, magic # % write% eax to magic movl% ebx, mbd # ebx'den mbd'ye % yaz ana işlevi çağır : hlt # kesinti gerçekleşene kadar işlemciyi durdur jmp hang # hang to hang etiketine atla

İlk talimat, yığının en üstündeki değeri % esp kaydında saklamaktır. Yığın aşağı doğru büyüdükçe, % esp, yığın için ayrılan aralığın sonunun adresini depolar. Sonraki iki komut, Grub'un % eax, % ebx kayıtlarında geçtiği değerleri önceden ayrılmış 4 baytlık aralıklarda saklar. Ardından, zaten C'de yazılmış olan ana işlev çağrılır. Bu prosedür dönerse, işlemci bir döngüye girer.

Adım 2. Program için ek kod hazırlayın (sistem kitaplığı):

Tüm program sıfırdan yazıldığı için printf fonksiyonu sıfırdan yazılmalıdır. Bunu yapmak için birkaç dosya hazırlamanız gerekir.
Ortak bir klasör oluşturalım ve klasör ekleyelim:

Mkdir ortak mkdir içerir

Bilinen printf işlevinin uygulamasını içerecek bir ortak \ printf.c dosyası oluşturalım. Bu dosya tamamen www.bitvisor.org projesinden alınabilir. Bitvisor kaynaklarındaki dosyanın yolu: core / printf.c. Bitvisor'dan kopyalanan printf.c dosyasında, hedef programda kullanmak için satırları değiştirmeniz gerekir:

#include "initfunc.h" #include "printf.h" #include "putchar.h" #include "spinlock.h"
satır başına:
#include "types.h" #include "stdarg.h" #include "screen.h"

Ardından, printf_init_global işlevini ve bu dosyadaki tüm referanslarını kaldırın:

Statik void printf_init_global (void) (spinlock_init (& printf_lock);) INITFUNC ("global0", printf_init_global);

Ardından printf_lock değişkenini ve bu dosyadaki tüm referansları kaldırın:
statik spinlock_t printf_lock; … Spinlock_lock (& ​​printf_lock); ... spinlock_unlock (& ​​printf_lock);

printf işlevi, yazılması gereken putchar işlevini kullanır. Bunu yapmak için, aşağıdaki içeriğe sahip ortak bir \ screen.c dosyası oluşturun:
#include "types.h" #define GREEN 0x2 #define MAX_COL 80 // Maksimum sütun sayısı #define MAX_ROW 25 // Maksimum satır sayısı #define VRAM_SIZE (MAX_COL * MAX_ROW) // Ekran boyutu, kısaca "s # define DEF_VRAM_BASE 0xb8000 // Video belleği için varsayılan temel static unsigned char curr_col = 0; static unsigned char curr_row = 0; // Karakteri geçerli ekran konumuna yaz #define PUT (c) (((unsigned short *) (DEF_VRAM_BASE)) \ [(curr_row * MAX_COL) + curr_col] = (YEŞİL<< 8) | (c)) // Place a character on next screen position static void cons_putc(int c) { switch (c) { case "\t": do { cons_putc(" "); } while ((curr_col % 8) != 0); break; case "\r": curr_col = 0; break; case "\n": curr_row += 1; if (curr_row >= MAX_ROW) (curr_row = 0;) ara; case "\ b": if (curr_col> 0) (curr_col - = 1; PUT (""));) break; varsayılan: PUT (c); curr_col + = 1; if (curr_col> = MAX_COL) (curr_col = 0; Curr_row + = 1; if (curr_row> = MAX_ROW) (curr_row = 0;))); ) void putchar (int c) (if (c == "\ n") cons_putc ("\ r"); cons_putc (c);) void clear_screen (void) (curr_col = 0; curr_row = 0; int i; için (i = 0; ben< VRAM_SIZE; i++) cons_putc(" "); curr_col = 0; curr_row = 0; }

Yukarıdaki kod, metin modunda ekrana karakterleri yazdırmak için basit bir mantık içerir. Bu modda, 0xB8000 adresinden başlayarak, doğrudan ekranda görüntülenen video belleğine yazılan bir karakter (biri karakter koduyla, diğeri nitelikleriyle birlikte) yazmak için iki bayt kullanılır. Ekran çözünürlüğü 80x25 karakterdir. Bir sembolün doğrudan yazdırılması, PUT makrosu kullanılarak gerçekleştirilir.
Şimdi yalnızca birkaç başlık dosyası eksik:
1. Dosya \ screen.h içerir. printf işlevinde kullanılan putchar işlevini bildirir. Dosya içeriği:
#ifndef _SCREEN_H #define _SCREEN_H void clear_screen (void); geçersiz putchar (int c); #endif

2. Dosya içerir \ printf.h. main içinde kullanılan printf işlevini bildirir. Dosya içeriği:
#ifndef _PRINTF_H #define _PRINTF_H int printf (const char * biçimi, ...); #endif

3. Dosya \ stdarg.h içerir. Sayısı önceden bilinmeyen bağımsız değişkenler üzerinde yineleme işlevleri bildirir. Dosyanın tamamı www.bitvisor.org projesinden alınmıştır. Bitvisor proje kodundaki dosyanın yolu, include \ core \ stdarg.h'dir.
4. Dosya içerir \ type.h. NULL ve size_t bildirir. Dosya içeriği:
#ifndef _TYPES_H #define _TYPES_H #define NULL 0 typedef unsigned int size_t; #endif
Böylece, içerme ve ortak klasörler, herhangi bir programın ihtiyaç duyduğu minimum sistem kitaplığı kodunu içerir.

Adım 3. Bağlayıcı için bir komut dosyası oluşturun:

Bağlayıcı tarafından hedef program dosyasını (kernel.bin) oluşturmak için kullanılacak bir linker.ld dosyası oluşturun. Dosya aşağıdakileri içermelidir:

GİRİŞ (yükleyici) LMA = 0x00100000; BÖLÜMLER (. = LMA; .multiboot ALIGN (0x1000): (loader.o (.text)) .text ALIGN (0x1000): (* (. Text)) .rodata ALIGN (0x1000): (* (. Rodata *) ) .data ALIGN (0x1000): (* (. veri)) .bss: (* (ORTAK) * (. bss)) / İPTAL /: (* (. yorum)))

Yerleşik ENTRY () işlevi, çekirdeğimiz için giriş noktasını belirlememizi sağlar. Bu adreste grub, çekirdek yüklendikten sonra kontrolü aktaracaktır. Bağlayıcı, bir ELF ikili dosyası oluşturmak için bu komut dosyasını kullanacaktır. Bir ELF dosyası bir dizi segment ve bölümden oluşur. Bölümlerin listesi Program başlık tablosunda, bölümlerin listesi Bölüm başlık tablosunda bulunur. Bağlayıcı bölümlerle, görüntü yükleyici (bizim durumumuzda GRUB'dur) bölümlerle çalışır.


Şekilde de görebileceğiniz gibi, segmentler bölümlerden oluşur. Bölümü açıklayan alanlardan biri, yürütme sırasında bölümün bulunması gereken sanal adrestir. Aslında, bir segmentin konumunu tanımlayan 2 alanı vardır: segmentin sanal adresi ve segmentin fiziksel adresi. Segmentin sanal adresi, kod yürütme sırasında segmentin ilk baytının sanal adresidir, segmentin fiziksel adresi, segmentin yüklenmesi gereken fiziksel adrestir. Uygulama programları için bu adresler her zaman aynıdır. Grub, görüntü segmentlerini fiziksel adreslerine yükler. Grub sayfalamayı yapılandırmadığından, sanal bellek de programımızda yapılandırılmadığından, segmentin sanal adresi fiziksel adresiyle eşleşmelidir.

BÖLÜMLER
Bölümlerin aşağıda açıklandığını belirtir.
... = LMA;
Bu ifade, bağlayıcıya, sonraki tüm bölümlerin LMA adresinden sonra olduğunu söyler.
HİZALA (0x1000)
Yukarıdaki yönerge, bölümün 0x1000 bayt hizalı olduğu anlamına gelir.
.multiboot ALIGN (0x1000): (loader.o (.text))
Yükleyici.o dosyasından .text bölümünü içeren ayrı bir çoklu önyükleme bölümü, çoklu önyükleme biçimi imzasının çekirdek görüntüsünün ilk 8 kb'sine girmesini sağlamak için yapılmıştır.
.bss: (* (ORTAK) * (. bss))
* (ORTAK) .comm ve.lcomm komutları tarafından belleğin ayrıldığı alandır. .bss bölümüne yerleştiriyoruz.
/ İPTAL /: (* (. Yorum))
DISCARD olarak işaretlenen tüm bölümler görüntüden kaldırılır. Bu durumda, linker sürümü hakkında bilgi içeren.comment bölümünü siliyoruz.

Şimdi kodu aşağıdaki komutlarla bir ikili dosyada derleyelim:
as -o loader.o loader.s gcc -Iinclude -Wall -fno-builtin -nostdinc -nostdlib -o kernel.o -c kernel.c gcc -Iinclude -Wall -fno-builtin -nostdinc -nostdlib -o printf.o -c common / printf.c gcc -Iinclude -Wall -fno-builtin -nostdinc -nostdlib -o screen.o -c common /screen.c ld -T linker.ld -o kernel.bin kernel.o screen.o printf .o yükleyici.o
Objdump kullanarak, bağladıktan sonra çekirdek görüntüsünün nasıl göründüğünü görelim:
objdump -ph ./kernel.bin


Gördüğünüz gibi, görüntüdeki bölümler, linker betiğinde açıklananlarla aynıdır. Bağlayıcı, açıklanan bölümlerden 3 bölüm oluşturmuştur. İlk segment multiboot, .text, .rodata bölümlerini içerir ve 0x00100000 sanal ve fiziksel adrese sahiptir. İkinci segment .data ve .bss bölümlerini içerir ve 0x00104000'de bulunur. Yani bu dosyayı Grub ile indirmeye hazırsınız.

Adım 4. Grub önyükleyicisini hazırlayın:
Grub klasörü oluşturun:
mkdir grubu

Görüntüye yüklemek için gerekli olan birkaç Grub dosyasını bu klasöre kopyalayın (sistemde Grub yüklüyse aşağıdaki dosyalar bulunur). Bunu yapmak için aşağıdaki komutları çalıştırmanız gerekir:
cp / usr / lib / grub / i386-pc / aşama1 ./grub/ cp / usr / lib / grub / i386-pc / aşama2 ./grub/ cp / usr / lib / grub / i386-pc / fat_stage1_5 ./grub /

Aşağıdaki içeriğe sahip bir grub / menu.lst dosyası oluşturun:
zaman aşımı 3 varsayılan 0 başlık mini_os kökü (hd0,0) çekirdek /kernel.bin

Adım 5. Önyüklenebilir bir görüntüyü otomatikleştirin ve oluşturun:

Oluşturma sürecini otomatikleştirmek için make yardımcı programını kullanacağız. Bunu yapmak için, derleme kaynak kodu oluşturacak, bir çekirdek oluşturacak ve bir önyükleme görüntüsü oluşturacak bir makefile oluşturacağız. Makefile aşağıdaki içeriğe sahip olmalıdır:

CC = gcc CFLAGS = -Wall -fno-builtin -nostdinc -nostdlib LD = ld OBJFILES = \ loader.o \ common / printf.o \ common / screen.o \ kernel.o görüntüsü: @echo "hdd.img oluşturuluyor. .. "@dd if = / dev / zero of =. / hdd.img bs = 512 count = 16065 1> / dev / null 2> & 1 @echo" Önyüklenebilir ilk FAT32 bölümü oluşturma ... "@losetup / dev / loop1 ./hdd.img @ (eko c; yankı u; yankı n; yankı p; yankı 1; yankı; yankı; yankı a; yankı 1; yankı t; yankı c; yankı w;) | fdisk / dev / loop1 1> / dev / null 2> & 1 || true @echo "Bölüm / dev / loop2'ye monte ediliyor ..." @losetup / dev / loop2 ./hdd.img \ --offset `echo \` fdisk -lu / dev / loop1 | sed -n 10p | awk "($$ 3 yazdırın)" \ `* 512 | bc` \ --sizelimit `echo \` fdisk -lu / dev / loop1 | sed -n 10p | awk "($$ 4 yazdırın)" \ `* 512 | bc` @losetup -d / dev / loop1 @echo "Bölümü biçimlendir ..." @mkdosfs / dev / loop2 @echo "Çekirdek ve grup dosyalarını bölüme kopyalayın ..." @mkdir -p tempdir @mount / dev / loop2 tempdir @mkdir tempdir / boot @cp -r grub tempdir / boot / @cp kernel.bin tempdir / @sleep 1 @umount / dev / loop2 @rm -r tempdir @losetup -d / dev / loop2 @echo "GRUB yükleniyor. .. "@echo" cihazı (hd0) hdd.img \ n \ kök (hd0,0) \ n \ kurulum (hd0) \ n \ çıkış \ n "| grub --batch 1> / dev / null @echo "Bitti!" tümü: kernel.bin yeniden: hepsini temizle .s.o: as -o [e-posta korumalı] $< .c.o: $(CC) -Iinclude $(CFLAGS) -o [e-posta korumalı]-c $< kernel.bin: $(OBJFILES) $(LD) -T linker.ld -o [e-posta korumalı]$ ^ temiz: rm -f $ (OBJFILES) hdd.img kernel.bin

Dosya iki ana hedefi bildirir: tümü - çekirdeği derler ve bir önyükleme diski oluşturan görüntü. Tüm hedef, her zamanki makefile gibi, * .s ve * .c dosyalarını nesne dosyalarında (* .o) derleyen .so ve .co alt amaçlarını ve ayrıca çağıran kernel.bin oluşturma hedefini içerir. daha önce oluşturulan komut dosyasına sahip bağlayıcı. Bu hedefler, 3. adımda belirtilen komutların tam olarak aynısını gerçekleştirir.
Burada özellikle ilgi çekici olan, hdd.img (hedef görüntü) önyükleme görüntüsünün oluşturulmasıdır. Bunun nasıl olduğunu aşamalı olarak ele alalım.
dd if = / dev / sıfır of =. / hdd.img bs = 512 sayı = 16065 1> / dev / null 2> & 1
Bu komut, daha fazla çalışmanın gerçekleştirileceği bir görüntü oluşturur. Sektör sayısı rastgele seçilmedi: 16065 = 255 * 63. Varsayılan olarak, fdsik diskle CHS geometrisine sahipmiş gibi çalışır, burada Başlıklar (H) = 255, Sektörler (S) = 63 ve Silindirler (C) ) disk boyutuna bağlıdır. Böylece, fdsik yardımcı programının varsayılan geometriyi değiştirmeden çalışabileceği minimum disk boyutu 512 * 255 * 63 * 1 = 8225280 bayttır, burada 512 sektör boyutu ve 1 silindir sayısıdır.
Ardından, bir bölüm tablosu oluşturulur:
Lostup / dev / loop1 ./hdd.img (eko c; yankı u; yankı n; yankı p; yankı 1; yankı; yankı; yankı a; yankı 1; yankı t; yankı c; yankı w;) | fdisk / dev / loop1 1> / dev / null 2> & 1 || NS
İlk komut, hdd.img dosyasını / dev / loop1 blok aygıtına bağlar ve dosyanın bir aygıt gibi ele alınmasına izin verir. İkinci komut, / dev / loop1 cihazında, FAT32 dosya sistemi ile etiketlenmiş, tüm diski kaplayan, diskin 1 birincil önyükleme bölümünü içeren bir bölüm tablosu oluşturur.
Daha sonra oluşturulan bölümü formatlıyoruz. Bunu yapmak için, onu bir blok cihaz olarak monte etmeniz ve biçimlendirme yapmanız gerekir.
Lostup / dev / loop2 ./hdd.img \ --offset `echo \` fdisk -lu / dev / loop1 | sed -n 10p | awk "($$ 3 yazdırın)" \ `* 512 | bc` \ --sizelimit `echo \` fdisk -lu / dev / loop1 | sed -n 10p | awk "($$ 4 yazdırın)" \ `* 512 | bc`lostup -d / dev / loop1
İlk komut, önceden oluşturulmuş bölümü / dev / loop2 aygıtına bağlar. –offset seçeneği bölümün başlangıcını, –sizelimit ise bölümün sonunu belirtir. Her iki parametre de fdisk komutu kullanılarak elde edilir.
mkdosfs / dev / loop2
mkdosfs yardımcı programı, bölümü FAT32 dosya sistemine biçimlendirir.
Çekirdeği doğrudan oluşturmak için, klasik makefile sözdiziminde daha önce tartışılan komutlar kullanılır.
Şimdi GRUB'u bir bölüme nasıl kuracağımızı görelim:
mkdir -p tempdir # geçici bir dizin oluşturur mount / dev / loop2 tempdir # bölümü mkdir dizinine bağlar tempdir / boot # cp bölümünde bir / boot dizini oluşturur -r grub tempdir / boot / # grub klasörünü / dizinine kopyalar boot cp kernel.bin tempdir / # çekirdeği bölümün kök dizinine kopyalar sleep 1 # Ubuntu için bekle umount / dev / loop2 # geçici klasörün bağlantısını kes rm -r tempdir # geçici klasörü sil Lostup -d / dev / loop2 # bölümün bağlantısını kes
Yukarıdaki komutları yürüttükten sonra görüntü GRUB'u kurmaya hazır olacaktır. Aşağıdaki komut, GRUB'u hdd.img disk görüntüsünün MBR'sine yükler.
echo "aygıt (hd0) hdd.img \ n \ kök (hd0,0) \ n \ kurulum (hd0) \ n \ çık \ n" | grub --batch 1> / dev / boş

Test için her şey hazır!

6. Adım: Başlatın:

Derlemek için şu komutu kullanın:
hepsini yapmak
Bundan sonra kernel.bin dosyası görünmelidir.
Önyüklenebilir bir disk görüntüsü oluşturmak için şu komutu kullanın:
sudo resim yap
Sonuç olarak hdd.img dosyası görünmelidir.
Artık hdd.img disk görüntüsünden önyükleme yapabilirsiniz. Bunu aşağıdaki komutla kontrol edebilirsiniz:
qemu -hda hdd.img -m 32
veya:
qemu-system-i386 -hda hdd.img



Gerçek bir makineyi kontrol etmek için bu görüntüyü bir flash sürücüye eklemeniz ve ondan önyükleme yapmanız gerekir. Örneğin aşağıdaki komutla:
sudo dd if =. / hdd.img = / dev / sdb

Özetle, yapılan işlemler sonucunda sistem programlama alanında çeşitli deneyler yapmanızı sağlayan bir dizi kaynak ve komut dosyası elde edildiğini söyleyebiliriz. Hipervizörler ve işletim sistemleri gibi sistem yazılımları oluşturmaya yönelik ilk adımı atmak.

Bazı uygulamaların Windows'ta çalışması için yükseltilmiş haklar gerekir ve yönetici olarak çalıştırılması gerekir. Bu, isteği görüntüler " Kullanıcı Hesap Denetimi"(Kullanıcı Hesabı Denetimi veya UAC), sistemin uygulamayı başlatmak için onayınızı istediği.

Birçok kullanıcı, yanlışlıkla Kullanıcı Hesabı Denetimi'nin engel olduğuna inanıyor ve onu kapatıyor. Aynı zamanda, bilgisayarın güvenliği ciddi şekilde etkilenir. Uygulamaları başlatmak için artık kullanıcı onayı gerekmiyor ve herhangi bir kötü amaçlı yazılım sorunsuz bir şekilde başlatılıp çalıştırılabilir. Antivirüsün varlığı da %100 bilgisayar güvenliğini garanti edemez.

Bu makalede, UAC'yi (tamamen veya kısmen) devre dışı bırakmadan ve güvenlikten ödün vermeden seçilen uygulamaları yönetici olarak çalıştırma sürecini nasıl basitleştireceğinizi göstereceğim.

Uygulamayı yönetici olarak çalıştırmanın birkaç yolu vardır:

Örnek olarak, koşacağız Komut satırı(cmd) yönetici olarak.

Yöntem numarası 1 (normal) - farenin sağ düğmesiyle başlat (UAC isteği görüntülenir)

Simgeye sağ tıklayın istenen uygulama ve seçin " Yönetici olarak çalıştır":

Yöntem numarası 2 - " kullanarak başlat Ctrl + Üst Karakter + Enter"(UAC istemi görüntülenir)

Tıklamak Başlangıç, arama çubuğuna şunu yazın istediğin komut ve bas Ctrl + Üst Karakter + Enter.

Yöntem numarası 3 - başlatmayı kısayolun özelliklerinde yönetici olarak ayarlayın (UAC isteği görüntülenir)

İstediğiniz kısayola sağ tıklayın ve " Özellikler".

Git " Etiket", Tıklayın" bunlara ek olarak", kutuyu kontrol et" Yönetici olarak çalıştır":


Veya " uyumluluk"ve kutuyu işaretleyin" Bu programı yönetici olarak çalıştırın":

Yöntem numarası 4 - görev zamanlayıcıyı kullanarak seçili uygulamalar için başlatmayı basitleştirin (UAC isteği görüntülenmez)

Önemli! Bu yöntem yalnızca gruba dahil olan hesaplar için çalışır. Yöneticiler... Sıradan kullanıcılar için çalışmayacaktır, çünkü onların tavan hakları sınırlıdır.

Gelelim en ilginç yola. Sürekli çalıştırdığınız bir uygulama varsa ve güvenilir bir yazılım üreticisinden alınmışsa, örneğin bu Windows uygulaması- lansmanı basitleştirebilirsiniz. için bir kısayol oluşturun istenilen program 2 dakikadan fazla sürmez ve bu, gelecekte gereksiz eylemlerden kurtulmanızı sağlar. Başlatmak görev Zamanlayıcısı (Başlangıç---> Tüm programlar ---> Standart---> Hizmet---> Görev Zamanlayıcısı) ve tıklayın " Görev oluştur":

belirtiyoruz İsim yeni bir görev için ve kutuyu işaretleyin " En yüksek haklarla yürütün":

sekmeye git Hareketler, basmak " Oluşturmak", sonraki pencerede tıklayın" genel bakış":

İstediğiniz uygulamanın yolunu belirtin ve " Açık":



Resmi büyüt

Tıklamak " Tamam":

Zamanlayıcıyı kapatın ve bir kısayol oluşturmaya devam edin.

Masaüstünde bir kısayol oluşturmak için sağ tıklayın, " Oluşturmak" ---> "Etiket":


alanında Mülk konumu tanıtıyoruz:

Schtasks / çalıştır / tn cmd_admin

nerede cmd_admin- oluşturduğumuz görevin adı. Ad boşluk içeriyorsa, tırnak içine alınmalıdır.

Kısayolun adını belirledik:



Resmi büyüt

Kısayol oluşturuldu ve kullanıma hazır.

Simgeyi değiştirmek için - kısayola sağ tıklayın, " Özellikler":

Git " Etiket"ve bas " Simgeyi Değiştir":

"genel bakış..."

Programın yolunu belirtiyoruz:



Resmi büyüt

İstediğiniz simgeyi seçin ve her iki pencereyi de " ile kapatın. Tamam":

Artık istenen uygulamanın yönetici olarak başlatılması, oluşturulan kısayola çift tıklanarak gerçekleştirilir, UAC istemi görüntülenmez ve güvenlik bozulmadan kalır.

Otomasyon için yardımcı program "Yöntem numarası 4"

Çok sayıda program için kısayollar oluşturmanız gerekiyorsa, yardımcı programı kullanmak uygundur.

Yardımcı programla çalışmak iki basit adımdan oluşur:

  • Kurulum
  • Yürütülebilir dosyayı (* .exe, * .bat, * .cmd) yardımcı program kısayoluna sürükleyip bırakın:


Çalışan bir programa otomatik odaklanma

Uygulamaları zamanlayıcıdan başlatmanın özelliği, odağın pencereye aktarılmaması ve örneğin komut satırına bir komut yazmak için ayrıca pencereye tıklamanız gerektiğidir. Bu davranış, rutin zamanlanmış işlemleri otomatikleştirmeye yardımcı olabilir, ancak Yöntem # 4 için her zaman uygun değildir.

"Geçici çözüm" için birkaç yöntem vardır. Biraz farklı çalışırlar, bu yüzden sizin için en uygun olanı seçin. Birincisi, programları çalıştırmak için, ikincisi ise komut dosyalarını çalıştırmak için daha uygundur.

Görev oluştururken ekleyin:

Başlat komutunu kullanma

Program veya komut dosyası:

Argümanlar:

/ c start / d "program_path" dosyaadı.exe

/ c start / d "C: \ Windows \ System32 \" cmd.exe

NirCmd yardımcı programını kullanma

Program veya komut dosyası:

Path_to_nircmd \ nircmd.exe

Argümanlar:

Exec gösterisi "program_path\filename.exe"

Exec gösterisi "C: \ Windows \ System32 \ cmd.exe"

Yönetici olarak "Çalıştır" iletişim kutusunu çalıştır

Komut satırını başlatmaya benzeterek, " Uygulamak" ve içine girilen komutlar da yönetici adına çalıştırılacaktır. Bu yaklaşımın rahatlığı, daha önce kullanılan komutların listesinin kaydedilmesi ve listeden ihtiyacınız olanı seçebilmenizdir.


Zamanlayıcıda bir görev oluştururken, " Eylem oluştur"belirtiniz:

alanında" Program veya komut dosyası":

Rundll32

alanında" Argüman ekle":

Shell32.dll, # 61

Yardımcı programı indirin, paketinden çıkarın. Komut satırını başlatıyoruz, gerekli komutu giriyoruz, sözdizimi oldukça basit:

<путь к утилите> <путь к нужному приложению>


Bir UAC istemi görünecek ve uygulama yönetici olarak çalışacaktır.

Not: V bağlam menüsü Windows 7, dosya yolunu kopyalamak için çok kullanışlı bir işleve sahiptir: basılı tutun Vardiya, dosyaya sağ tıklayın, " Yol olarak kopyala".


Yönetici şifresini girmeden programları kullanıcı tarafından yönetici olarak çalıştırın

Önemli! Bu yöntem güvenli değildir, çünkü sınırlı bir kullanıcının tüm haklara sahip kod çalıştırmasına izin verir. Kurnaz bir kullanıcı veya kötü amaçlı yazılım bundan yararlanabilir ve sistemi tehlikeye atabilir.

Başka bir ilginç görev düşünün: Hesabınız Windows girişi yöneticiler grubuna ait, bir veya daha fazla hesaplar kullanıcı grubuna dahildir. Kullanıcının yükseltme gerektiren bir programı çalıştırması gerekir. Genellikle şöyle görünür: kullanıcı dosyaya sağ tıklar ve yönetici parolasını isteyen "Yönetici Olarak Çalıştır"ı seçer:


Tabii ki, kullanıcılara yönetici şifresi vermek iyi bir fikir değil. Bunu aşmak için Alexey Kuryakin'in AdmiLink yardımcı programını kullanacağız. Onun yardımı ile yönetici, kullanıcının gerekli programı başlatması için bir kısayol oluşturabilir, ancak bir kısayol oluştururken yönetici şifresinin yalnızca 1 kez girilmesi gerekir. Kullanıcı programı başlattığında şifre şifreli olarak iletilecektir.



Bu yöntem, program yalnızca yönetici olarak çalıştırılabiliyorsa ve geliştirici bildirimde bu koşulu belirtmeyi unutmadıysa işe yarar. Ancak, hem normal modda hem de yönetici adına başlatılabilen çok sayıda eski program veya program hala vardır (bu durumda, farklı bir dizi işlev kullanılabilir olacaktır). AdmiLink kullanarak böyle bir programı çalıştırmayı denediğinizde, normal modda (yönetici ayrıcalıkları olmadan) başlar. Ve kutuyu işaretlemeye çalışırsanız "Yöntem numarası 3. Yazarın orijinal stili kaydedilir.

gastroguru 2017