Comment créer un raccourci qui permet aux utilisateurs réguliers d'exécuter une application avec des droits d'administrateur. Faciliter l'exécution d'applications sous Windows en tant qu'administrateur sans désactiver l'UAC

Que faire si vous avez besoin d'exécuter un programme mais que vous ne voulez pas l'installer ? Zero Install à la rescousse !

Des milliards de personnes dans le monde utilisent des ordinateurs ou des ordinateurs portables sur système opérateur Les fenêtres. Habituellement, nous installons des programmes, après quoi ils occupent de l'espace disque libre et utilisent RAM... Cela ralentit la vitesse de l'ordinateur.

Aujourd'hui, nous allons vous montrer comment augmenter les performances de votre ordinateur et réduire la charge sur la mémoire. Pour ce faire, vous devez exécuter les programmes requis sans les installer.

Comment exécuter le programme sans installation ?

1. Téléchargez Zero Install.

Tout d'abord, téléchargez le logiciel Zero Install, qui vous permettra d'exécuter des programmes sans avoir à les installer sur votre ordinateur.

2. Installez Zero Install.

Après avoir téléchargé Zero Install, double-cliquez sur le fichier pour l'installer. Puis cours nouveau programme sur ton ordinateur.

3. Cliquez sur dansla maçonnerie "Catalogue".

Dès que Zero Install est lancé sur l'ordinateur ou Ordinateur portable Windows, vous devez aller dans l'onglet "Catalogue". Cliquez ici sur le bouton "Actualiser la liste" pour mettre à jour la liste des programmes disponibles.

4. Sélectionnez un programme à exécuter.

Regarde bien liste complète programmes disponibles. Si vous trouvez le programme dont vous avez besoin, sélectionnez-le et cliquez sur "Exécuter". Certains programmes peuvent choisir Navigateur Firefox ou Mozilla pour exécuter. Attendez qu'il soit complètement chargé Logiciel, après quoi vous pouvez l'exécuter sur votre ordinateur sans l'installer.


Résumer

Si votre ordinateur n'a pas assez de mémoire libre ou de puissance pour exécuter le programme, vous pouvez utiliser Zero Install. Je pense que c'est un excellent moyen d'éviter d'encombrer votre ordinateur avec des programmes dont vous avez besoin en même temps.

De plus, votre ordinateur peut ne pas avoir assez de puissance pour exécuter certains programmes comme Eclipse IDE, JetBrains, NetBeans, etc. Ce sont des programmes de développement vraiment lourds qui consomment un grand nombre de mémoire vive.

Zero Install vous aidera à exécuter ces programmes et bien d'autres sans les installer sur votre ordinateur.

La chose la plus importante n'a pas été décrite de manière suffisamment détaillée : comment exécuter ce code sur du matériel réel ? Comment créer le vôtre disque de démarrage? Dans cet article, nous répondrons à toutes ces questions en détail (certaines de ces questions ont été traitées dans l'article précédent, mais pour faciliter la lecture, nous nous permettrons une petite duplication du matériel).

Sur Internet, il existe un grand nombre de descriptions et de tutoriels sur la façon d'écrire votre propre mini-OS, il existe même des centaines de petits systèmes d'exploitation de passe-temps prêts à l'emploi. L'une des ressources les plus intéressantes sur ce sujet, que je voudrais souligner, est le portail osdev.org. Pour compléter l'article précédent sur PCI (et la possibilité d'écrire des articles ultérieurs sur les différentes fonctions présentes dans tout système d'exploitation moderne), nous décrirons instructions étape par étape sur la création d'un disque amorçable avec un programme familier en langage C. Nous avons essayé d'écrire autant de détails que possible afin que vous puissiez tout comprendre par vous-même.

Alors, l'objectif : faire le moins d'efforts possible, créer le vôtre clé USB amorçable, qui imprime simplement le classique "Hello World" sur l'écran de l'ordinateur.

Pour être plus précis, nous devons « entrer » dans le mode protégé avec la pagination et les interruptions désactivées - le mode le plus simple du processeur avec le comportement habituel d'un simple programme de console. Le moyen le plus intelligent d'atteindre un tel objectif est de construire un noyau qui prend en charge le format multiboot et de le démarrer en utilisant le populaire chargeur de démarrage Grub... Une alternative à cette solution consiste à écrire votre propre enregistrement de démarrage de volume (VBR), qui chargerait le propre chargeur écrit (loader). Un chargeur de démarrage décent, au moins, devrait pouvoir fonctionner avec un disque, avec un système de fichiers et analyser des images elf. Cela signifie que vous devez écrire beaucoup de code assembleur, et beaucoup de code C. Bref, il est plus facile d'utiliser Grub, qui sait déjà faire tout ce que vous devez faire.

Pour commencer, d'autres actions nécessitent un certain ensemble de compilateurs et d'utilitaires. Le moyen le plus simple est d'utiliser une sorte de Linux (par exemple, Ubuntu), car il contiendra déjà tout ce dont vous avez besoin pour créer une clé USB amorçable. Si vous avez l'habitude de travailler sous Windows, vous pouvez configurer machine virtuelle avec Linux (en utilisant Virtual Box ou VMware Workstation).

Si vous utilisez Linux Ubuntu, vous devez tout d'abord installer plusieurs utilitaires :
1. Larve. Pour ce faire, utilisez la commande :

Sudo apt-get install grub

2. Qemu. Il faut tout tester et déboguer rapidement (Lien vers l'article sur le débogueur), pour cela, la commande est similaire :

Sudo apt-get install qemu

Notre plan ressemble maintenant à ceci :
1.Créez un programme C qui imprime une chaîne à l'écran.
2. construisez à partir de celle-ci une image (kernel.bin) au format miniboot afin qu'elle soit disponible pour le démarrage à l'aide de GRUB.
3. Créez un fichier image disque amorçable et formatez-le.
4. installez Grub sur cette image.
5. copiez le programme créé (kernel.bin) sur le disque.
6. écrivez l'image sur un support physique ou exécutez-la dans qemu.

et le processus de démarrage du système :

Pour ce faire, vous devrez créer plusieurs fichiers et répertoires :

Étape 1. Génération du code du programme cible (noyau) :

Créez un fichier kernel.c contenant le code suivant pour imprimer un message à l'écran :

#include "printf.h" #include "screen.h" #include "types.h" void main (void) (clear_screen (); printf ("n >>> Hello World! n");)

Tout est familier et simple ici. L'ajout des fonctions printf et clear_screen sera discuté plus tard. En attendant, nous devons compléter ce code avec tout le nécessaire pour qu'il puisse être chargé par Grub.
Pour que le noyau soit au format multiboot, la structure suivante est nécessaire dans les 8 premiers kilo-octets de l'image du noyau :

Si toutes les conditions spécifiées sont remplies, Grub transmet un pointeur vers la structure d'information multiboot et la valeur 0x1BADB002 via les registres % eax et % ebx, respectivement. La structure d'information multiboot contient diverses informations, y compris une liste des modules chargés et leur emplacement, qui peuvent être nécessaires pour un chargement ultérieur du système.
Pour que le fichier avec le programme contienne les signatures nécessaires, nous allons créer un fichier loader.s, avec le contenu suivant :

Text .global loader # rendant le point d'entrée visible pour l'éditeur de liens # configuration de l'en-tête Multiboot - voir la documentation GRUB pour plus de détails l'en-tête .set CHECKSUM, - (MAGIC + FLAGS) # somme de contrôle requise .align 4 .long MAGIC .long FLAGS .long CHECKSUM # réserve l'espace initial de la pile du noyau .set STACKSIZE, 0x4000 # c'est-à-dire 16k. .lcomm stack, STACKSIZE # reserve 16k stack .comm mbd, 4 # nous l'utiliserons dans kmain .comm magic, 4 # nous l'utiliserons dans kmain loader: movl $ (stack + STACKSIZE),% esp # configurer la pile movl% eax, magic # Multiboot magic number movl% ebx, mbd # Multiboot data structure call main # call code C cli hang: hlt # stop machine devrait kernel return jmp hang

Regardons de plus près le code. Ce code, presque inchangé, est tiré de wiki.osdev.org/Bare_Bones. Comme gcc est utilisé pour la compilation, la syntaxe GAS est utilisée. Regardons de plus près ce que fait ce code.

Tout le code suivant tombera dans la section exécutable .text.

Chargeur global

Nous déclarons le symbole du chargeur visible pour l'éditeur de liens. Ceci est nécessaire car l'éditeur de liens utilisera le chargeur comme point d'entrée.

Set FLAGS, 0x0 # assign FLAGS = 0x0 .set MAGIC, 0x1BADB002 # assign MAGIC = 0x1BADB002 .set CHECKSUM, - (MAGIC + DRAPEAUX) # assign CHECKSUM = - (MAGIC + FLAGS) .align 4 # aligne les données suivantes de 4 octets. long MAGIC # place la valeur MAGIC à l'adresse courante .long FLAGS # place la valeur FLAGS à l'adresse courante .long CHECKSUM # place la valeur CHECKSUM à l'adresse courante

Ce code génère une signature au format Multiboot. La directive .set définit la valeur d'un caractère sur une expression à droite de la virgule. La directive .align 4 aligne le contenu suivant sur 4 octets. La directive .long stocke la valeur dans les quatre octets suivants.

Définissez STACKSIZE, 0x4000 # assignez STACKSIZE = 0x4000 .lcomm stack, STACKSIZE # réservez STACKSIZE octets. stack fait référence à la plage comm mbd, 4 # réserve 4 octets pour la variable mdb dans la zone COMMON .comm magic, 4 # réserve 4 octets pour la variable magic dans la zone COMMON

Pendant la botte ne configure pas la pile, et la première chose que le noyau doit faire est de configurer la pile, pour cela nous réservons 0x4000 (16Kb) octets. La directive .lcomm réserve le nombre d'octets après la virgule dans la section .bss. Le nom de la pile ne sera visible que dans le fichier compilé. La directive ..comm fait la même chose que .lcomm, mais le nom du symbole sera déclaré globalement. Cela signifie qu'en écrivant la ligne suivante dans le code C, nous pouvons l'utiliser.
magie externe

Et maintenant la dernière partie :

Loader: movl $ (stack + STACKSIZE),% esp # initialiser la pile movl% eax, magic # write% eax to magic movl% ebx, mbd # write% ebx to mbd call main # call main function cli # désactiver les interruptions du blocage matériel : hlt # arrête le processeur jusqu'à ce que l'interruption se produise jmp hang # saute à la balise volante

La première instruction consiste à stocker la valeur en haut de la pile dans le registre % esp. Au fur et à mesure que la pile croît vers le bas, % esp stocke l'adresse de la fin de la plage allouée à la pile. Les deux instructions suivantes stockent dans les plages de 4 octets précédemment réservées les valeurs que Grub passe dans les registres% eax,% ebx. Ensuite, la fonction principale est appelée, qui est déjà écrite en C. Si cette procédure revient, le processeur entrera dans une boucle.

Étape 2. Préparez du code supplémentaire pour le programme (bibliothèque système) :

Étant donné que l'ensemble du programme est écrit à partir de zéro, la fonction printf doit être écrite à partir de zéro. Pour ce faire, vous devez préparer plusieurs fichiers.
Créons un dossier commun et inclus :

Mkdir commun mkdir inclure

Créons un fichier commonprintf.c qui contiendra l'implémentation de la fonction printf familière. L'intégralité du fichier peut être extraite du projet www.bitvisor.org/. Le chemin d'accès au fichier dans les sources bitvisor : core / printf.c. Dans le fichier printf.c copié depuis bitvisor, pour une utilisation dans le programme cible, vous devez remplacer les lignes :

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

par lignes :

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

Ensuite, supprimez la fonction printf_init_global et toutes ses références dans ce fichier :

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

Supprimez ensuite la variable printf_lock et toutes les références à celle-ci dans ce fichier :

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

La fonction printf utilise la fonction putchar, qui doit également être écrite. Pour ce faire, créez un fichier commonscreen.c avec le contenu suivant :

#include "types.h" #define GREEN 0x2 #define MAX_COL 80 // Nombre maximum de colonnes #define MAX_ROW 25 // Nombre maximum de lignes #define VRAM_SIZE (MAX_COL * MAX_ROW) // Taille de l'écran, en "s courts # define DEF_VRAM_BASE 0xb8000 // Base par défaut pour la mémoire vidéo static unsigned char curr_col = 0; static unsigned char curr_row = 0; // Ecrit le caractère à l'emplacement actuel de l'écran #define PUT (c) (((unsigned short *) (DEF_VRAM_BASE)) [ (curr_row * MAX_COL) + curr_col] = (VERT<< 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;) pause ; case "b": if (curr_col> 0) (curr_col - = 1; PUT ("");) break ; par défaut : METTRE (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 ; je< VRAM_SIZE; i++) cons_putc(" "); curr_col = 0; curr_row = 0; }

Le code ci-dessus contient une logique simple pour imprimer des caractères à l'écran en mode texte. Dans ce mode, deux octets permettent d'écrire un caractère (l'un avec le code du caractère, l'autre avec ses attributs), écrit directement dans la mémoire vidéo affichée immédiatement à l'écran et à partir de l'adresse 0xB8000. La résolution de l'écran est de 80x25 caractères. L'impression directe d'un symbole s'effectue à l'aide de la macro PUT.
Maintenant, seuls quelques fichiers d'en-tête sont manquants :
1. Le fichier includescreen.h. Déclare la fonction putchar, qui est utilisée dans la fonction printf. Contenu du fichier :

#ifndef _SCREEN_H #define _SCREEN_H void clear_screen (void); void putchar (int c); #fin si

2. Fichier includeprintf.h. Déclare la fonction printf, qui est utilisée dans main. Contenu du fichier :

#ifndef _PRINTF_H #define _PRINTF_H int printf (const char * format, ...); #fin si

3. Le fichier includestdarg.h. Déclare des fonctions d'itération sur des arguments dont le nombre n'est pas connu à l'avance. L'intégralité du fichier provient du projet www.bitvisor.org/. Le chemin d'accès au fichier dans le code du projet bitvisor est includecorestdarg.h.
4. Fichier includetypes.h. Déclare NULL et size_t. Contenu du fichier :

#ifndef _TYPES_H #define _TYPES_H #define NULL 0 typedef unsigned int size_t; #fin si

Ainsi, les dossiers include et common contiennent le code de bibliothèque système minimum dont tout programme a besoin.

Étape 3. Créez un script pour l'éditeur de liens :

Créez un fichier linker.ld qui sera utilisé par l'éditeur de liens pour générer le fichier programme cible (kernel.bin). Le fichier doit contenir les éléments suivants :

ENTREE (chargeur) LMA = 0x0010000; SECTIONS (. = LMA; .multiboot ALIGN (0x1000): (loader.o (.text)) .text ALIGN (0x1000): (* (. Text)) .rodata ALIGN (0x1000): (* (. Rodata *) ) .data ALIGN (0x1000): (* (. data)) .bss: (* (COMMON) * (. bss)) / DISCARD /: (* (. comment)))

La fonction intégrée ENTRY() nous permet de définir le point d'entrée de notre noyau. C'est à cette adresse que grub transférera le contrôle après le chargement du noyau. L'éditeur de liens utilisera ce script pour créer un fichier binaire ELF. Un fichier ELF se compose d'un ensemble de segments et de sections. La liste des segments est contenue dans la table d'en-tête du programme, la liste des sections est dans la table d'en-tête de section. L'éditeur de liens fonctionne avec des sections, le chargeur d'images (dans notre cas c'est GRUB) avec des segments.


Comme vous pouvez le voir sur la figure, les segments sont constitués de sections. L'un des champs décrivant la section est l'adresse virtuelle à laquelle la section doit être située au moment de l'exécution. En fait, un segment possède 2 champs qui décrivent son emplacement : l'adresse virtuelle du segment et l'adresse physique du segment. L'adresse virtuelle du segment est l'adresse virtuelle du premier octet du segment au moment de l'exécution du code, l'adresse physique du segment est l'adresse physique à laquelle le segment doit être chargé. Pour les programmes d'application, ces adresses sont toujours les mêmes. Grub charge les segments d'image à leur adresse physique. Puisque Grub ne configure pas la pagination, l'adresse virtuelle du segment doit correspondre à son adresse physique, puisque dans notre programme mémoire virtuelle pas non plus configurable.

LMA ;

Cette expression indique à l'éditeur de liens que toutes les sections suivantes sont après l'adresse LMA.

ALIGNER (0x1000)

La directive ci-dessus signifie que la section est alignée sur 0x1000 octets.

Multiboot ALIGN (0x1000): (loader.o (.text))

Une section multiboot distincte, qui inclut la section .text du fichier loader.o, est conçue pour garantir que la signature du format multiboot pénètre dans les 8 premiers Ko de l'image du noyau.

Bss : (* (COMMUN) * (. Bss))

* (COMMON) est la zone dans laquelle la mémoire est réservée par les instructions .comm et.lcomm. Nous le plaçons dans la section .bss.

/ ABANDONNER / : (* (. Commentaire))

Toutes les sections marquées comme DISCARD sont supprimées de l'image. Dans ce cas, nous supprimons la section.comment, qui contient des informations sur la version de l'éditeur de liens.

Compilons maintenant le code dans un fichier binaire avec les commandes suivantes :

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 chargeur.o

En utilisant objdump, voyons à quoi ressemble l'image du noyau après la liaison :

Objdump -ph ./kernel.bin



Comme vous pouvez le voir, les sections de l'image sont les mêmes que celles décrites dans le script de l'éditeur de liens. Le lieur a formé 3 segments à partir des sections décrites. Le premier segment comprend les sections multiboot, .text, .rodata et a une adresse virtuelle et physique de 0x0010000. Le deuxième segment contient les sections .data et .bss et est situé à 0x00104000. Vous êtes donc prêt à télécharger ce fichier avec Grub.

Étape 4. Préparez le chargeur de démarrage Grub :
Créer un dossier grub :

Mkdir grub

Copiez plusieurs fichiers Grub dans ce dossier, qui sont nécessaires pour l'installer sur l'image (les fichiers suivants existent si Grub est installé sur le système). Pour ce faire, vous devez exécuter les commandes suivantes :

Cp / usr / lib / grub / i386-pc / stage1 ./grub/ cp / usr / lib / grub / i386-pc / stage2 ./grub/ cp / usr / lib / grub / i386-pc / fat_stage1_5 ./grub /

Créez un fichier grub/menu.lst, avec le contenu suivant :

Timeout 3 par défaut 0 titre mini_os root (hd0,0) kernel /kernel.bin

Étape 5. Automatisez et créez une image amorçable :

Pour automatiser le processus de construction, nous utiliserons l'utilitaire make. Pour ce faire, nous allons créer un makefile qui construira le code source de la compilation, construira un noyau et créera une image de démarrage. Le Makefile doit avoir le contenu suivant :

CC = gcc CFLAGS = -Wall -fno-builtin -nostdinc -nostdlib LD = ld OBJFILES = loader.o common / printf.o common / screen.o kernel.o image: @echo "Creating hdd.img ..." @ dd if = / dev / zero of =. / hdd.img bs = 512 count = 16065 1> / dev / null 2> & 1 @echo "Création de la première partition FAT32 amorçable ..." @losetup / dev / loop1 ./ hdd .img @ (écho c; écho u; écho n; écho p; écho 1; écho; écho; écho a; écho 1; écho t; écho c; écho w;) | fdisk / dev / loop1 1> / dev / null 2> & 1 || true @echo "Montage de la partition sur / dev / loop2 ..." @losetup / dev / loop2 ./hdd.img --offset `echo` fdisk -lu / dev / loop1 | sed -n 10p | awk "(imprimer $$ 3)" `* 512 | bc` --sizelimit `echo` fdisk -lu / dev / loop1 | sed -n 10p | awk "(imprimer $$ 4)" `* 512 | bc` @losetup -d / dev / loop1 @echo "Formater la partition ..." @mkdosfs / dev / loop2 @echo "Copier les fichiers noyau et grub sur la partition ..." @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 "Installation de GRUB. .. "@echo" périphérique (hd0) hdd.img n root (hd0,0) n setup (hd0) n quitn "| grub --batch 1> / dev / null @echo "Terminé !" all : kernel.bin reconstruire : nettoyer tout .s.o : as -o [email protégé] $< .c.o: $(CC) -Iinclude $(CFLAGS) -o [email protégé]-c $< kernel.bin: $(OBJFILES) $(LD) -T linker.ld -o [email protégé]$ ^ nettoyer : rm -f $ (OBJFILES) hdd.img kernel.bin

Le fichier déclare deux objectifs principaux : all - compile le noyau, et image - qui crée un disque de démarrage. La cible all, comme le makefile habituel, contient les sous-objectifs .so et .co, qui compilent les fichiers * .s et * .c en fichiers objets (* .o), ainsi qu'une cible pour générer kernel.bin, qui appelle l'éditeur de liens avec le script créé précédemment. Ces objectifs exécutent exactement les mêmes commandes que celles spécifiées à l'étape 3.
Le plus intéressant ici est la création image de démarrage hdd.img (image cible). Considérons par étapes comment cela se produit.

Dd if = / dev / zero of =. / Hdd.img bs = 512 count = 16065 1> / dev / null 2> & 1

Cette commande crée une image avec laquelle d'autres travaux auront lieu. Le nombre de secteurs n'a pas été choisi au hasard : 16065 = 255 * 63. Par défaut, fdsik fonctionne avec le disque comme s'il avait une géométrie CHS, dans laquelle Headers (H) = 255, Sectors (S) = 63, et Cylinders © dépend sur la taille du disque ... Ainsi, la taille de disque minimale avec laquelle l'utilitaire fdsik peut fonctionner sans modifier la géométrie par défaut est de 512 * 255 * 63 * 1 = 8225280 octets, où 512 est la taille du secteur et 1 est le nombre de cylindres.
Ensuite, une table de partition est créée :

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

La première commande monte le fichier hdd.img sur le périphérique bloc /dev/loop1, permettant au fichier d'être traité comme un périphérique. La deuxième commande crée une table de partition sur le périphérique/dev/loop1, qui contient 1 primaire partition de démarrage disque qui occupe tout le disque, étiqueté avec le système de fichiers FAT32.
Ensuite, nous formatons la section créée. Pour ce faire, vous devez le monter en tant que périphérique bloc et effectuer le formatage.

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

La première commande monte la partition précédemment créée sur le périphérique /dev/loop2. L'option –offset spécifie le début de la section et –sizelimit spécifie la fin de la section. Les deux paramètres sont obtenus à l'aide de la commande fdisk.

Mkdosfs / dev / loop2

L'utilitaire mkdosfs formate la partition en système de fichiers FAT32.
Pour construire le noyau directement, les commandes décrites précédemment dans la syntaxe classique du makefile sont utilisées.
Voyons maintenant comment installer GRUB sur une partition :

Mkdir -p tempdir # crée un répertoire temporaire mount / dev / loop2 tempdir # monte la partition dans le répertoire mkdir tempdir / boot # crée un répertoire / boot sur la partition cp -r grub tempdir / boot / # copie le dossier grub dans / boot cp kernel.bin tempdir / # copie le noyau à la racine de la partition sleep 1 # attend Ubuntu umount / dev / loop2 # démonte le dossier temporaire rm -r tempdir # supprime le dossier temporaire losetup -d / dev / loop2 # démonter la partition

Après avoir exécuté les commandes ci-dessus, l'image sera prête à installer GRUB. La commande suivante installe GRUB dans le MBR de l'image disque hdd.img.

Echo "périphérique (hd0) hdd.img n racine (hd0,0) n configuration (hd0) n quitn" | grub --batch 1> / dev / null

Tout est prêt à être testé !

Étape 6. Lancez :

Pour compiler, utilisez la commande :

Fait tout

Après quoi le fichier kernel.bin devrait apparaître.
Pour créer une image disque amorçable, utilisez la commande :

Sudo faire une image

Par conséquent, le fichier hdd.img devrait apparaître.
Vous pouvez maintenant démarrer à partir de l'image disque hdd.img. Vous pouvez le vérifier avec la commande suivante :

Qemu -hda hdd.img -m 32

Qemu-system-i386 -hda hdd.img




Pour vérifier sur une vraie machine, vous devez ajouter cette image sur un lecteur flash et démarrer à partir de celui-ci. Par exemple avec la commande suivante :

Sudo dd si =. / Hdd.img de = / dev / sdb

En résumé, nous pouvons dire qu'à la suite des actions entreprises, un ensemble de sources et de scripts est obtenu qui vous permet de réaliser diverses expériences dans le domaine de la programmation système. Faire le premier pas vers la création de logiciels système tels que des hyperviseurs et des systèmes d'exploitation.

La chose la plus importante n'a pas été décrite de manière suffisamment détaillée : comment exécuter ce code sur du matériel réel ? Comment créer mon propre disque amorçable ? Dans cet article, nous répondrons à toutes ces questions en détail (certaines de ces questions ont été traitées dans l'article précédent, mais pour faciliter la lecture, nous nous permettrons une petite duplication du matériel).

Sur Internet, il existe un grand nombre de descriptions et de didacticiels sur la façon d'écrire votre propre mini-OS, il existe même des centaines de petits systèmes d'exploitation de passe-temps prêts à l'emploi. L'une des ressources les plus intéressantes sur ce sujet, que je voudrais souligner, est le portail osdev.org. Pour compléter l'article précédent sur PCI (et la possibilité d'écrire des articles ultérieurs sur les différentes fonctions présentes dans tout système d'exploitation moderne), nous décrirons des instructions pas à pas pour créer un disque amorçable avec un programme familier en C. Nous essayé d'écrire le plus en détail possible afin que tout puisse être compris vous-même.

Donc, l'objectif : en dépensant le moins d'effort possible, créez votre propre clé USB amorçable qui imprime simplement le classique "Hello World" sur l'écran de l'ordinateur.

Pour être plus précis, nous devons « entrer » dans le mode protégé avec la pagination et les interruptions désactivées - le mode le plus simple du processeur avec le comportement habituel d'un simple programme de console. La façon la plus intelligente d'y parvenir est de créer un noyau multiboot et de le démarrer à l'aide du populaire chargeur de démarrage Grub. Une alternative à cette solution consiste à écrire votre propre enregistrement de démarrage de volume (VBR), qui chargerait le propre chargeur écrit (loader). Un chargeur de démarrage décent, au moins, devrait pouvoir fonctionner avec un disque, avec un système de fichiers et analyser des images elf. Cela signifie que vous devez écrire beaucoup de code assembleur, et beaucoup de code C. Bref, il est plus facile d'utiliser Grub, qui sait déjà faire tout ce que vous devez faire.

Pour commencer, d'autres actions nécessitent un certain ensemble de compilateurs et d'utilitaires. Le moyen le plus simple est d'utiliser une sorte de Linux (par exemple, Ubuntu), car il contiendra déjà tout ce dont vous avez besoin pour créer une clé USB amorçable. Si vous avez l'habitude de travailler sous Windows, vous pouvez configurer une machine virtuelle Linux (à l'aide de Virtual Box ou de VMware Workstation).

Si vous utilisez Linux Ubuntu, vous devez tout d'abord installer plusieurs utilitaires :
1. Larve. Pour ce faire, utilisez la commande :
sudo apt-get install grub

2. Qemu. Il faut que tout soit rapide, pour cela, la commande est similaire :
sudo apt-get install qemu

Notre plan ressemble maintenant à ceci :
1.Créez un programme C qui imprime une chaîne à l'écran.
2. construisez à partir de celle-ci une image (kernel.bin) au format miniboot afin qu'elle soit disponible pour le démarrage à l'aide de GRUB.
3. Créez un fichier image disque amorçable et formatez-le.
4. installez Grub sur cette image.
5. copiez le programme créé (kernel.bin) sur le disque.
6. écrivez l'image sur un support physique ou exécutez-la dans qemu.

Et le processus de démarrage du système :

Pour ce faire, vous devrez créer plusieurs fichiers et répertoires :

Étape 1. Génération du code du programme cible (noyau) :

Créez un fichier kernel.c contenant le code suivant pour imprimer un message à l'écran :

#include "printf.h" #include "screen.h" #include "types.h" void main (void) (clear_screen (); printf ("\ n >>> Hello World! \ n");)

Tout est familier et simple ici. L'ajout des fonctions printf et clear_screen sera discuté plus tard. En attendant, nous devons compléter ce code avec tout le nécessaire pour qu'il puisse être chargé par Grub.
Pour que le noyau soit au format multiboot, la structure suivante est nécessaire dans les 8 premiers kilo-octets de l'image du noyau :

Si toutes les conditions spécifiées sont remplies, Grub transmet un pointeur vers la structure d'information multiboot et la valeur 0x1BADB002 via les registres % eax et % ebx, respectivement. La structure d'informations multiboot contient diverses informations, notamment la liste des modules chargés et leur emplacement, qui peuvent être nécessaires pour poursuivre le démarrage du système.
Pour que le fichier avec le programme contienne les signatures nécessaires, nous allons créer un fichier loader.s, avec le contenu suivant :

Text .global loader # rendant le point d'entrée visible pour l'éditeur de liens # configuration de l'en-tête Multiboot - voir la documentation GRUB pour plus de détails l'en-tête .set CHECKSUM, - (MAGIC + FLAGS) # somme de contrôle requise .align 4 .long MAGIC .long FLAGS .long CHECKSUM # réserve l'espace initial de la pile du noyau .set STACKSIZE, 0x4000 # c'est-à-dire 16k. .lcomm stack, STACKSIZE # reserve 16k stack .comm mbd, 4 # nous l'utiliserons dans kmain .comm magic, 4 # nous l'utiliserons dans kmain loader: movl $ (stack + STACKSIZE),% esp # configurer la pile movl% eax, magic # Multiboot magic number movl% ebx, mbd # Multiboot data structure call main # call code C cli hang: hlt # stop machine devrait kernel return jmp hang

Regardons de plus près le code. Ce code, presque inchangé, est tiré de wiki.osdev.org/Bare_Bones. Comme gcc est utilisé pour la compilation, la syntaxe GAS est utilisée. Regardons de plus près ce que fait ce code.
.texte
Tout le code suivant tombera dans la section exécutable .text.
.chargeur global
Nous déclarons le symbole du chargeur visible pour l'éditeur de liens. Ceci est nécessaire car l'éditeur de liens utilisera le chargeur comme point d'entrée.
.set FLAGS, 0x0 # assign FLAGS = 0x0 .set MAGIC, 0x1BADB002 # assign MAGIC = 0x1BADB002 .set CHECKSUM, - (MAGIC + DRAPEAUX) # assign CHECKSUM = - (MAGIC + DRAPEAUX) .align 4 # aligne les données suivantes de 4 octets .long MAGIC # place la valeur MAGIC à l'adresse courante .long FLAGS # place la valeur FLAGS à l'adresse courante .long CHECKSUM # place la valeur CHECKSUM à l'adresse courante
Ce code génère une signature au format Multiboot. La directive .set définit la valeur d'un caractère sur une expression à droite de la virgule. La directive .align 4 aligne le contenu suivant sur 4 octets. La directive .long stocke la valeur dans les quatre octets suivants.
.set STACKSIZE, 0x4000 # assigne STACKSIZE = 0x4000 .lcomm stack, STACKSIZE # réserve des octets STACKSIZE. stack fait référence à la plage comm mbd, 4 # réserve 4 octets pour la variable mdb dans la zone COMMON .comm magic, 4 # réserve 4 octets pour la variable magic dans la zone COMMON
Au démarrage, grub ne configure pas la pile, et la première chose que le noyau doit faire est de configurer la pile, pour cela nous réservons 0x4000 (16Kb) octets. La directive .lcomm réserve le nombre d'octets après la virgule dans la section .bss. Le nom de la pile ne sera visible que dans le fichier compilé. La directive ..comm fait la même chose que .lcomm, mais le nom du symbole sera déclaré globalement. Cela signifie qu'en écrivant la ligne suivante dans le code C, nous pouvons l'utiliser.
magie externe

Et maintenant la dernière partie :
loader: movl $ (stack + STACKSIZE),% esp # initialiser la pile movl% eax, magic # write% eax to magic movl% ebx, mbd # write% ebx to mbd call main # call main function cli # désactiver les interruptions du blocage matériel : hlt # arrête le processeur jusqu'à ce que l'interruption se produise jmp hang # saute à la balise volante

La première instruction consiste à stocker la valeur en haut de la pile dans le registre % esp. Au fur et à mesure que la pile croît vers le bas, % esp stocke l'adresse de la fin de la plage allouée à la pile. Les deux instructions suivantes stockent dans les plages de 4 octets précédemment réservées les valeurs que Grub passe dans les registres% eax,% ebx. Ensuite, la fonction principale est appelée, qui est déjà écrite en C. Si cette procédure revient, le processeur entrera dans une boucle.

Étape 2. Préparez du code supplémentaire pour le programme (bibliothèque système) :

Étant donné que l'ensemble du programme est écrit à partir de zéro, la fonction printf doit être écrite à partir de zéro. Pour ce faire, vous devez préparer plusieurs fichiers.
Créons un dossier commun et inclus :

Mkdir commun mkdir inclure

Créons un fichier common \ printf.c, qui contiendra l'implémentation de la fonction printf familière. Ce fichier peut être entièrement extrait du projet www.bitvisor.org. Le chemin d'accès au fichier dans les sources bitvisor : core / printf.c. Dans le fichier printf.c copié depuis bitvisor, pour une utilisation dans le programme cible, vous devez remplacer les lignes :

#include "initfunc.h" #include "printf.h" #include "putchar.h" #include "spinlock.h"
par lignes :
#include "types.h" #include "stdarg.h" #include "screen.h"

Ensuite, supprimez la fonction printf_init_global et toutes ses références dans ce fichier :

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

Supprimez ensuite la variable printf_lock et toutes les références à celle-ci dans ce fichier :
statique spinlock_t printf_lock; … Spinlock_lock (& ​​​​printf_lock); ... spinlock_unlock (& ​​​​printf_lock);

La fonction printf utilise la fonction putchar, qui doit également être écrite. Pour ce faire, créez un fichier \screen.c commun avec le contenu suivant :
#include "types.h" #define GREEN 0x2 #define MAX_COL 80 // Nombre maximum de colonnes #define MAX_ROW 25 // Nombre maximum de lignes #define VRAM_SIZE (MAX_COL * MAX_ROW) // Taille de l'écran, en "s courts # define DEF_VRAM_BASE 0xb8000 // Base par défaut pour la mémoire vidéo static unsigned char curr_col = 0; static unsigned char curr_row = 0; // Ecrit le caractère à l'emplacement actuel de l'écran #define PUT (c) (((unsigned short *) (DEF_VRAM_BASE)) \ [(curr_row * MAX_COL) + curr_col] = (VERT<< 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;) pause ; case "\ b": if (curr_col> 0) (curr_col - = 1; PUT ("");) break; par défaut : METTRE (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 (je = 0; je< VRAM_SIZE; i++) cons_putc(" "); curr_col = 0; curr_row = 0; }

Le code ci-dessus contient une logique simple pour imprimer des caractères à l'écran en mode texte. Dans ce mode, deux octets permettent d'écrire un caractère (l'un avec le code du caractère, l'autre avec ses attributs), écrit directement dans la mémoire vidéo affichée immédiatement à l'écran et à partir de l'adresse 0xB8000. La résolution de l'écran est de 80x25 caractères. L'impression directe d'un symbole s'effectue à l'aide de la macro PUT.
Maintenant, seuls quelques fichiers d'en-tête sont manquants :
1. Le fichier comprend \ screen.h. Déclare la fonction putchar, qui est utilisée dans la fonction printf. Contenu du fichier :
#ifndef _SCREEN_H #define _SCREEN_H void clear_screen (void); void putchar (int c); #fin si

2. Le fichier comprend \ printf.h. Déclare la fonction printf, qui est utilisée dans main. Contenu du fichier :
#ifndef _PRINTF_H #define _PRINTF_H int printf (const char * format, ...); #fin si

3. Le fichier comprend \ stdarg.h. Déclare des fonctions d'itération sur des arguments dont le nombre n'est pas connu à l'avance. Le fichier entier est tiré du projet www.bitvisor.org. Le chemin d'accès au fichier dans le code du projet bitvisor est include \ core \ stdarg.h.
4. Le fichier comprend \ types.h. Déclare NULL et size_t. Contenu du fichier :
#ifndef _TYPES_H #define _TYPES_H #define NULL 0 typedef unsigned int size_t; #fin si
Ainsi, les dossiers include et common contiennent le code de bibliothèque système minimum dont tout programme a besoin.

Étape 3. Créez un script pour l'éditeur de liens :

Créez un fichier linker.ld qui sera utilisé par l'éditeur de liens pour générer le fichier programme cible (kernel.bin). Le fichier doit contenir les éléments suivants :

ENTREE (chargeur) LMA = 0x0010000; SECTIONS (. = LMA; .multiboot ALIGN (0x1000): (loader.o (.text)) .text ALIGN (0x1000): (* (. Text)) .rodata ALIGN (0x1000): (* (. Rodata *) ) .data ALIGN (0x1000): (* (. data)) .bss: (* (COMMON) * (. bss)) / DISCARD /: (* (. comment)))

La fonction intégrée ENTRY() nous permet de définir le point d'entrée de notre noyau. C'est à cette adresse que grub transférera le contrôle après le chargement du noyau. L'éditeur de liens utilisera ce script pour créer un fichier binaire ELF. Un fichier ELF se compose d'un ensemble de segments et de sections. La liste des segments est contenue dans la table d'en-tête du programme, la liste des sections est dans la table d'en-tête de section. L'éditeur de liens fonctionne avec des sections, le chargeur d'images (dans notre cas c'est GRUB) avec des segments.


Comme vous pouvez le voir sur la figure, les segments sont constitués de sections. L'un des champs décrivant la section est l'adresse virtuelle à laquelle la section doit être située au moment de l'exécution. En fait, un segment possède 2 champs qui décrivent son emplacement : l'adresse virtuelle du segment et l'adresse physique du segment. L'adresse virtuelle du segment est l'adresse virtuelle du premier octet du segment au moment de l'exécution du code, l'adresse physique du segment est l'adresse physique à laquelle le segment doit être chargé. Pour les programmes d'application, ces adresses sont toujours les mêmes. Grub charge les segments d'image à leur adresse physique. Puisque Grub ne configure pas la pagination, l'adresse virtuelle du segment doit correspondre à son adresse physique, car la mémoire virtuelle n'est pas non plus configurée dans notre programme.

SECTIONS
Indique que les sections sont décrites ci-dessous.
... = LMA ;
Cette expression indique à l'éditeur de liens que toutes les sections suivantes sont après l'adresse LMA.
ALIGNER (0x1000)
La directive ci-dessus signifie que la section est alignée sur 0x1000 octets.
.multiboot ALIGN (0x1000): (loader.o (.text))
Une section multiboot distincte, qui inclut la section .text du fichier loader.o, est conçue pour garantir que la signature du format multiboot pénètre dans les 8 premiers Ko de l'image du noyau.
.bss : (* (COMMUN) * (. bss))
* (COMMON) est la zone dans laquelle la mémoire est réservée par les instructions .comm et.lcomm. Nous le plaçons dans la section .bss.
/ ABANDONNER / : (* (. Commentaire))
Toutes les sections marquées comme DISCARD sont supprimées de l'image. Dans ce cas, nous supprimons la section.comment, qui contient des informations sur la version de l'éditeur de liens.

Compilons maintenant le code dans un fichier binaire avec les commandes suivantes :
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 chargeur.o
En utilisant objdump, voyons à quoi ressemble l'image du noyau après la liaison :
objdump -ph ./kernel.bin


Comme vous pouvez le voir, les sections de l'image sont les mêmes que celles décrites dans le script de l'éditeur de liens. Le lieur a formé 3 segments à partir des sections décrites. Le premier segment comprend les sections multiboot, .text, .rodata et a une adresse virtuelle et physique de 0x0010000. Le deuxième segment contient les sections .data et .bss et est situé à 0x00104000. Vous êtes donc prêt à télécharger ce fichier avec Grub.

Étape 4. Préparez le chargeur de démarrage Grub :
Créer un dossier grub :
mkdir grub

Copiez plusieurs fichiers Grub dans ce dossier, qui sont nécessaires pour l'installer sur l'image (les fichiers suivants existent si Grub est installé sur le système). Pour ce faire, vous devez exécuter les commandes suivantes :
cp / usr / lib / grub / i386-pc / stage1 ./grub/ cp / usr / lib / grub / i386-pc / stage2 ./grub/ cp / usr / lib / grub / i386-pc / fat_stage1_5 ./grub /

Créez un fichier grub/menu.lst, avec le contenu suivant :
timeout 3 par défaut 0 titre mini_os root (hd0,0) kernel /kernel.bin

Étape 5. Automatisez et créez une image amorçable :

Pour automatiser le processus de construction, nous utiliserons l'utilitaire make. Pour ce faire, nous allons créer un makefile qui construira le code source de la compilation, construira un noyau et créera une image de démarrage. Le Makefile doit avoir le contenu suivant :

CC = gcc CFLAGS = -Wall -fno-builtin -nostdinc -nostdlib LD = ld OBJFILES = \loader.o\common/printf.o\common/screen.o\kernel.o image : @echo "Création hdd.img. .. " @dd if = / dev / zero of =. / hdd.img bs = 512 count = 16065 1> / dev / null 2> & 1 @echo " Création d'une première partition FAT32 bootable ... " @losetup / dev / loop1 ./hdd.img @ (écho c; écho u; écho n; écho p; écho 1; écho; écho; écho a; écho 1; écho t; écho c; écho w;) | fdisk / dev / loop1 1> / dev / null 2> & 1 || true @echo "Montage de la partition sur / dev / loop2 ..." @losetup / dev / loop2 ./hdd.img \ --offset `echo \` fdisk -lu / dev / loop1 | sed -n 10p | awk "(imprimer $$ 3)" \ `* 512 | bc` \ --sizelimit `echo \` fdisk -lu / dev / loop1 | sed -n 10p | awk "(imprimer $$ 4)" \ `* 512 | bc` @losetup -d / dev / loop1 @echo "Formater la partition ..." @mkdosfs / dev / loop2 @echo "Copier les fichiers noyau et grub sur la partition ..." @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 "Installation de GRUB. .. "@echo" périphérique (hd0) hdd.img \ n \ root (hd0,0) \ n \ setup (hd0) \ n \ quit \ n " | grub --batch 1> / dev / null @echo "Terminé !" all : kernel.bin reconstruire : nettoyer tout .s.o : as -o [email protégé] $< .c.o: $(CC) -Iinclude $(CFLAGS) -o [email protégé]-c $< kernel.bin: $(OBJFILES) $(LD) -T linker.ld -o [email protégé]$ ^ nettoyer : rm -f $ (OBJFILES) hdd.img kernel.bin

Le fichier déclare deux objectifs principaux : all - compile le noyau, et image - qui crée un disque de démarrage. La cible all, comme le makefile habituel, contient les sous-objectifs .so et .co, qui compilent les fichiers * .s et * .c en fichiers objets (* .o), ainsi qu'une cible pour générer kernel.bin, qui appelle l'éditeur de liens avec le script créé précédemment. Ces objectifs exécutent exactement les mêmes commandes que celles spécifiées à l'étape 3.
La création de l'image de démarrage hdd.img (image cible) est particulièrement intéressante ici. Considérons par étapes comment cela se produit.
dd if = / dev / zero of =. / hdd.img bs = 512 count = 16065 1> / dev / null 2> & 1
Cette commande crée une image avec laquelle d'autres travaux auront lieu. Le nombre de secteurs n'a pas été choisi au hasard : 16065 = 255 * 63. Par défaut, fdsik fonctionne avec le disque comme s'il avait une géométrie CHS, dans laquelle Headers (H) = 255, Sectors (S) = 63, et Cylinders (C ) dépend de la taille du disque. Ainsi, la taille de disque minimale avec laquelle l'utilitaire fdsik peut fonctionner sans modifier la géométrie par défaut est de 512 * 255 * 63 * 1 = 8225280 octets, où 512 est la taille du secteur et 1 est le nombre de cylindres.
Ensuite, une table de partition est créée :
losetup / dev / loop1 ./hdd.img (echo c; echo u; echo n; echo p; echo 1; echo; echo; echo a; echo 1; echo t; echo c; echo w;) | fdisk / dev / loop1 1> / dev / null 2> & 1 || vrai
La première commande monte le fichier hdd.img sur le périphérique bloc /dev/loop1, permettant au fichier d'être traité comme un périphérique. La deuxième commande crée une table de partition sur le périphérique / dev / loop1, qui contient 1 partition de démarrage principale du disque, occupant tout le disque, étiquetée avec le système de fichiers FAT32.
Ensuite, nous formatons la section créée. Pour ce faire, vous devez le monter en tant que périphérique bloc et effectuer le formatage.
losetup / dev / loop2 ./hdd.img \ --offset `echo \` fdisk -lu / dev / loop1 | sed -n 10p | awk "(imprimer $$ 3)" \ `* 512 | bc` \ --sizelimit `echo \` fdisk -lu / dev / loop1 | sed -n 10p | awk "(imprimer $$ 4)" \ `* 512 | bc`losetup -d / dev / loop1
La première commande monte la partition précédemment créée sur le périphérique /dev/loop2. L'option –offset spécifie le début de la section et –sizelimit spécifie la fin de la section. Les deux paramètres sont obtenus à l'aide de la commande fdisk.
mkdosfs / dev / loop2
L'utilitaire mkdosfs formate la partition dans le système de fichiers FAT32.
Pour construire le noyau directement, les commandes décrites précédemment dans la syntaxe classique du makefile sont utilisées.
Voyons maintenant comment installer GRUB sur une partition :
mkdir -p tempdir # crée un répertoire temporaire mount / dev / loop2 tempdir # monte la partition dans le répertoire mkdir tempdir / boot # crée un répertoire / boot sur la partition cp -r grub tempdir / boot / # copie le dossier grub dans / boot cp kernel.bin tempdir / # copie le noyau à la racine de la partition sleep 1 # attend Ubuntu umount / dev / loop2 # démonte le dossier temporaire rm -r tempdir # supprime le dossier temporaire losetup -d / dev / loop2 # démonter la partition
Après avoir exécuté les commandes ci-dessus, l'image sera prête à installer GRUB. La commande suivante installe GRUB dans le MBR de l'image disque hdd.img.
echo "périphérique (hd0) hdd.img \ n \ root (hd0,0) \ n \ setup (hd0) \ n \ quit \ n" | grub --batch 1> / dev / null

Tout est prêt à être testé !

Étape 6. Lancez :

Pour compiler, utilisez la commande :
fait tout
Après quoi le fichier kernel.bin devrait apparaître.
Pour créer une image disque amorçable, utilisez la commande :
sudo faire une image
Par conséquent, le fichier hdd.img devrait apparaître.
Vous pouvez maintenant démarrer à partir de l'image disque hdd.img. Vous pouvez le vérifier avec la commande suivante :
qemu -hda hdd.img -m 32
ou:
qemu-system-i386 -hda hdd.img



Pour vérifier sur une vraie machine, vous devez ajouter cette image sur un lecteur flash et démarrer à partir de celui-ci. Par exemple avec la commande suivante :
sudo dd si =. / hdd.img de = / dev / sdb

En résumé, nous pouvons dire qu'à la suite des actions entreprises, un ensemble de sources et de scripts est obtenu qui vous permet de réaliser diverses expériences dans le domaine de la programmation système. Faire le premier pas vers la création de logiciels système tels que des hyperviseurs et des systèmes d'exploitation.

Certaines applications nécessitent des droits élevés pour s'exécuter sous Windows et doivent être exécutées en tant qu'administrateur. Cela affiche la demande " Contrôle de compte d'utilisateur"(Contrôle de compte d'utilisateur ou UAC), dans lequel le système vous demande votre accord pour lancer l'application.

De nombreux utilisateurs pensent à tort que le contrôle de compte d'utilisateur ne fait que gêner et le désactivent. Dans le même temps, la sécurité de l'ordinateur est sérieusement affectée. Le consentement de l'utilisateur n'est plus requis pour lancer des applications, et tout logiciel malveillant peut se lancer et s'exécuter sans problème. La présence d'antivirus ne peut pas non plus garantir une sécurité informatique à 100 %.

Dans cet article, je vais vous montrer comment simplifier le processus d'exécution des applications sélectionnées en tant qu'administrateur sans désactiver l'UAC (en tout ou en partie) et sans compromettre la sécurité.

Il existe plusieurs façons d'exécuter l'application en tant qu'administrateur :

A titre d'exemple, nous exécuterons ligne de commande(cmd) en tant qu'administrateur.

Méthode numéro 1 (normale) - lancement via le bouton droit de la souris (la demande UAC est affichée)

clic droit sur l'icone application souhaitée et sélectionnez " Exécuter en tant qu'administrateur":

Méthode numéro 2 - lancer en utilisant " Ctrl + Maj + Entrée"(L'invite UAC s'affiche)

Cliquer sur Début, dans la barre de recherche, tapez la commande que tu veux et appuyez sur Ctrl + Maj + Entrée.

Méthode numéro 3 - définissez le lancement en tant qu'administrateur dans les propriétés du raccourci (la demande UAC s'affiche)

Faites un clic droit sur le raccourci souhaité et sélectionnez " Propriétés".

Allez au " Étiqueter", Cliquez sur" en outre", cochez la case" Exécuter en tant qu'administrateur":


Ou allez au " Compatibilité"et cochez la case" Exécutez ce programme en tant qu'administrateur":

Méthode numéro 4 - simplifier le lancement des applications sélectionnées à l'aide du planificateur de tâches (la demande UAC n'est pas affichée)

Important! Cette méthode ne fonctionne que pour les comptes inclus dans le groupe. Administrateurs... Cela ne fonctionnera pas pour les utilisateurs ordinaires, car leur plafond est limité en droits.

Passons à la manière la plus intéressante. S'il existe une application que vous exécutez constamment et qu'elle a été obtenue auprès d'un fabricant de logiciels fiable, par exemple, cette Application Windows- vous pouvez simplifier le lancement. Créer un raccourci pour le programme souhaité ne prend pas plus de 2 minutes et cela vous permettra de vous débarrasser des actions inutiles à l'avenir. Lancer Planificateur de tâches (Début---> Tous les programmes ---> Standard---> Service---> Planificateur de tâches) et cliquez sur " Créer une tâche":

Nous indiquons Nom pour une nouvelle tâche et cochez la case " Exécuter avec les droits les plus élevés":

Allez dans l'onglet Actions, presse " Créer", dans la fenêtre suivante, cliquez sur" Aperçu":

Spécifiez le chemin vers l'application souhaitée et cliquez sur " Ouvert":



Agrandir l'image

Cliquez sur " d'accord":

Fermez le planificateur et passez à la création d'un raccourci.

Pour créer un raccourci sur le bureau, faites un clic droit, sélectionnez " Créer" ---> "Étiqueter":


Dans le champ Emplacement de la propriété nous introduisons :

Schtasks / run / tn cmd_admin

cmd_admin- le nom de la tâche que nous avons créée. Si le nom contient des espaces, il doit être placé entre guillemets.

Nous définissons le nom du raccourci :



Agrandir l'image

Le raccourci est créé et prêt à être utilisé.

Pour changer l'icône - faites un clic droit sur le raccourci, sélectionnez " Propriétés":

Allez au " Étiqueter" et appuyez sur " Changer l'icône":

"Aperçu..."

Nous indiquons le chemin vers le programme:



Agrandir l'image

Sélectionnez l'icône souhaitée et fermez les deux fenêtres avec le " d'accord":

Désormais, le lancement de l'application souhaitée en tant qu'administrateur s'effectue en double-cliquant sur le raccourci créé, tandis que l'invite UAC ne s'affiche pas et que la sécurité reste intacte.

Utilitaire pour l'automatisation "Méthode numéro 4"

Si vous devez créer des raccourcis pour un grand nombre de programmes, il est pratique d'utiliser l'utilitaire.

L'utilisation de l'utilitaire se résume à deux étapes simples :

  • Installation
  • Glissez-déposez le fichier exécutable (* .exe, * .bat, * .cmd) dans le raccourci de l'utilitaire :


Mise au point automatique sur un programme en cours d'exécution

La spécificité du lancement d'applications depuis l'ordonnanceur est que le focus n'est pas reporté sur la fenêtre et, par exemple, pour taper une commande en ligne de commande, il faut en plus cliquer sur la fenêtre. Ce comportement peut aider à automatiser les opérations planifiées de routine, mais pour la méthode n° 4, ce n'est pas toujours pratique.

Il existe plusieurs méthodes de "contournement". Ils fonctionnent un peu différemment, alors choisissez celui qui vous convient le mieux. Le premier est plus pratique pour exécuter des programmes et le second pour exécuter des scripts.

Ajouter lors de la création d'une tâche :

Utilisation de la commande de démarrage

Programme ou script :

Arguments:

/ c start / d "program_path" filename.exe

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

Utilisation de l'utilitaire NirCmd

Programme ou script :

Chemin_vers_nircmd \ nircmd.exe

Arguments:

Exec show "program_path \ filename.exe"

Exec show "C:\Windows\System32\cmd.exe"

Exécuter la boîte de dialogue "Exécuter" en tant qu'administrateur

Par analogie avec le lancement de la ligne de commande, vous pouvez configurer le lancement du " Exécuter", et les commandes qui y sont entrées seront également exécutées au nom de l'administrateur. La commodité de cette approche est que la liste des commandes précédemment utilisées est enregistrée et que vous pouvez sélectionner celle dont vous avez besoin dans la liste.


Lors de la création d'une tâche dans le planificateur, dans le " Créer une action"spécifier:

dans le champ " Programme ou script":

Exécuterdll32

dans le champ " Ajouter des arguments":

Shell32.dll, # 61

Téléchargez l'utilitaire, décompressez-le. Nous lançons la ligne de commande, entrons la commande requise, la syntaxe est assez simple :

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


Une invite UAC apparaîtra et l'application s'exécutera en tant qu'administrateur.

Noter: V menu contextuel Windows 7 a une fonction très pratique pour copier le chemin du fichier : maintenez Décalage, faites un clic droit sur le fichier, sélectionnez " Copier comme chemin".


Exécuter des programmes par utilisateur en tant qu'administrateur sans saisir de mot de passe administrateur

Important! Cette méthode n'est pas sécurisée car elle permet à un utilisateur limité d'exécuter du code avec tous les droits. Un utilisateur rusé ou un logiciel malveillant peut en profiter et compromettre le système.

Considérez une autre tâche intéressante : votre compte Entrée Windows appartient au groupe des administrateurs, il existe un ou plusieurs comptes inclus dans le groupe d'utilisateurs. L'utilisateur doit exécuter un programme qui nécessite une élévation. Cela ressemble généralement à ceci : l'utilisateur fait un clic droit sur le fichier et sélectionne "Exécuter en tant qu'administrateur", ce qui demande le mot de passe administrateur :


Bien sûr, donner aux utilisateurs un mot de passe administrateur n'est pas une bonne idée. Pour contourner ce problème, nous utiliserons l'utilitaire AdmiLink d'Alexey Kuryakin. Avec son aide, l'administrateur peut créer un raccourci pour que l'utilisateur lance le programme requis, tandis que la saisie du mot de passe administrateur n'est requise qu'une seule fois - lors de la création d'un raccourci. Lorsque l'utilisateur démarre le programme, le mot de passe sera transmis sous forme cryptée.



Cette méthode fonctionnera si le programme ne peut être exécuté qu'en tant qu'administrateur et que le développeur n'a pas oublié de spécifier cette condition dans le manifeste. Cependant, il existe encore un grand nombre d'anciens programmes ou de programmes qui peuvent être lancés à la fois en mode normal et pour le compte de l'administrateur (dans ce cas, un ensemble de fonctions différent sera disponible). Lorsque vous essayez d'exécuter un tel programme à l'aide d'AdmiLink, il démarre en mode normal (sans privilèges administratifs). Et si vous essayez de cocher la case "Méthode numéro 3. Le style original de l'auteur est enregistré.

gastroguru 2017