Author Topic: How to have permission to access ports?  (Read 16006 times)

nobody

  • Guest
How to have permission to access ports?
« on: December 18, 2008, 07:46:36 PM »
I write a simple code to read a port with the in instruction but when i run the program the in al, dx create a segmentation fault.

I find that to use in or out instruction in linux i first need permission but i don't know how?

The code:

global _start

section .data

section .text

_start:

mov dx, 03f8h
in al, dx

xor ebx, ebx      ; send 0 as 'exit code'
mov eax, 1      ; terminate process
int 80h         ; execute the syscall

nobody

  • Guest
Re: How to have permission to access ports?
« Reply #1 on: December 19, 2008, 12:24:04 AM »

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: How to have permission to access ports?
« Reply #2 on: December 19, 2008, 06:14:29 AM »
The emulator is probably a smarter idea, but we *can* get permission to diddle the ports. I don't think it's what we "should" do. Probably messing with ioctls to make the changes we want is safer. But we *can*...

Best,
Frank

global _start

; LED junk example | (CL) 2008 by ??? | 63 bytes !!!
; modified for Linux, fbk
; no longer 63 bytes!
;
; nasm -f elf32 kbled.asm
; ld -o kbled kbled.o
;
; (as root)
; chown root:root kbled
; chmod +s kbled
; (or run as root)

section .text
_start:
   nop ; parking place for gdb

mov ebx, 60h ; starting port
   mov ecx, 5   ; how many ports
   mov edx, 3   ; read/write (?)

mov eax, 101 ; __NR_ioperm
   int 80h

test eax, eax
   jns okay_ioperm
   neg eax ; (for display with "echo $?")
   jmp exit

okay_ioperm:

;------------------------------;
;  Rotate the keyboard LED's   ;
;------------------------------;

;-------------------------------------------------------------------;
; _________________        LED status byte:                         ;
; |0|0|0|0|0|1|1|1|                                                 ;
; +---------------+                     1 = True   0 = False        ;
;            | | +--->  scroll lock                                 ;
;            | +----->  num lock                                    ;
;            +------->  caps lock                                   ;
;-------------------------------------------------------------------;

; Main start
        mov   dl, 100       ; Amount of loops
        mov   bl, 2         ; Starting value
loo:
        ; Write to the LED's
        call  kbdwait
        mov   al, $0ED      ; command for "LED"
        out   $60, al
        call  kbdwait
        mov   al, bl        ; The LED value finally
        out   $60, al
;        call  kbdwait ; we need this one?

; Rotate
        shl   bl, 1
        cmp   bl, 8
        jne   .continue
        mov   bl, 1
.continue:
   mov eax, 500000000 ; 'arf a sec, guvnor
   call delay
        ; Continue or abort
        dec   dl
        jnz   loo     ; Looping back to the loo :-D

xor eax, eax      ; no error
exit:
   mov ebx, eax
   mov eax, 1 ; __NR_exit
   int 80h
        ;----

;------------------;
;  keyboard wait   ;
;------------------;

; b1 input buffer full (input 60/64 has data for 8042)
;    no write access allowed until bit clears
; b0 output buffer full (output 60 has data for system)
;    bit is cleared after read access

kbdwait:
;        out   $0ED, al       ; "DUMMY" port (as $EB) for delaying
        in    al, $64
        test  al, 1         ; Something to pick ?
        jz    short .inbuf_empty      ; NO :-(
;        out   $0ED, al       ; "DUMMY" port (as $EB) for delaying
        in    al, $60       ; Eat it
        jmp   short kbdwait
        ;------------------
.inbuf_empty:    test  al, 2         ; Buffer full flag - can write now ?
        jnz   short kbdwait ; Full - NO :-(
        ret
        ;----

;------------------
delay:
   push ebx
   push ecx

cmp eax, byte 1
   jbe .no_delay

xor ebx, ebx
.check_ns:
   cmp eax, 1000000000 ; limit for nanosleep 999999999 ns...
   jb .okay_ns
   sub eax, 1000000000
   inc ebx
   jmp short .check_ns
.okay_ns:

push eax ; set up a time_spec structure on the stack
   push ebx

.take_a_nap:
   mov eax, 162 ; __NR_nanosleep
   mov ebx, esp ; same structure for "request"
   mov ecx, esp ; and "remaining" - does this work?
   int 80h
   cmp eax, byte -4 ; -EINTR
   jz .take_a_nap

add esp, byte 8 ; remove time_spec "structure"

.no_delay:
   pop ecx
   pop ebx
   ret
;------------------