
   Power management.

   If you ever though about how to use just software methods to turn off
   the  hard  drives  or  reboot  your  computer  (without  pressing any
   buttons), then this article should answer all your questions.
     ________________________________________________________________

   Hard drives.

   (skip hard drives)
   As  a  decent system, Linux won't let us operate directly on the hard
   drive.  But  it will let us do it by using the system call sys_ioctl.
   Below  you'll  find a working (although to open the hard drive device
   file,  you  need  root privileges) piece of code which stops the hard
   drive.  I  wrote  this  code thanks to analysing the hdparm program's
   source  code  (you'll  find  all  the details there and on the manual
   pages: ioctl, ioctl_list). If you aren't using my library, change the
   constant names to their value given in the comments.
   Here's the code (NASM syntax):
   (skip code for stopping hard drives)
%include "bibl/incl/nasm/n_system.inc"          ; system constants

section .text

global _start

_start:
        mov     eax, sys_open                   ; =5. open the file....
        mov     ebx, dysk                       ; ....of the hard drive
        mov     ecx, O_RDONLY|O_NONBLOCK        ; 04000q octal
        int     80h

        cmp     eax, 0
        jle     koniec                          ; if there's an erro,
                                                ; leave the program

        mov     ebx, eax                ; save the file descriptor

        mov     eax, sys_ioctl                  ; =54
        ; EBX = deskryptor pliku
        mov     ecx, 0x031f                     ; drive special command
        mov     edx, args1                      ; first parameters
        int     80h

        mov     eax, sys_ioctl
        ; EBX = deskryptor pliku
        mov     ecx, 0x031f                     ; drive special command
        mov     edx, args2                      ; second parameters
        int     80h

        mov     eax, sys_close                  ; =6
        ; EBX = deskryptor pliku
        int     80h                             ; close the open file

koniec:
        mov     eax, sys_exit                   ; =1
        xor     ebx, ebx
        int     80h                             ; exit the program

section .data
args1   db      0e6h, 0, 0, 0                   ; copied from hdparm.c
args2   db      99h, 0, 0, 0                    ; also copied
dysk    db      "/dev/hda",0                    ; first drive,hdb = second

   NOTE:  you  need to wait for while for the program to finish working.
   During the program running, your computer may stop responding.
   After  stopping  the  hard drive it can be started again by doing any
   file   system   operation  (like  displaying  the  current  directory
   contents).
     ________________________________________________________________

   Rebooting the computer or switching it off.

   (skip rebooting)
   In  order  to  reboot  the  computer,  we're  going to use the system
   function sys_reboot, giving it the right parameters. Here's a program
   which immediately reboots the computer:
   (skip the reboot program)
%include "bibl/incl/nasm/n_system.inc"

section .text

global _start

_start:
        mov     eax, sys_reboot                 ; =88
        mov     ebx, 0fee1deadh                 ; required constant
        mov     ecx, 672274793                  ; required constant
                                ; EDX = reboot mode. Here: normal reboot
        mov     edx, LINUX_REBOOT_CMD_RESTART   ; =0x01234567
        int     80h

        ; what's below will never be executed
        mov     eax, sys_exit                   ; =1
        xor     ebx, ebx
        int     80h

   Here's a program which immediately switches off the computer:
   (skip the poweroff program)
%include "bibl/incl/nasm/n_system.inc"

section .text

global _start

_start:
        mov     eax, sys_reboot                 ; =88
        mov     ebx, 0fee1deadh                 ; required constant
        mov     ecx, 672274793                  ; required constant
                        ; EDX = reboot mode. Here: poweroff
        mov     edx, LINUX_REBOOT_CMD_POWER_OFF ; =0x4321FEDC
        int     80h

        ; what's below will never be executed
        mov     eax, sys_exit                   ; =1
        xor     ebx, ebx
        int     80h

   NOTE:  because  of  the  fact,  that the given programs switch off or
   reboot  the  machine  right  after launching them, I do NOT recommend
   using them, as this may be bad for the file system.
     ________________________________________________________________

   Turning the monitor off.

   Well,  maybe  this won't be exactly turning off, but in any case, the
   displayed  picture  will  be  gone. To do this, we're going to use to
   svgalib library (to compile the program, a svgalib-devel package will
   probably be necessary).
   Everything  is very simple: initialize the library using the vga_init
   function, turn the picture off using the vga_screenoff function, wait
   for  a  key  being pressed (system function sys_read reading from the
   standard  input)  and  bring the picture back using vga_screenon. The
   vga functions do not need any parameters.
   The program looks like this:
   (skip monitor switching off code)
; Program uses SVGAlib to switc off the monitor
;
; Author: Bogdan D., bogdandr (at) op.pl
; compile:
;   nasm -O999 -f elf -o mon_off.o mon_off.asm
;   gcc -o mon_off mon_off.o -lvga

section .text
global  main

extern  vga_screenoff
extern  vga_screenon
extern  vga_init

%idefine        stdin           0
%idefine        sys_read        3

main:
        call    vga_init
        call    vga_screenoff

        mov     eax, sys_read   ; read-from-file function
        mov     ebx, stdin      ; standard input
        mov     ecx, znak       ; address of where to put the data
        mov     edx, 1          ; read 1 byte
        int     80h

        call    vga_screenon

        ret

section .data

znak            db      0

   Notice  the compiling method. Since we're using C language libraries,
   we'll  use GCC for compiling. Then, our entry function must be called
   main - just like in C language programs (and just like in C programs,
   we  can  end it with a RET). The needed functions are simply declared
   external (extern).
   I  ran  this program under a graphical environment (X11). Nothing bad
   happened, but after the program was finished, I had to go to the text
   console  (Ctrl+Alt+F1)  and  then go back to the graphic interface to
   bring the picture back.
   To  work  under  X,  this program may need access to the /dev/console
   file, under the text console - to /dev/mem.

   On-line contents (Alt+2)
   Helpers for people with disabilities (Alt+0)
