Tornamos mais fácil executar aplicativos no Windows como administrador sem desabilitar o UAC. Como criar um atalho que permita que usuários padrão executem um aplicativo com direitos de administrador

E se você precisar executar um programa, mas não quiser instalá-lo? Zero Install para o resgate!

Bilhões de pessoas em todo o mundo usam computadores ou laptops na sala de cirurgia Sistema Windows. Normalmente instalamos programas, após os quais eles ocupam espaço livre em disco e usam BATER. Isso diminui a velocidade do computador.

Hoje vamos contar como você pode aumentar o desempenho do seu computador e reduzir a carga de memória. Para fazer isso, execute os programas necessários sem instalá-los.

Como executar o programa sem instalação?

1. Baixe a instalação zero.

Primeiro, baixe o software Zero Install, que permitirá executar programas sem precisar instalá-los em seu computador.

2. Instale a instalação zero.

Depois de fazer o download do Zero Install, clique duas vezes no arquivo para instalá-lo. Então corra novo programa no seu computador.

3. Clique emAlvenaria “catálogo”.

Assim que o Zero Install estiver em execução no seu computador ou Notebook com Windows, você deve ir até a aba “Catálogo”. Aqui, clique no botão “Atualizar lista” para atualizar a lista de programas disponíveis.

4. Selecione um programa para iniciar.

Dê uma boa olhada lista completa programas disponíveis. Se você encontrar o programa que precisa, destaque-o e clique em “Executar”. Alguns programas podem escolher Navegador Firefox ou Mozilla para executar. Apenas espere até que esteja totalmente carregado Programas, após o qual você poderá executá-lo em seu computador sem instalá-lo.


Resumindo

Se o seu computador não tiver memória livre ou energia suficiente para executar o programa, você pode usar o Zero Install. Acho que essa é uma ótima maneira de evitar sobrecarregar seu computador com programas que você só precisa usar uma vez.

Além disso, seu computador pode não ter energia suficiente para executar determinados programas, como Eclipse IDE, JetBrains, NetBeans, etc. Estes são programas realmente pesados ​​para os desenvolvedores consumirem um grande número de memória de acesso aleatório.

Zero Install irá ajudá-lo a executar estes e muitos outros programas sem instalá-los em seu computador.

O mais importante não foi descrito com detalhes suficientes: como executar esse código em hardware real? Como criar o seu próprio disco de inicialização? Neste artigo responderemos detalhadamente a todas essas questões (parcialmente essas questões foram discutidas no artigo anterior, mas para facilitar a leitura nos permitiremos uma ligeira duplicação de material).

Há um grande número de descrições e tutoriais na Internet sobre como escrever seu próprio mini-SO. Existem até centenas de pequenos sistemas operacionais de hobby já prontos; Um dos recursos mais valiosos sobre este tema, que gostaria de destacar especialmente, é o portal osdev.org. Para complementar o artigo anterior sobre PCI (e a oportunidade de escrever artigos subsequentes sobre as diversas funções que estão presentes em qualquer sistema operacional moderno), descreveremos instruções passo a passo sobre a criação de um disco de inicialização com um programa familiar em C. Tentamos escrever com o máximo de detalhes possível para que você pudesse descobrir tudo sozinho.

Então, o objetivo: com o mínimo esforço possível, criar o seu próprio unidade flash USB inicializável, que apenas imprime o clássico “Hello World” na tela do computador.

Para ser mais preciso, precisamos “entrar” no modo protegido com endereçamento de página e interrupções desabilitadas - o modo mais simples de operação do processador com comportamento familiar para um programa de console simples. A maneira mais razoável de atingir esse objetivo é construir um kernel que suporte o formato multiboot e carregá-lo usando o popular Carregador de inicialização Grub. Uma alternativa para esta solução é escrever seu próprio registro de inicialização de volume (VBR), que carregaria seu próprio carregador escrito. Um bootloader decente, no mínimo, deve ser capaz de trabalhar com um disco, com um sistema de arquivos e analisar imagens elfas. Isso significa que você precisa escrever muito código assembly e muito código em C. Resumindo, é mais fácil usar o Grub, que já pode fazer tudo o que você precisa.

Vamos começar com o fato de que para ações futuras você precisará de um determinado conjunto de compiladores e utilitários. A maneira mais fácil é usar algum Linux (por exemplo, Ubuntu), pois ele já conterá tudo que você precisa para criar uma unidade flash inicializável. Se você está acostumado a trabalhar no Windows, pode configurar máquina virtual com Linux (usando Virtual Box ou VMware Workstation).

Se você estiver usando LinuxUbuntu, primeiro você precisa instalar vários utilitários:
1. Comida. Para fazer isso usaremos o comando:

Sudo apt-get install grub

2. Qemu. É necessário testar e depurar tudo rapidamente (Link para artigo sobre o depurador), para isso o comando é semelhante:

Sudo apt-get install qemu

Agora nosso plano fica assim:
Primeiro, crie um programa C que imprima uma string na tela.
2. Construa uma imagem a partir dele (kernel.bin) no formato miniboot para que fique disponível para inicialização usando GRUB.
3. crie um arquivo de imagem de disco de inicialização e formate-o.
4. instale o Grub nesta imagem.
5. copie o programa criado (kernel.bin) para o disco.
6. grave a imagem em mídia física ou execute-a no qemu.

e o processo de inicialização do sistema:

Para que tudo funcione, você precisará criar vários arquivos e diretórios:

Passo 1. Criando o código para o programa alvo (kernel):

Crie um arquivo kernel.c, que conterá o seguinte código que imprime uma mensagem na tela:

#include "printf.h" #include "screen.h" #include "types.h" void main(void) ( clear_screen(); printf("n>>> Olá Mundo!n"); )

Tudo aqui é familiar e simples. A adição das funções printf e clear_screen será discutida mais adiante. Enquanto isso, precisamos complementar este código com tudo o que for necessário para que ele possa ser carregado pelo Grub.
Para que o kernel esteja no formato multiboot, os primeiros 8 kilobytes da imagem do kernel devem conter a seguinte estrutura:

Se todas as condições especificadas forem atendidas, o Grub passa um ponteiro para a estrutura de informações de inicialização múltipla e o valor 0x1BADB002 através dos registros %eax e %ebx, respectivamente. A estrutura de informações de inicialização múltipla contém várias informações, incluindo uma lista de módulos carregados e sua localização, que pode ser necessária para carregamento adicional do sistema.
Para que o arquivo do programa contenha as assinaturas necessárias, criaremos um arquivo loader.s com o seguinte conteúdo:

Texto .global loader # tornando o ponto de entrada visível para o vinculador # configurando o cabeçalho Multiboot - consulte a documentação do GRUB para obter detalhes .set FLAGS, 0x0 # este é o campo "flag" do Multiboot .set MAGIC, 0x1BADB002 # "número mágico" permite que o bootloader encontre o cabeçalho .set CHECKSUM, -(MAGIC + FLAGS) # checksum necessário .align 4 .long MAGIC .long FLAGS .long CHECKSUM # reserva o espaço inicial da pilha do kernel .set STACKSIZE, 0x4000 # ou seja, 16k. .lcomm stack, STACKSIZE # reserva 16k stack .comm mbd, 4 # usaremos isso no kmain .comm magic, 4 # usaremos isso no carregador kmain: movl $(stack + STACKSIZE), %esp # configura a pilha movl %eax, magic # Número mágico de inicialização múltipla movl %ebx, mbd # Estrutura de dados de inicialização múltipla chama main # chama código C cli hang: hlt # máquina de parada deve o kernel retornar jmp hang

Vejamos o código com mais detalhes. Este código, quase inalterado, foi retirado de wiki.osdev.org/Bare_Bones. Como o gcc é usado para compilação, a sintaxe GAS é usada. Vamos dar uma olhada mais de perto no que esse código faz.

Todo o código subsequente terminará na seção executável.text.

Carregador global

Declaramos o símbolo do carregador visível para o vinculador. Isso é necessário porque o vinculador usará o carregador como ponto de entrada.

Set FLAGS, 0x0 # set FLAGS = 0x0 .set MAGIC, 0x1BADB002 # set MAGIC = 0x1BADB002 .set CHECKSUM, -(MAGIC + FLAGS) # set CHECKSUM = -(MAGIC + FLAGS).align 4 # alinha os dados subsequentes em 4 bytes. long MAGIC # coloca o valor de MAGIC no endereço atual .long FLAGS # coloca o valor de FLAGS no endereço atual .long CHECKSUM # coloca o valor de CHECKSUM no endereço atual

Este código gera uma assinatura no formato Multiboot. A diretiva .set define o valor do caractere para a expressão à direita da vírgula. A diretiva .align 4 alinha o conteúdo subsequente a 4 bytes. A diretiva .long armazena o valor nos próximos quatro bytes.

Defina STACKSIZE, 0x4000 # atribua STACKSIZE = 0x4000 .lcomm stack, STACKSIZE # reserve bytes STACKSIZE. pilha refere-se a range.comm mbd, 4 # reserve 4 bytes para a variável mdb na área COMMON .comm magic, 4 # reserve 4 bytes para a variável mágica na área COMMON

Em andamento inicialização grub não configura a pilha, e a primeira coisa que o kernel deve fazer é configurar a pilha, para isso reservamos 0x4000 (16Kb) bytes. A diretiva.lcomm reserva o número de bytes especificado após o ponto decimal na seção.bss. O nome da pilha só ficará visível no arquivo compilado. A diretiva .comm faz o mesmo que .lcomm, mas o nome do símbolo será declarado globalmente. Isso significa que, escrevendo a seguinte linha em código C, podemos usá-la.
magia interna externa

E agora a última parte:

Carregador: movl $(stack + STACKSIZE), %esp # inicializa a pilha movl %eax, magic # escreve %eax no endereço mágico movl %ebx, mbd # escreve %ebx no endereço mbd call main # chama a função principal cli # desabilita interrupções from hardware hang: hlt # para o processador até que ocorra uma interrupção jmp hang # salta para o rótulo de travamento

A primeira instrução armazena o valor no topo da pilha no registrador %esp. Como a pilha cresce para baixo, o endereço do final do intervalo alocado para a pilha é gravado em %esp. As próximas duas instruções armazenam em intervalos de 4 bytes previamente reservados os valores que o Grub passa nos registradores %eax, %ebx. Em seguida é chamada a função principal, que já está escrita em C. Se este procedimento retornar, o processador entrará em loop.

Passo 2. Preparando código adicional para o programa (biblioteca do sistema):

Como todo o programa foi escrito do zero, a função printf deve ser escrita do zero. Para fazer isso, você precisa preparar vários arquivos.
Vamos criar uma pasta comum e include:

Mkdir mkdir comum inclui

Vamos criar um arquivo commonprintf.c, que conterá uma implementação da familiar função printf. Todo esse arquivo pode ser retirado do projeto www.bitvisor.org/. Caminho para o arquivo nas fontes do bitvisor: core/printf.c. No arquivo printf.c copiado do bitvisor, para uso no programa alvo é necessário substituir as linhas:

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

para linhas:

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

Em seguida, remova a função printf_init_global e todas as suas referências neste arquivo:

Estático void printf_init_global (void) ( spinlock_init (&printf_lock); ) INITFUNC ("global0", printf_init_global);

Em seguida, remova a variável printf_lock e todas as referências a ela neste arquivo:

Spinlock_t estático printf_lock; ... spinlock_lock (&printf_lock); ... spinlock_unlock (&printf_lock);

A função printf usa a função putchar, que também precisa ser escrita. Para fazer isso, crie um arquivo commonscreen.c com o seguinte conteúdo:

#include "types.h" #define GREEN 0x2 #define MAX_COL 80 // Número máximo de colunas #define MAX_ROW 25 // Número máximo de linhas #define VRAM_SIZE (MAX_COL*MAX_ROW) // Tamanho da tela, em resumo # define DEF_VRAM_BASE 0xb8000 // Base padrão para memória de vídeo static unsigned char curr_col = 0; static unsigned char curr_row = 0; // Grava o caractere no local atual da tela #define PUT(c) (((unsigned short *) (DEF_VRAM_BASE)) [ (curr_row * MAX_COL) + curr_col] = (VERDE<< 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; ) pausa; case "b": if (curr_col > 0) ( curr_col -= 1; PUT(" "); ) break; padrão: 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;< VRAM_SIZE; i++) cons_putc(" "); curr_col = 0; curr_row = 0; }

O código especificado contém lógica simples para imprimir caracteres na tela em modo texto. Neste modo, dois bytes são utilizados para gravar um caractere (um com o código do caractere, outro com seus atributos), gravado diretamente na memória de vídeo exibida imediatamente na tela e iniciando no endereço 0xB8000. A resolução da tela é de 80x25 caracteres. O caractere é impresso diretamente usando a macro PUT.
Agora faltam apenas alguns arquivos de cabeçalho:
1. Arquivo includescreen.h. Declara a função putchar, que é usada na função printf. Conteúdo do arquivo:

#ifndef _SCREEN_H #define _SCREEN_H void clear_screen(void); vazio putchar(int c); #fim se

2. Arquivo includeprintf.h. Declara a função printf, que é usada em main. Conteúdo do arquivo:

#ifndef _PRINTF_H #define _PRINTF_H int printf (const char *formato, ...); #fim se

3. Arquivo incluitdarg.h. Declara funções para enumerar argumentos, cujo número não é conhecido antecipadamente. O arquivo inteiro foi retirado do projeto www.bitvisor.org/. Caminho para o arquivo no código do projeto bitvisor: includecorestdarg.h.
4. Arquivo includetypes.h. Declara NULL e size_t. Conteúdo do arquivo:

#ifndef _TYPES_H #define _TYPES_H #define NULL 0 typedef unsigned int size_t; #fim se

Assim, as pastas include e common contêm o código mínimo da biblioteca do sistema que qualquer programa precisa.

Etapa 3: crie um script para o vinculador:

Criamos um arquivo linker.ld, que será usado pelo vinculador para gerar o arquivo do programa de destino (kernel.bin). O arquivo deve conter o seguinte:

ENTRADA (carregador) LMA = 0x00100000; SEÇÕES ( . = LMA; .multiboot ALIGN (0x1000) : ( loader.o(.text) ) .text ALIGN (0x1000) : ( *(.text) ) .rodata ALIGN (0x1000) : ( *(.rodata*) ) .data ALIGN (0x1000) : ( *(.data) ) .bss: ( *(COMMON) *(.bss) ) /DISCARD/ : ( *(.comment) ) )

A função integrada ENTRY() nos permite definir o ponto de entrada para nosso kernel. É para este endereço que o grub transferirá o controle após carregar o kernel. O vinculador usará este script para criar um arquivo binário no formato ELF. Um arquivo ELF consiste em um conjunto de segmentos e seções. A lista de segmentos está contida na tabela de cabeçalho do programa, a lista de seções na tabela de cabeçalho de seção. O vinculador opera com seções, o carregador de imagens (no nosso caso, GRUB) com segmentos.


Como pode ser visto na figura, os segmentos consistem em seções. Um dos campos que descreve uma seção é o endereço virtual onde a seção deve estar localizada no momento da execução. Na verdade, um segmento possui 2 campos que descrevem sua localização: o endereço virtual do segmento e o endereço físico do segmento. O endereço virtual de um segmento é o endereço virtual do primeiro byte do segmento no momento em que o código é executado, o endereço físico do segmento é o endereço físico no qual o segmento deve ser carregado. Para programas aplicativos, esses endereços são sempre os mesmos. Grub carrega segmentos de imagem por seu endereço físico. Como o Grub não configura paginação, o endereço virtual de um segmento deve corresponder ao seu endereço físico, já que em nosso programa memória virtual Também não é configurável.

LM;

Esta expressão informa ao vinculador que todas as seções subsequentes estão após o endereço LMA.

ALINHAR (0x1000)

A diretiva acima significa que a seção está alinhada em 0x1000 bytes.

ALIGN de ​​inicialização múltipla (0x1000): (loader.o(.text))

Uma seção separada de inicialização múltipla, que inclui a seção .text do arquivo loader.o, é criada para garantir que a assinatura do formato de inicialização múltipla seja incluída nos primeiros 8kb da imagem do kernel.

Bss: ( *(COMUM) *(.bss) )

*(COMMON) é a área na qual a memória é reservada pelas instruções .comm e .lcomm. Colocamos na seção.bss.

/DISCARD/ : ( *(.comment) )

Todas as seções marcadas como DISCARD são removidas da imagem. Nesse caso, removemos a seção .comment, que contém informações sobre a versão do vinculador.

Agora vamos compilar o código em um arquivo binário usando os seguintes comandos:

Como -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 comum/printf.c gcc -Iinclude -Wall -fno-builtin -nostdinc -nostdlib -o tela.o -c comum/tela.c ld -T linker.ld -o kernel.bin kernel.o tela.o printf .o carregador.o

Usando objdump, vamos ver como fica a imagem do kernel após a vinculação:

Objdump -ph./kernel.bin



Como você pode ver, as seções da imagem coincidem com aquelas que descrevemos no script do vinculador. O ligante formou 3 segmentos a partir das seções descritas. O primeiro segmento inclui as seções .multiboot, .text, .rodata e possui endereço virtual e físico 0x00100000. O segundo segmento contém as seções .data e .bss e está localizado no endereço 0x00104000. Isso significa que você está pronto para carregar este arquivo usando o Grub.

Etapa 4: Preparando o gerenciador de inicialização Grub:
Crie uma pasta grub:

Comida Mkdir

Copie para esta pasta vários arquivos Grub que são necessários para instalá-lo na imagem (os seguintes arquivos existem se o Grub estiver instalado no sistema). Para fazer isso você precisa executar os seguintes comandos:

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 /

Crie um arquivo grub/menu.lst com o seguinte conteúdo:

Tempo limite 3 padrão 0 título mini_os root (hd0,0) kernel /kernel.bin

Etapa 5. Automatize e crie uma imagem de inicialização:

Para automatizar o processo de construção, usaremos o utilitário make. Para fazer isso, criaremos um makefile que irá compilar o código fonte, construir o kernel e criar uma imagem de boot. Makefile deve ter o seguinte conteúdo:

CC = gcc CFLAGS = -Wall -fno-builtin -nostdinc -nostdlib LD = ld OBJFILES = loader.o common/printf.o common/screen.o kernel.o imagem: @echo "Criando hdd.img..." @ dd if=/dev/zero of=./hdd.img bs=512 count=16065 1>/dev/null 2>&1 @echo "Criando a primeira partição FAT32 inicializável..." @losetup /dev/loop1 ./hdd .img @(eco c; eco u; eco n; eco p; eco 1; eco ; eco ; eco a; eco 1; eco t; eco c; eco w;) | fdisk /dev/loop1 1>/dev/null 2>&1 || true @echo "Montando partição em /dev/loop2..." @losetup /dev/loop2 ./hdd.img --offset `echo `fdisk -lu /dev/loop1 | sed-n 10p | awk "(imprimir $$3)"`*512 | bc` --sizelimit `echo `fdisk -lu /dev/loop1 | sed-n 10p | awk "(imprimir $$4)"`*512 | bc` @losetup -d /dev/loop1 @echo "Formatar partição..." @mkdosfs /dev/loop2 @echo "Copiar arquivos do kernel e grub na partição..." @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 "Instalando GRUB. .." @echo "dispositivo (hd0) hdd.img n root (hd0,0) n configuração (hd0) n quitn" | grub --batch 1>/dev/null @echo "Concluído!" tudo: kernel.bin reconstruir: limpar tudo .s.o: as -o $@ $< .c.o: $(CC) -Iinclude $(CFLAGS) -o $@ -c $< kernel.bin: $(OBJFILES) $(LD) -T linker.ld -o $@ $^ clean: rm -f $(OBJFILES) hdd.img kernel.bin

O arquivo declara dois objetivos principais: all - que compila o kernel, e image - que cria um disco de inicialização. O objetivo all, como o makefile usual, contém subgoals.s.o e.c.o, que compilam arquivos *.s e *.c em arquivos objeto (*.o), bem como um objetivo para gerar kernel.bin, que chama o vinculador com o script criado anteriormente. Esses destinos executam exatamente os mesmos comandos especificados na etapa 3.
De maior interesse aqui é a criação imagem de inicialização hdd.img (imagem de destino). Vejamos como isso acontece passo a passo.

Dd if=/dev/zero de=./hdd.img bs=512 contagem=16065 1>/dev/null 2>&1

Esta equipe cria uma imagem com a qual o trabalho continuará. O número de setores não foi escolhido aleatoriamente: 16065 = 255 * 63. Por padrão, o fdsik trabalha com o disco como se tivesse geometria CHS, em que Cabeçalhos (H) = 255, Setores (S) = 63, e Cilindros© depende do tamanho do disco. Assim, o tamanho mínimo do disco com o qual o utilitário fdsik pode trabalhar, sem alterar a geometria padrão, é 512 * 255 * 63 * 1 = 8225280 bytes, onde 512 é o tamanho do setor e 1 é o número de cilindros.
A seguir, a tabela de partições é criada:

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

O primeiro comando monta o arquivo hdd.img no dispositivo de bloco /dev/loop1, permitindo que o arquivo seja tratado como um dispositivo. O segundo comando cria uma tabela de partição no dispositivo /dev/loop1, que contém 1 primário partição de inicialização disco, ocupando todo o disco, com o rótulo do sistema de arquivos FAT32.
Em seguida, formatamos a partição criada. Para fazer isso, você precisa montá-lo como um dispositivo de bloco e formatá-lo.

Losetup /dev/loop2 ./hdd.img --offset `echo `fdisk -lu /dev/loop1 | sed-n 10p | awk "(imprimir $$3)"`*512 | bc` --sizelimit `echo `fdisk -lu /dev/loop1 | sed-n 10p | awk "(imprimir $$4)"`*512 | bc` perder configuração -d /dev/loop1

O primeiro comando monta a partição criada anteriormente no dispositivo /dev/loop2. A opção –offset especifica o endereço do início da seção e –sizelimit especifica o endereço do final da seção. Ambas as opções são obtidas usando o comando fdisk.

Mkdosfs /dev/loop2

O utilitário mkdosfs formata a partição em sistema de arquivo FAT32.
Para construir diretamente o kernel, são usados ​​os comandos discutidos anteriormente na sintaxe clássica do makefile.
Agora vamos ver como instalar o GRUB em uma partição:

Mkdir -p tempdir # cria um diretório temporário mount /dev/loop2 tempdir # monta a partição no diretório mkdir tempdir/boot # cria um diretório /boot na partição cp -r grub tempdir/boot/ # copia a pasta grub para / boot cp kernel.bin tempdir / # copia o kernel para a raiz da partição sleep 1 # espere pelo Ubuntu umount /dev/loop2 # desmonte a pasta temporária rm -r tempdir # exclua a pasta temporária losstup -d /dev/loop2 # desmontar a partição

Após executar os comandos acima, a imagem estará pronta para instalação do GRUB. O comando a seguir instala o GRUB no MBR da imagem de disco hdd.img.

Echo "dispositivo (hd0) hdd.img n root (hd0,0) n configuração (hd0) n quitn" | grub --batch 1>/dev/null

Tudo está pronto para teste!

Etapa 6. Lançamento:

Para compilar, use o comando:

Faça tudo

Depois disso, o arquivo kernel.bin deve aparecer.
Para criar uma imagem de disco inicializável, use o comando:

Sudo criar imagem

Como resultado, o arquivo hdd.img deve aparecer.
Agora você pode inicializar a partir da imagem de disco hdd.img. Você pode verificar isso usando o seguinte comando:

Qemu -hda hdd.img -m 32

Qemu-system-i386 -hda hdd.img




Para verificar em uma máquina real, você precisa adicionar esta imagem a uma unidade flash e inicializar a partir dela. Por exemplo com este comando:

Sudo dd if=./hdd.img of=/dev/sdb

Resumindo, podemos dizer que como resultado das ações realizadas, obtém-se um conjunto de códigos-fonte e scripts que nos permitem realizar diversos experimentos na área de programação de sistemas. O primeiro passo foi dado para a criação de software de sistema, como hipervisores e sistemas operacionais.

O mais importante não foi descrito com detalhes suficientes: como executar esse código em hardware real? Como criar seu próprio disco de inicialização? Neste artigo responderemos detalhadamente a todas essas questões (parcialmente essas questões foram discutidas no artigo anterior, mas para facilitar a leitura nos permitiremos uma ligeira duplicação de material).

Há um grande número de descrições e tutoriais na Internet sobre como escrever seu próprio mini-SO. Existem até centenas de pequenos sistemas operacionais de hobby já prontos; Um dos recursos mais valiosos sobre este tema, que gostaria de destacar especialmente, é o portal osdev.org. Para complementar o artigo anterior sobre PCI (e a oportunidade de escrever artigos subsequentes sobre as diversas funções que estão presentes em qualquer sistema operacional moderno), descreveremos instruções passo a passo para criar um disco de inicialização com um programa familiar em C. Nós Tentei escrever com o máximo de detalhes possível para que tudo fosse possível descobrir por conta própria.

Então, o objetivo: com o mínimo de esforço possível, criar seu próprio pen drive bootável, que apenas imprime o clássico “Hello World” na tela do computador.

Para ser mais preciso, precisamos “entrar” no modo protegido com endereçamento de página e interrupções desabilitadas - o modo mais simples de operação do processador com comportamento familiar para um programa de console simples. A maneira mais inteligente de atingir esse objetivo é construir um kernel que suporte o formato multiboot e inicializá-lo usando o popular gerenciador de inicialização Grub. Uma alternativa para esta solução é escrever seu próprio registro de inicialização de volume (VBR), que carregaria seu próprio carregador escrito. Um bootloader decente, no mínimo, deve ser capaz de trabalhar com um disco, com um sistema de arquivos e analisar imagens elfas. Isso significa que você precisa escrever muito código assembly e muito código em C. Resumindo, é mais fácil usar o Grub, que já pode fazer tudo o que você precisa.

Vamos começar com o fato de que para ações futuras você precisará de um determinado conjunto de compiladores e utilitários. A maneira mais fácil é usar algum Linux (por exemplo, Ubuntu), pois ele já conterá tudo que você precisa para criar uma unidade flash inicializável. Se você está acostumado a trabalhar no Windows, pode configurar uma máquina virtual com Linux (usando Virtual Box ou VMware Workstation).

Se você estiver usando Linux Ubuntu, primeiro precisará instalar vários utilitários:
1. Comida. Para fazer isso usaremos o comando:
sudo apt-get install grub

2. Qemu. É necessário deixar tudo rápido, para isso o comando é semelhante:
sudo apt-get install qemu

Agora nosso plano fica assim:
Primeiro, crie um programa C que imprima uma string na tela.
2. Construa uma imagem a partir dele (kernel.bin) no formato miniboot para que fique disponível para inicialização usando GRUB.
3. crie um arquivo de imagem de disco de inicialização e formate-o.
4. instale o Grub nesta imagem.
5. copie o programa criado (kernel.bin) para o disco.
6. grave a imagem em mídia física ou execute-a no qemu.

E o processo de inicialização do sistema:

Para que tudo funcione, você precisará criar vários arquivos e diretórios:

Passo 1. Criando o código para o programa alvo (kernel):

Crie um arquivo kernel.c, que conterá o seguinte código que imprime uma mensagem na tela:

#include "printf.h" #include "screen.h" #include "types.h" void main(void) ( clear_screen(); printf("\n>>> Olá Mundo!\n"); )

Tudo aqui é familiar e simples. A adição das funções printf e clear_screen será discutida mais adiante. Enquanto isso, precisamos complementar este código com tudo o que for necessário para que ele possa ser carregado pelo Grub.
Para que o kernel esteja no formato multiboot, os primeiros 8 kilobytes da imagem do kernel devem conter a seguinte estrutura:

Se todas as condições especificadas forem atendidas, o Grub passa um ponteiro para a estrutura de informações de inicialização múltipla e o valor 0x1BADB002 através dos registros %eax e %ebx, respectivamente. A estrutura de informações de inicialização múltipla contém várias informações, incluindo uma lista de módulos carregados e sua localização, que podem ser necessárias para posterior inicialização do sistema.
Para que o arquivo do programa contenha as assinaturas necessárias, criaremos um arquivo loader.s com o seguinte conteúdo:

Texto .global loader # tornando o ponto de entrada visível para o vinculador # configurando o cabeçalho Multiboot - consulte a documentação do GRUB para obter detalhes .set FLAGS, 0x0 # este é o campo "flag" do Multiboot .set MAGIC, 0x1BADB002 # "número mágico" permite que o bootloader encontre o cabeçalho .set CHECKSUM, -(MAGIC + FLAGS) # checksum necessário .align 4 .long MAGIC .long FLAGS .long CHECKSUM # reserva o espaço inicial da pilha do kernel .set STACKSIZE, 0x4000 # ou seja, 16k. .lcomm stack, STACKSIZE # reserva 16k stack .comm mbd, 4 # usaremos isso no kmain .comm magic, 4 # usaremos isso no carregador kmain: movl $(stack + STACKSIZE), %esp # configura a pilha movl %eax, magic # Número mágico de inicialização múltipla movl %ebx, mbd # Estrutura de dados de inicialização múltipla chama main # chama código C cli hang: hlt # máquina de parada deve o kernel retornar jmp hang

Vejamos o código com mais detalhes. Este código, quase inalterado, foi retirado de wiki.osdev.org/Bare_Bones. Como o gcc é usado para compilação, a sintaxe GAS é usada. Vamos dar uma olhada mais de perto no que esse código faz.
.texto
Todo o código subsequente terminará na seção executável.text.
carregador .global
Declaramos o símbolo do carregador visível para o vinculador. Isso é necessário porque o vinculador usará o carregador como ponto de entrada.
.set FLAGS, 0x0 # atribua FLAGS = 0x0 .set MAGIC, 0x1BADB002 # atribua MAGIC = 0x1BADB002 .set CHECKSUM, -(MAGIC + FLAGS) # atribua CHECKSUM = -(MAGIC + FLAGS) .align 4 # alinhe os dados subsequentes em 4 bytes .long MAGIC # coloca o valor de MAGIC no endereço atual .long FLAGS # coloca o valor de FLAGS no endereço atual .long CHECKSUM # coloca o valor de CHECKSUM no endereço atual
Este código gera uma assinatura no formato Multiboot. A diretiva .set define o valor do caractere para a expressão à direita da vírgula. A diretiva .align 4 alinha o conteúdo subsequente a 4 bytes. A diretiva .long armazena o valor nos próximos quatro bytes.
.set STACKSIZE, 0x4000 # set STACKSIZE = 0x4000 .lcomm stack, STACKSIZE # reserva bytes STACKSIZE. pilha refere-se a range.comm mbd, 4 # reserve 4 bytes para a variável mdb na área COMMON .comm magic, 4 # reserve 4 bytes para a variável mágica na área COMMON
Durante o processo de boot o grub não configura a pilha, e a primeira coisa que o kernel deve fazer é configurar a pilha, para isso reservamos 0x4000(16Kb) bytes. A diretiva.lcomm reserva o número de bytes especificado após o ponto decimal na seção.bss. O nome da pilha só ficará visível no arquivo compilado. A diretiva .comm faz o mesmo que .lcomm, mas o nome do símbolo será declarado globalmente. Isso significa que, escrevendo a seguinte linha em código C, podemos usá-la.
magia interna externa

E agora a última parte:
loader: movl $(stack + STACKSIZE), %esp # inicializa a pilha movl %eax, magic # escreve %eax no endereço magic movl %ebx, mbd # escreve %ebx no endereço mbd call main # chama a função principal cli # desabilita interrupções por travamento de hardware: hlt # para o processador até que ocorra uma interrupção jmp hang # salta para o rótulo de travamento

A primeira instrução armazena o valor no topo da pilha no registrador %esp. Como a pilha cresce para baixo, o endereço do final do intervalo alocado para a pilha é gravado em %esp. As próximas duas instruções armazenam em intervalos de 4 bytes previamente reservados os valores que o Grub passa nos registradores %eax, %ebx. Em seguida é chamada a função principal, que já está escrita em C. Se este procedimento retornar, o processador entrará em loop.

Passo 2. Preparando código adicional para o programa (biblioteca do sistema):

Como todo o programa foi escrito do zero, a função printf deve ser escrita do zero. Para fazer isso, você precisa preparar vários arquivos.
Vamos criar uma pasta comum e include:

Mkdir mkdir comum inclui

Vamos criar um arquivo common\printf.c, que conterá uma implementação da familiar função printf. Este arquivo pode ser obtido na íntegra no projeto www.bitvisor.org. Caminho para o arquivo nas fontes do bitvisor: core/printf.c. No arquivo printf.c copiado do bitvisor, para uso no programa alvo é necessário substituir as linhas:

#include "initfunc.h" #include "printf.h" #include "putchar.h" #include "spinlock.h"
para linhas:
#include "types.h" #include "stdarg.h" #include "screen.h"

Em seguida, remova a função printf_init_global e todas as suas referências neste arquivo:

Estático void printf_init_global (void) ( spinlock_init (&printf_lock); ) INITFUNC ("global0", printf_init_global);

Em seguida, remova a variável printf_lock e todas as referências a ela neste arquivo:
spinlock_t estático printf_lock; ... spinlock_lock (&printf_lock); ... spinlock_unlock (&printf_lock);

A função printf usa a função putchar, que também precisa ser escrita. Para fazer isso, crie um arquivo common\screen.c com o seguinte conteúdo:
#include "types.h" #define GREEN 0x2 #define MAX_COL 80 // Número máximo de colunas #define MAX_ROW 25 // Número máximo de linhas #define VRAM_SIZE (MAX_COL*MAX_ROW) // Tamanho da tela, em resumo # define DEF_VRAM_BASE 0xb8000 // Base padrão para memória de vídeo static unsigned char curr_col = 0; static unsigned char curr_row = 0; // Grava o caractere no local atual da tela #define PUT(c) (((unsigned short *) (DEF_VRAM_BASE)) \ [(curr_row * MAX_COL) + curr_col] = (VERDE<< 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; ) quebra; case "\b": if (curr_col > 0) ( curr_col -= 1; PUT(" "); ) break; padrão: 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 (eu = 0; eu< VRAM_SIZE; i++) cons_putc(" "); curr_col = 0; curr_row = 0; }

O código especificado contém lógica simples para imprimir caracteres na tela em modo texto. Neste modo, dois bytes são utilizados para gravar um caractere (um com o código do caractere, outro com seus atributos), gravado diretamente na memória de vídeo exibida imediatamente na tela e iniciando no endereço 0xB8000. A resolução da tela é de 80x25 caracteres. O caractere é impresso diretamente usando a macro PUT.
Agora faltam apenas alguns arquivos de cabeçalho:
1. Arquivo include\screen.h. Declara a função putchar, que é usada na função printf. Conteúdo do arquivo:
#ifndef _SCREEN_H #define _SCREEN_H void clear_screen(void); vazioputchar(int c); #fim se

2. Arquivo include\printf.h. Declara a função printf, que é usada em main. Conteúdo do arquivo:
#ifndef _PRINTF_H #define _PRINTF_H int printf (const char *formato, ...); #fim se

3. Arquivo include\stdarg.h. Declara funções para enumerar argumentos, cujo número não é conhecido antecipadamente. O arquivo inteiro foi retirado do projeto www.bitvisor.org. Caminho para o arquivo no código do projeto bitvisor: include\core\stdarg.h.
4. Arquivo include\types.h. Declara NULL e size_t. Conteúdo do arquivo:
#ifndef _TYPES_H #define _TYPES_H #define NULL 0 typedef unsigned int size_t; #fim se
Assim, as pastas include e common contêm o código mínimo da biblioteca do sistema que qualquer programa precisa.

Etapa 3: crie um script para o vinculador:

Criamos um arquivo linker.ld, que será usado pelo vinculador para gerar o arquivo do programa de destino (kernel.bin). O arquivo deve conter o seguinte:

ENTRADA (carregador) LMA = 0x00100000; SEÇÕES ( . = LMA; .multiboot ALIGN (0x1000) : ( loader.o(.text) ) .text ALIGN (0x1000) : ( *(.text) ) .rodata ALIGN (0x1000) : ( *(.rodata*) ) .data ALIGN (0x1000) : ( *(.data) ) .bss: ( *(COMMON) *(.bss) ) /DISCARD/ : ( *(.comment) ) )

A função integrada ENTRY() nos permite definir o ponto de entrada para nosso kernel. É para este endereço que o grub transferirá o controle após carregar o kernel. O vinculador usará este script para criar um arquivo binário no formato ELF. Um arquivo ELF consiste em um conjunto de segmentos e seções. A lista de segmentos está contida na tabela de cabeçalho do programa, a lista de seções na tabela de cabeçalho de seção. O vinculador opera com seções, o carregador de imagens (no nosso caso, GRUB) com segmentos.


Como pode ser visto na figura, os segmentos consistem em seções. Um dos campos que descreve uma seção é o endereço virtual onde a seção deve estar localizada no momento da execução. Na verdade, um segmento possui 2 campos que descrevem sua localização: o endereço virtual do segmento e o endereço físico do segmento. O endereço virtual de um segmento é o endereço virtual do primeiro byte do segmento no momento em que o código é executado, o endereço físico do segmento é o endereço físico no qual o segmento deve ser carregado. Para programas aplicativos, esses endereços são sempre os mesmos. Grub carrega segmentos de imagem por seu endereço físico. Como o Grub não configura o endereçamento de página, o endereço virtual de um segmento deve corresponder ao seu endereço físico, pois a memória virtual também não está configurada em nosso programa.

SEÇÕES
Indica que as seções são descritas abaixo.
. = ML;
Esta expressão informa ao vinculador que todas as seções subsequentes estão após o endereço LMA.
ALINHAR (0x1000)
A diretiva acima significa que a seção está alinhada em 0x1000 bytes.
.multiboot ALIGN (0x1000): (loader.o(.text))
Uma seção separada de inicialização múltipla, que inclui a seção .text do arquivo loader.o, é criada para garantir que a assinatura do formato de inicialização múltipla seja incluída nos primeiros 8kb da imagem do kernel.
.bss: ( *(COMUM) *(.bss) )
*(COMMON) é a área na qual a memória é reservada pelas instruções .comm e .lcomm. Colocamos na seção.bss.
/DISCARD/ : ( *(.comment) )
Todas as seções marcadas como DISCARD são removidas da imagem. Nesse caso, removemos a seção .comment, que contém informações sobre a versão do vinculador.

Agora vamos compilar o código em um arquivo binário usando os seguintes comandos:
como -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 comum/printf.c gcc -Iinclude -Wall -fno-builtin -nostdinc -nostdlib -o tela.o -c comum/tela.c ld -T linker.ld -o kernel.bin kernel.o tela.o printf .o carregador.o
Usando objdump, vamos ver como fica a imagem do kernel após a vinculação:
objdump -ph ./kernel.bin


Como você pode ver, as seções da imagem coincidem com aquelas que descrevemos no script do vinculador. O ligante formou 3 segmentos a partir das seções descritas. O primeiro segmento inclui as seções .multiboot, .text, .rodata e possui endereço virtual e físico 0x00100000. O segundo segmento contém as seções .data e .bss e está localizado no endereço 0x00104000. Isso significa que você está pronto para carregar este arquivo usando o Grub.

Etapa 4: Preparando o gerenciador de inicialização Grub:
Crie uma pasta grub:
mkdir grub

Copie para esta pasta vários arquivos Grub que são necessários para instalá-lo na imagem (os seguintes arquivos existem se o Grub estiver instalado no sistema). Para fazer isso você precisa executar os seguintes comandos:
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 /

Crie um arquivo grub/menu.lst com o seguinte conteúdo:
tempo limite 3 padrão 0 título mini_os root (hd0,0) kernel /kernel.bin

Etapa 5. Automatize e crie uma imagem de inicialização:

Para automatizar o processo de construção, usaremos o utilitário make. Para fazer isso, criaremos um makefile que irá compilar o código fonte, construir o kernel e criar uma imagem de boot. Makefile deve ter o seguinte conteúdo:

CC=gcc CFLAGS=-Wall -fno-builtin -nostdinc -nostdlib LD=ld OBJFILES=\loader.o\common/printf.o\common/screen.o\kernel.o imagem: @echo "Criando hdd.img. .." @dd if=/dev/zero of=./hdd.img bs=512 count=16065 1>/dev/null 2>&1 @echo "Criando a primeira partição FAT32 inicializável..." @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 || true @echo "Montando partição em /dev/loop2..." @losetup /dev/loop2 ./hdd.img \ --offset `echo \`fdisk -lu /dev/loop1 | sed-n 10p | awk "(imprimir $$3)"\`*512 | bc` \ --sizelimit `echo \`fdisk -lu /dev/loop1 | sed-n 10p | awk "(imprimir $$4)"\`*512 | bc` @losetup -d /dev/loop1 @echo "Formatar partição..." @mkdosfs /dev/loop2 @echo "Copiar arquivos do kernel e grub na partição..." @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 "Instalando GRUB. .." @echo "dispositivo (hd0) hdd.img \n \ root (hd0,0) \n \ setup (hd0) \n \ quit\n" | grub --batch 1>/dev/null @echo "Concluído!" tudo: kernel.bin reconstruir: limpar tudo .s.o: as -o $@ $< .c.o: $(CC) -Iinclude $(CFLAGS) -o $@ -c $< kernel.bin: $(OBJFILES) $(LD) -T linker.ld -o $@ $^ clean: rm -f $(OBJFILES) hdd.img kernel.bin

O arquivo declara dois objetivos principais: all - que compila o kernel, e image - que cria um disco de inicialização. O objetivo all, como o makefile usual, contém subgoals.s.o e.c.o, que compilam arquivos *.s e *.c em arquivos objeto (*.o), bem como um objetivo para gerar kernel.bin, que chama o vinculador com o script criado anteriormente. Esses destinos executam exatamente os mesmos comandos especificados na etapa 3.
De maior interesse aqui é a criação da imagem de inicialização hdd.img (imagem de destino). Vejamos como isso acontece passo a passo.
dd if=/dev/zero of=./hdd.img bs=512 contagem=16065 1>/dev/null 2>&1
Esta equipe cria uma imagem com a qual o trabalho futuro será realizado. O número de setores não foi escolhido aleatoriamente: 16065 = 255 * 63. Por padrão, o fdsik trabalha com o disco como se tivesse geometria CHS, em que Cabeçalhos (H) = 255, Setores (S) = 63, e Cilindros ( C) depende do tamanho do disco. Assim, o tamanho mínimo do disco com o qual o utilitário fdsik pode trabalhar, sem alterar a geometria padrão, é 512 * 255 * 63 * 1 = 8225280 bytes, onde 512 é o tamanho do setor e 1 é o número de cilindros.
A seguir, a tabela de partições é criada:
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 || verdadeiro
O primeiro comando monta o arquivo hdd.img no dispositivo de bloco /dev/loop1, permitindo que o arquivo seja tratado como um dispositivo. O segundo comando cria uma tabela de partição no dispositivo /dev/loop1 que contém 1 partição de disco de inicialização primária que ocupa todo o disco, denominada FAT32.
Em seguida, formatamos a partição criada. Para fazer isso, você precisa montá-lo como um dispositivo de bloco e formatá-lo.
Losetup /dev/loop2 ./hdd.img \ --offset `echo \`fdisk -lu /dev/loop1 | sed-n 10p | awk "(imprimir $$3)"\`*512 | bc` \ --sizelimit `echo \`fdisk -lu /dev/loop1 | sed-n 10p | awk "(imprimir $$4)"\`*512 | bc` perder configuração -d /dev/loop1
O primeiro comando monta a partição criada anteriormente no dispositivo /dev/loop2. A opção –offset especifica o endereço do início da seção e –sizelimit especifica o endereço do final da seção. Ambas as opções são obtidas usando o comando fdisk.
mkdosfs /dev/loop2
O utilitário mkdosfs formata a partição para o sistema de arquivos FAT32.
Para construir diretamente o kernel, são usados ​​os comandos discutidos anteriormente na sintaxe clássica do makefile.
Agora vamos ver como instalar o GRUB em uma partição:
mkdir -p tempdir # cria um diretório temporário mount /dev/loop2 tempdir # monta a partição no diretório mkdir tempdir/boot # cria um diretório /boot na partição cp -r grub tempdir/boot/ # copia a pasta grub para / boot cp kernel.bin tempdir / # copia o kernel para a raiz da partição sleep 1 # espere pelo Ubuntu umount /dev/loop2 # desmonte a pasta temporária rm -r tempdir # exclua a pasta temporária losstup -d /dev/loop2 # desmontar a partição
Após executar os comandos acima, a imagem estará pronta para instalação do GRUB. O comando a seguir instala o GRUB no MBR da imagem de disco hdd.img.
echo "dispositivo (hd0) hdd.img \n \ root (hd0,0) \n \ setup (hd0) \n \ quit\n" | grub --batch 1>/dev/null

Tudo está pronto para teste!

Etapa 6. Lançamento:

Para compilar, use o comando:
faça tudo
Depois disso, o arquivo kernel.bin deve aparecer.
Para criar uma imagem de disco inicializável, use o comando:
sudo criar imagem
Como resultado, o arquivo hdd.img deve aparecer.
Agora você pode inicializar a partir da imagem de disco hdd.img. Você pode verificar isso usando o seguinte comando:
qemu -hda hdd.img -m 32
ou:
qemu-system-i386 -hda hdd.img



Para verificar em uma máquina real, você precisa adicionar esta imagem a uma unidade flash e inicializar a partir dela. Por exemplo com este comando:
sudo dd if=./hdd.img of=/dev/sdb

Resumindo, podemos dizer que como resultado das ações realizadas, obtém-se um conjunto de códigos-fonte e scripts que nos permitem realizar diversos experimentos na área de programação de sistemas. O primeiro passo foi dado para a criação de software de sistema, como hipervisores e sistemas operacionais.

Quer permitir que usuários com uma conta padrão executem aplicativos com direitos administrativos sem UAC ou solicitação de senha? Então vou te dizer como fazer. Criaremos um atalho usando o comando runas /savecred, que salva a senha. Observe que isso pode ser considerado uma falha de segurança - um usuário comum poderá usar runas /savecred para executar qualquer comando como administrador sem inserir uma senha. No entanto, em algumas situações pode ser útil - por exemplo, se quiser que o seu filho seja tratado fora do padrão conta poderia executar aplicativos como administrador sem perguntar a você.

Habilite a conta de administrador

A primeira etapa é habilitar a conta de administrador integrada, que está desabilitada por padrão. Então clique com o botão direito no atalho linha de comando e selecione "Executar como administrador".

Na janela do prompt de comando que é aberta, execute o seguinte comando:

administrador de usuário da rede /ativo: sim


A conta agora está habilitada, embora sem senha. Para definir uma senha, abra o Painel de Controle, selecione a categoria Contas de Usuário e Segurança Familiar e abra o menu Contas de Usuário. Em seguida, clique no link “Gerenciar outra conta”.

Selecione a conta de administrador, clique no botão “Criar senha” e crie uma senha para a conta de administrador.

Crie um atalho

Agora criaremos um atalho que iniciará o aplicativo com privilégios de administrador. Clique com o botão direito na área de trabalho, selecione Novo e clique em Atalho.

Na janela que se abre, você precisa inserir o seguinte tipo de comando:

runas/usuário: Nome do computador\Administrador /savecred “ C:\Caminho\Para\Program.exe

Observe que você precisa substituir Nome do computador ao nome do seu computador e C:\Caminho\Para\Program.exe para o caminho completo do programa que você deseja executar. Por exemplo, se o nome do computador for Laptop e o programa que você deseja executar for Auslogics BoostSpeed, será necessário inserir o seguinte caminho:

runas /usuário:Laptop\Administrador /savecred “C:\Arquivos de Programas\Auslogics\Auslogics BoostSpeed\BoostSpeed.exe"


Na próxima janela, digite um nome para o atalho. Se desejar, você pode selecionar um ícone para o novo atalho - clique com o botão direito sobre ele e selecione “Propriedades”.

Na caixa de diálogo "Propriedades", clique no botão "Alterar ícone" e selecione o apropriado.

Na primeira vez que você clicar duas vezes no atalho, será solicitado que você insira a senha da conta de administrador criada anteriormente.


Esta senha será salva - na próxima vez que você iniciar o programa, não será necessário digitá-la novamente.

Conforme mencionado acima, nas contas padrão, os usuários podem executar qualquer programa com direitos de administrador sem inserir uma senha (usando o comando runas /savecred), portanto, tenha isso em mente.

A senha do administrador é armazenada no Credential Manager - se quiser remover a senha salva, você pode fazer isso a partir daí.

Tenha um ótimo dia!



gastroguru 2017