wiki:WikiStart

Version 21 (modified by lorenzo, 16 years ago) ( diff )

--

Laboratorio di Sistemi Operativi

TOC(noheading)

Lezione 1: Introduzione

Slide

Programmi

  • Accesso diretto alla macchina fisica mioboot-nobios-simple.asm
    bits 16                         ; 16 bit real mode
    org 0x7C00                      ; origine indirizzo 0000:7C00
    
    start:	
     mov ax, 0xb800	 ; text video memory
     mov ds, ax
     mov eax, 10
    write:
     cmp eax, 0
     jz end
     mov byte [eax], 'm'
     mov byte [eax+1], 0x0F    ; attrib = white on black
     sub eax, 2
     jmp write
    end:
     hlt
    
    times 510-($-$$) db 0 ; 0-padding 
    dw 0xAA55
    
    nasm -l mioboot-nobios-simple.lst -o mioboot-nobios-simple.img mioboot-nobios-simple.asm
    qemu mioboot-nobios-simple.img
    
  • Uso dei servizi del BIOS mioboot.asm
    bits 16                         ; 16 bit real mode
    org 0x7C00                      ; origine indirizzo 0000:7C00
            
    start:
            cld                     ; clears direction flag (index regs incremented)
            mov si, boot
            call message
    working:
            mov si, work
            call message
    
            call waitenter
            jmp working
    
    message:
            lodsb                   ; carica un byte da [DS:SI] in AL e inc SI
            cmp al, 0
            jz done
            mov ah, 0x0E            ; write char to screen in text mode
            mov bx, 0               ; BH page number BL foreground color
            int 0x10                ; write AL to screen (BIOS)
            jmp message
    done:   ret
    
    boot: db "Loading unuseful system...." , 10, 13, 0
    work: db "I've done my unuseful stuff!" , 10, 13, 0 
    cont: db "Hit ENTER to continue...", 10, 13, 0
    wow: db "Great! Hello world!" , 10, 13, 0
            
    waitenter: mov si, cont
               call message
               mov ah, 0
               int 0x16                ; Wait for keypress (BIOS)
               cmp al, 'm'
               jz egg
               cmp al, 'b'
               jz basic
               cmp al, 13
               jnz waitenter
               ret
    egg:       mov si, wow
               call message
               jmp waitenter
    basic:     int 0x18		; basic (BIOS)
               hlt
    
            times 510-($-$$) db 0
            dw 0xAA55
    
    nasm -l mioboot.lst -o mioboot.img mioboot.asm
    qemu mioboot.img
    # con qemu -d in_asm potete vedere (in /tmp/qemu.log) il codice eseguito dalla macchina virtuale: per la maggior parte istruzioni del BIOS 
    
  • Programma che esegue il codice letto da standard input exec.c
    #include <stdio.h>
    
    int main() {
      unsigned char buf[1024];
      void (*ptr)();
      int n;
      unsigned int eax;
    
      // leggi il codice da eseguire da standard input
      n = read(0, buf, 1024);
      // forza il codice a ritornare dalla chiamata a funzione (0xC3 = ret)
      buf[n] = '\xc3';
    
      // esegui il codice letto come se fosse una funzione
      ptr = (void(*)()) buf;
      ptr();
    
      // stampa il valore del registro EAX
      __asm__("mov %%eax, %0" : "=m"(eax));
      printf("EAX: %.8x\n", eax);
    
      return 0;
    }
    
    gcc -o exec exec.c
    echo -ne "\xB8\x11\x22\x33\x44" | ./exec
    echo -n "ciao" | ./exec
    ...
    

Lezione 2

Slide

Esercizi

fork

/* un programma che "forca" un nuovo processo */

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(void){
  int x = fork();
  if (x < 0){
      perror("Errore nella fork:");
      exit(1);
  } else {
    if (x != 0){
      while(1){
        sleep(1);
        printf("Processo padre (Figlio: %d)\n", x);
      }
    } else {
      while(1) {
       printf("Processo figlio (%d)\n", x);
       sleep(1);
      }
    }
  }
  return 0;
}

/* da compilare con un comando del tipo 'cc -o prova prova.c' */
/* Per terminare Ctrl-C */

Exit status

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  int i;

  if (argc != 2)
    return -1;

  return atoi(argv[1]);
}

/* da compilare con un comando del tipo 'cc -o prova prova.c' */
/* Per verificare l'exit status: ./prova ; echo $? */

Esecuzione in sequenza e parallelo

#include <stdio.h>
#include <unistd.h>

int main(void){
  int i = 0;
  for (i=0; i<10; ++i){
    sleep(1);
    printf("%d: %d\n", getpid(), i);
  }
  return 0;
}
# In sequenza
./hello ; ./hello
# In parallelo
./hello & ./hello
echo $?

Cosa fa?

/usr/bin/touch piripacchio
while /bin/ls piripacchio; do
 /usr/bin/sleep 2
 /bin/echo ciao
done & ( /usr/bin/sleep 10 ; /bin/rm piripacchio )

Consultate il manuale!

man man
man touch
man ls
man 1 sleep # man 3 sleep è il manuale della funzione della libreria C
man echo
man rm

Uso del for e if

for i in dog cat fish; do if ls /bin/$i; then echo Trovato $i; else echo $i non trovato; fi; done
man test
for i in dog cat fish; do if test -f /bin/$i; then echo Trovato $i; else echo $i non trovato; fi; done

Link

Lezione 3

Slide

Materiale

stdout.c
/* 
   scrive st stdout(1) gli argomenti ricevuti sulla riga di comando

   utile per capire come funzionano quoting, escaping e command substitution nella shell:
   e.s. ./stdout "ciao ciao"
        ./stdout ciao ciao
        a="giallo"; b="rosso" ; ./stdout "$a $b"
        ./stdout $(ls /etc)

   compilare con: cc -o stdout stdout.c

*/

#include <stdio.h>

int main(int argc, char **argv) {
  int i;

  for (i = 0; i < argc; i++) {
    printf("%d: %s\n", i, argv[i]);
  }

  return 0;
}

stdouterr.c

/*
   scrive su stdout(1)  e stderr (2) gli argomenti ricevuti sulla riga di
   comando; l'i-esimo argomento viene scritto su stdout se i e' pari e su
   stderr se i e' dispari
   
   utile per capire come funzionano redirezione e pipe nella shell
   e.s. ./stdouterr "primo argomento" "secondo argomento" | cat
        ./stdouterr "primo argomento" "secondo argomento" 2> /tmp/2
        ./stdouterr "primo" "secondo" 2> /dev/null

   per compilare: cc -o stdouterr stdouterr.c
*/

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
  int i;
  char buf[2048];

  for (i = 0; i < argc; i++) {
    snprintf(buf, 2047, "%d: %s\n", i, argv[i]);
    write(i % 2 + 1, buf, strlen(buf));
  }

  return 0;
}

Esercizi online (per turno 2)

Note: See TracWiki for help on using the wiki.