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.
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):
%include "bibl/incl/linuxbsd/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 error, ; leave the program mov ebx, eax ; save the file descriptor mov eax, sys_ioctl ; =54 ; EBX = file descriptor mov ecx, 0x031f ; drive special command mov edx, args1 ; first parameters int 80h mov eax, sys_ioctl ; EBX = file descriptor mov ecx, 0x031f ; drive special command mov edx, args2 ; second parameters int 80h mov eax, sys_close ; =6 ; EBX = file descriptor 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).
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:
%include "bibl/incl/linuxbsd/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:
%include "bibl/incl/linuxbsd/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.
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:
; 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.