Create TOC

2009년 5월 19일

Debian/PS2 키보드가 인식되지 않을 때

부팅시 아래와 같은 메시지와 함께 PS/2 키보드가 바로 인식되지 않을 수 있다.

PNP: PS/2 appears to have AUX port disabled, if this is incorrect please boot with i8042.nopnp

일부 BIOS 에서 발생할 수 있는 문제이며 부트 로더에 커널 인자로 아래 값을 추가한다.

i8042.nopnp=1

Grub을 사용한다면 아래와 같이 커널 인자를 전달할 수 있다.

title       Debian GNU/Linux 5.0
root        (hd0,1)
kernel      /boot/vmlinuz-2.6.29.090518 root=UUID=7d0ee3d0-05cd-4737-ba08-2dee  eeff6ea9 ro i8042.nopnp=1 vga=785 splash quiet
initrd      /boot/initrd.img-2.6.29.090518

Debian/Kernel 패키지 만들기

kernel을 컴파일해서 사용할 때, debian에서는 패키지*.deb 파일을 말한다.를 만드는 것을 권장한다.

사용자 권한 추가

$ sudo adduser user_id src

권한 추가 후 groups 명령을 통해서 확인한다.

소스 준비

소스 패키기 설치

$ apt-get install linux-source-x.y.z

소스 풀기

$ cd /usr/src
$ tar xvfj linux-source-x.y.z.tar.bz2

링크 생성

$ ln -s linux-source-x.y.z linux

커널 패키지 만들기

커널 설정

$ make menuconfig

또는

$ make-kpkg --config=menuconfig configure

빌드

$ make-kpkg clean
$ fakeroot make-kpkg debian
$ CONCURRENCY_LEVEL=2 fakeroot make-kpkg -append-to-version=.090519 --initrd binary-arch

  • --initrd 옵션은 커널 옵션 중 initrd support 가 켜져 있어야 한다.
  • CONCURRENCY_LEVEL=2make -j2 옵션을 주는 것과 동일하다. cpu * 2 정도의 수를 입력한다.(안줘도 상관은 없다)
  • -append-to-version은 내가 빌드한 커널에 버전 값을 추가할 때 사용한다.

자동으로 -append-to-version을 붙이기 위해서 아래와 같은 간단한 shell script를 사용하기도 한다.

#!/bin/sh

APPENDVERSION=.`date +%y%m%d`
cd /usr/src/linux
fakeroot make-kpkg debian
CONCURRENCY_LEVEL=6 fakeroot make-kpkg -append-to-version=$APPENDVERSION --initrd binary-arch

설치

Kernel 패키지 설치

빌드가 끝나면 /usr/src에 3개의 package가 생성된다.

  • linux-headers-x.y.z.090519_x.y.z.090519-10.00.Custom_i386.deb
  • linux-image-x.y.z.090519_x.y.z.090519-10.00.Custom_i386.deb
  • linux-image-x.y.z.090519-dbg_x.y.z.090519-10.00.Custom_i386.deb

만들어진 패키지를 아래 명령으로 설치한다.

$ sudo dpkg -i linux-headers-x.y.z.090519_x.y.z.090519-10.00.Custom_i386.deb
$ sudo dpkg -i linux-image-x.y.z.090519_x.y.z.090519-10.00.Custom_i386.deb

ramdisk 업데이트

--initrd 옵션을 사용했다면 아래 명령으로 ramdisk 이미지를 갱신한다.

$ sudo update-initramfs -c -t -k x.y.z.090519

드라이버 업데이트

nvidia, VirtualBox 드라이버 등을 사용했다면 방금 빌드한 커널을 위해서 드라이버 모듈을 다시 빌드한다.

$ sudo m-a -l x.y.z.090519 a-i nvidia
$ sudo m-a -l x.y.z.090519 a-i virtualbox-ose

부트 로더 수정

빌드한 커널 이미지는 /boot/vmlinuz-x.y.z.090519 에 생성된다. 부트 로더를 이에 맞게 수정해준다.GRUB를 사용한다면 update-grub명령만 실행하면 된다.

Reference

Python/py2exe를 이용해서 win32 binary를 만들때 manifest 추가

Windows 환경에서 py2exe 를 이용해서 exe를 만들때 manifest 를 추가할 수 있다.

setup.py를 아래와 같이 만든다.

manifest = """
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <asmv3:trustInfo xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
    <asmv3:security>
      <asmv3:requestedPrivileges>
        <asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
      </asmv3:requestedPrivileges>
    </asmv3:security>
  </asmv3:trustInfo>
</assembly>
"""

setup(name='MyApp',
    #...
    windows=[ { #...
        'other_resources':[(24, 1, manifest)],
    }]
)

2009년 5월 16일

Ubuntu Netbook Remix

Ubuntu Netbook RemixVirtualBox에 설치해보았다.

Ubuntu Netbook Remix는 iso대신 img 파일만 제공하기 때문에 아래 링크의 내용을 참조해서 VirtualBox에 설치했다.

http://platonic.techfiz.info/2009/04/26/ubuntu-netbook-on-virtualbox/

설치 후 첫 로그인 화면은 아래와 같다.

Ubuntu Netook Remix에서는 화면이 작고 해상도가 낮은 Netbook을 위해서 여러가지 기능이 추가되어 있다. 우선 로그인 후 보이는 기본 화면. 좌측 위의 우분투 아이콘을 클릭하면 항상 이 화면을 볼 수 있다. 프로그램 시작 메뉴 역할도 같이 하는데 화면에 크게 크게 표시되는 아이콘이 특징이다.

불여우를 실행한 화면. 거의 모든 프로그램이 전체 화면으로 실행되며 실행한 프로그램은 좌측 상단에 아이콘이 추가된다. 해상도가 낮은 Netbook을 고려한 기능이다.

여러 프로그램을 실행한 모습.

추가된 기능은 시작 프로그램 형태로 제공된다(화면을 보면 Maximus Window Manager와 Netbook Launcher를 볼 수 있다).

2009년 5월 12일

Python/PyGTK

PyGTK 예제 소스를 순수 API를 호출하는 방법과 GtkBuilder를 사용한 방법으로 각각 구현해본다.

Hello, World

아래와 같은 모습을 가지도록 프로그램을 수정한다.

API 호출

코드

hello.py


#!/usr/bin/python
# -*- coding: utf-8 -*-
import gtk

class HelloWorld :
    def hello(self, widget, data=None) :
        print 'Hello, World'

    def delete_event(self, widget, event, data=None):
        print 'delete event occurred'
        return False

    def destroy(self, widget, data=None) :
        gtk.main_quit()

    def __init__(self) :
        self._win = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self._win.connect('delete_event', self.delete_event)
        self._win.connect('destroy', self.destroy)
        self._win.set_border_width(10)
        self._btnhello = gtk.Button('Hello World')
        self._btnhello.connect('clicked', self.hello, None)
        self._btnhello.connect_object('clicked', gtk.Widget.destroy, self._win)
        self._win.add(self._btnhello)

    def main(self) :
        self._win.show_all()
        gtk.main()

def main() :
    w = HelloWorld()
    w.main()

if __name__ == '__main__' :
    main()

GtkBuilder

GtkBuilder를 사용하면 ui 구성 코드를 xml로 분리할 수 있다.

코드

hello.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<interface>
  <object class="GtkWindow" id="HelloWindow">
    <property name="border_width">10</property>
    <signal name="delete_event" handler="delete_event" />
    <signal name="destroy" handler="destroy" />
    <child>
      <object class="GtkButton" id="BtnHello">
        <property name="label">Hello, world</property>
        <signal name="clicked" handler="hello" />
      </object>
    </child>
  </object>
</interface>

hello2.py

>#!/usr/bin/python # -*- coding: utf-8 -*- import gtk class HelloWorld : def hello(self, widget, data=None) : print 'Hello, World' def delete_event(self, widget, event, data=None): print 'delete event occurred' return False def destroy(self, widget, data=None) : gtk.main_quit() def __init__(self) : builder = gtk.Builder() builder.add_from_file('hello2.xml') builder.connect_signals(self) self._win = builder.get_object('HelloWindow') self._btnhello = builder.get_object('BtnHello') self._btnhello.connect_object('clicked', gtk.Widget.destroy, self._win) def main(self) : self._win.show_all() gtk.main() def main() : w = HelloWorld() w.main() if __name__ == '__main__' : main()

Hello, World 업그레이드

아래와 같은 모습을 가지도록 프로그램을 수정한다.

API 호출

코드

hello_upgrade.py

>#!/usr/bin/python # -*- coding: utf-8 -*- import gtk class HelloWorld2 : def callback(self, widget, data) : print 'Hello again - %s was pressed ' % data def delete_event(self, widget, event, data=None): gtk.main_quit() return False def __init__(self) : self._win = gtk.Window(gtk.WINDOW_TOPLEVEL) self._win.set_title('Hello Buttons!') self._win.connect('delete_event', self.delete_event) self._win.set_border_width(10) self._box1 = gtk.HBox(False, 0) self._win.add(self._box1) self._button1 = gtk.Button('Button 1') self._button1.connect('clicked', self.callback, 'button 1') self._box1.pack_start(self._button1, True, True, 0) self._button2 = gtk.Button('Button 2') self._button2.connect('clicked', self.callback, 'button 2') self._box1.pack_start(self._button2, True, True, 0) def main(self) : self._win.show_all() gtk.main() def main() : w = HelloWorld2() w.main() if __name__ == '__main__' : main()

GtkBuilder

코드

hello2_upgrade.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<interface>
  <object class="GtkWindow" id="HelloWindow">
    <property name="title">Hello Buttons!</property>
    <property name="border_width">10</property>
    <signal name="delete_event" handler="delete_event" />
    <child>
      <object class="GtkHBox" id="box1">
        <child>
          <object class="GtkButton" id="button1">
            <property name="label">Button 1</property>
            <signal name="clicked" handler="callback" />
          </object>
        </child>
        <child>
          <object class="GtkButton" id="button2">
            <property name="label">Button 2</property>
            <signal name="clicked" handler="callback" />
          </object>
        </child>
      </object>
    </child>
  </object>
</interface>

hello2_upgrade.py

#!/usr/bin/python
# -*- coding: utf-8 -*-
import gtk

class HelloWorld2 :
    def callback(self, widget, data = None) :
        print 'Hello again - %s was pressed ' % widget.get_name()

    def delete_event(self, widget, event, data=None):
        gtk.main_quit()
        return False

    def __init__(self) :
        builder = gtk.Builder()
        builder.add_from_file('hello2_upgrade.xml')
        builder.connect_signals(self)
        self._win = builder.get_object('HelloWindow')

    def main(self) :
        self._win.show_all()
        gtk.main()

def main() :
    w = HelloWorld2()
    w.main()

if __name__ == '__main__' :
    main()

Reference

2009년 5월 8일

Urlencode된 파일 이름을 Decode하기

Opera에서 파일을 받으면 한글이름일 경우 urlencode 된 이름으로 저장된다. decode 하는 간단한 스크립트를 작성했다

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os
import sys
import urllib


def printUsing():
    """사용 방법을 출력한다."""
    print 'fixname.py  [  ...]'


def getUnquoteFileName(name):
    try:
        return unicode(urllib.unquote(name).decode('utf-8'))
    except UnicodeDecodeError:
        return unicode(urllib.unquote(name).decode('cp949'))


def main():
    for argv in filter(os.path.isfile, sys.argv[1:]):
        decoded_argv = getUnquoteFileName(argv)
        if argv != decoded_argv:
            print '%s -> %s' % (argv, decoded_argv)
            os.rename(argv, decoded_argv)

if __name__ == '__main__':
    if len(sys.argv) < 2:
        printUsing()
    else:
        main()

2009년 5월 3일

Debian/HDTV 시청하기

이 문서는 Debian_Sid kernel 2.6.29 에서 HDTV 를 보기 위한 방법을 기술한다.

장치 설정

HDTV 카드

Dvico FusionHDTV5 USB Gold

ItemSpecifications
Input/OutputTV antenna reception port 1 Composite(using dongle cable), 1 S-Video Video Input Direct audio stream output to sound card(HDTV)
Compatibility (DVHS)Running on Windows XP or later only. 1394(Firewire) port
DriversConexant CX23882 drivers Dvico's own tuner driver Dvico's own full software HDTV decoder Dvico's own DxVA software HDTV decoder

커널 설정

-> Device Drivers
  ->Multimedia devices
   -> <M> DVB for Linux
    -> [*] Load and attach frontend and tuner driver modules as needed
    -> [*] Video capture adapters
      -> <M> BT848 Video For Linux
          -> [*] DVB/ATSC Support for bt878 based TV cards
      -> <M> Conexant 2388x (bt878 successor) support
          -> <M> Conexant 2388x DMA audio support
          -> <M> Blackbird MPEG encoder support (cx2388x + cx23416)
          -> <M> DVB/ATSC Support for cx2388x based TV cards
    -> [*] DVB/ATSC adapters
      -> <M> Support for various USB DVB devices
          -> [*] Conexant USB2.0 hybrid reference design support

펌웨어 설치

$ cd /usr/src/linux/Documentation/dvb
$ sudo perl get_dvb_firmware  bluebird
$ sudo  mv dvb-usb-bluebird-01.fw /usr/lib/hotplug/firmware
$ sudo ln -s /usr/lib/hotplug/firmware/dvb-usb-bluebird-01.fw /lib/firmware

또는

$ sudo wget http://www.linuxtv.org/download/dvb/firmware/dvb-usb-bluebird-01.fw
$ sudo  mv dvb-usb-bluebird-01.fw /usr/lib/hotplug/firmware
$ sudo ln -s /usr/lib/hotplug/firmware/dvb-usb-bluebird-01.fw /lib/firmware

디바이스 동작 확인

USB 에 접속한 후 아래와 같은 방법으로 확인한다.

dmesg로 확인

dvb-usb: generic DVB-USB module successfully deinitialized and disconnected.
usb 1-4: new high speed USB device using ehci_hcd and address 6
usb 1-4: configuration #1 chosen from 1 choice
dvb-usb: found a 'DViCO FusionHDTV5 USB Gold' in warm state.
dvb-usb: will pass the complete MPEG2 transport stream to the software demuxer.
DVB: registering new adapter (DViCO FusionHDTV5 USB Gold)
DVB: registering adapter 0 frontend 0 (LG Electronics LGDT3303 VSB/QAM Frontend)...
tuner-simple 4-0061: creating new instance
tuner-simple 4-0061: type set to 64 (LG TDVS-H06xF)
input: IR-receiver inside an USB DVB receiver as /class/input/input5
dvb-usb: schedule remote query interval to 100 msecs.
dvb-usb: DViCO FusionHDTV5 USB Gold successfully initialized and connected.

device 로 확인

$ ls -l /dev/dvb/adapter0/
crw-rw----+ 1 root video 212, 4 2009-04-21 22:50 demux0
crw-rw----+ 1 root video 212, 5 2009-04-21 22:50 dvr0
crw-rw----+ 1 root video 212, 3 2009-04-21 22:50 frontend0
crw-rw----+ 1 root video 212, 7 2009-04-21 22:50 net0

채널 검색

프로그램 설치

$ sudo apt-get install dvb-apps

채널 검색

안테나 사용시

$ mkdir ~/.azap
$ scan /usr/share/dvb/atsc/us-ATSC-center-frequencies-8VSB >> ~/.azap/channels.conf

케이블1

/usr/share/dvb/atsc/us-Cable-Standard-center-frequencies-QAM256 파일을 ~/us-Cable-Standard-center-frequencies-8VSB으로 복사한 후 vi등 에디터를 이용해서 파일안의 QAM256을 모두 8VSB로 변경한 후 scan 명령을 사용한다.

$ mkdir ~/.azap
$ scan ~/us-Cable-Standard-center-frequencies-8VSB >> ~/.azap/channels.conf

케이블2

$ mkdir ~/.azap
$ scan /usr/share/dvb/atsc/us-Cable-Standard-center-frequencies-QAM256 >> ~/.azap/channels.conf

채널 이름 설정

~/.azap/channels.conf 를 열어보면 채널 이름 없이 아래처럼 나온다(집이 난시청 지역인지 MBC는 보이지 않는다.).

$ cat ~/.azap/channel.conf
:623028615:8VSB:17:20:1
:641028615:8VSB:33:36:1
:677028615:8VSB:33:36:1
MBC DTV:749028615:8VSB:17:20:1

채널 이름을 넣어준다.채널 값은 지역마다 다를 수 있기 때문에 꼭 scan 해봐야 한다.

EBS:623028615:8VSB:17:20:1
KBS1:641028615:8VSB:33:36:1
KBS2:677028615:8VSB:33:36:1
MBC DTV:749028615:8VSB:17:20:1

리모콘 설정

@todo

프로그램별 설정

Mplayer

채널 설정

$ ln -s ~/.azap/channels.conf ~/.mplayer/channels.conf

TV 시청

실행할 때 채널 이름을 직접 입력한다.

mplayer dvb://KBS1

Totem

채널 설정

Totem은 backend로 GStreamer gst-plugins-bad 0.10.6 을 필요로 한다.또는 Xine을 사용할 수 있는데 이 문서에서는 GStreamer를 사용한다고 가정한다.

$ ln -s ~/.azap/channels.conf ~/.gstreamer-0.10/dvb-channels.conf

TV 시청

동영상 - 'DVB 어댑터 0' 에서 TV 보기 메뉴를 선택한다.GStreamer 문제인지 다른 설정 문제인지 몰라도 첫 화면이 표시된 후 화면이 갱신되지 않는다(정지 화면처럼 보인다.

채널 선택은 playlist를 사용한다.

Xine

채널 설정

$ ln -s ~/.azap/channels.conf ~/.xine/channels.conf

TV 시청

playlist 를 열고 DVB를 선택한다.

me-tv

채널 설정

metv를 실행하고 ~/.azap/channels.conf 파일을 import 한다.

TV 시청

그냥 실행한다.

VLC

VLC를 실행하고 미디어 - Stream메뉴를 선택한다(보기 - 재생목록 화면에서 고급 열기을 선택해도 된다.

갈무리 장치를 선택하고 아래와 같이 주파수를 선택하면 된다.

여기서 재생을 선택하면 재생목록에 추가되면서 바로 시청이 가능하고, 대기열에 넣기를 선택하면 재생목록에만 추가된다.

TV 녹화하기

@todo vdr

Reference