fun with linux device parameters
well i think i had a good start with this one. never really did any real interaction with linux device files in assembly. so i decided i’d try some experiments today. my list included doing something with regards to the linux framebuffer, virtual terminals and sound/dsp devices. it seems though that they require considerable effort to learn. after reading some man pages and header files, i decided to begin yet another chapter in my assembly adventure by manipulating the cd rom device in linux. this afternoon, i made my own version on the linux eject command. it only has two functions, that is, to open the cdrom tray, and close it. pretty basic huh? i want to get comfortable with the whole idea of device control first before doing any of the activities i mentioned a while ago.
[ introduction ]
from ioctl(2) manual…DESCRIPTION
The ioctl function manipulates the underlying device parameters of special files. In particular, many operating characteristics of character special files (e.g. terminals) may be controlled with ioctl requests. The argument d must be an open file descriptor.
i started out knowing only that /dev/cdrom is a symlink to /dev/hdc which is consequently, my cdrom drive. and that sys_ioctl is the linux system call responsible for interfacing with character and device files. eventually, i reached the ioctl_list(2) manual page after going thu the ioctl(2) manual a few times over. specially since the later doesn’t have any examples in it.
so now i have something to work with.
a) open a cdrom device (/dev/cdrom) so i can have a file descriptor for it.
b) use the new file descriptor when calling ioctl with the appropriate request and the appropriate structure (if necessary).
i confirmed the those steps above by running /usr/bin/eject under strace. it looked doable so i fired up vim and what do you know? the eject thingy i did works! -t flag closes the tray.
; /usr/include/linux/cdrom.h
; see also man ioctl_list(2)
%define CDROMEJECT 0x5309 ;/* Ejects the cdrom media */
%define CDROMCLOSETRAY 0x5319 ;/* pendant of CDROMEJECT */
; /usr/include/bits/fcntl.h
%define O_RDONLY 00
%define O_NONBLOCK 0x800 ; 04000
; /usr/include/asm/unistd.h
%define SYS_OPEN 0x0005
%define SYS_IOCTL 0x0036
global _start
section .text
_start
mov ecx, (O_RDONLY | O_NONBLOCK)
mov ebx, CD_DRIVE
mov eax, SYS_OPEN
int 0x80 ; open our default cdrom device file
test eax, eax ; set the sign flag
js quit ; error in opening device file.
pop ecx ; int argc
dec ecx ; number of arguments
mov ebx, eax ; ebx holds file descriptor to cdrom device
push CDROMEJECT
jz do_action
dec ecx
jnz quit ; too many arguments
pop ecx
pop ecx ; argv[0]
pop ecx ; argv[1]
cmp word [ecx], '-t'
jne quit
cmp byte [ecx+2], 0x0
jne quit
push CDROMCLOSETRAY ; ebx is already set
do_action
pop ecx
mov eax, SYS_IOCTL
int 0x80
test eax, eax
js quit
xor eax, eax
quit
mov ebx, eax
mov eax, 1
int 0x80
section .data
CD_DRIVE db '/dev/cdrom'
but yeah, it doesn’t print any message whatsoever. nor can it accept a user defined device file to eject. but that is an exercise for another day. i’m sleepy now.
bye bye.
