'IT/LINUX/EMBEDDED'에 해당되는 글 5건

  1. 2007.11.16 df
  2. 2007.11.16 [QT/Embedded] qt를 이용한 Embedded gui프로그램 개발방법
  3. 2007.09.27 getty의 man페이지
  4. 2007.09.27 init의 man페이지
  5. 2007.09.27 inittab 의 man페이지

df

IT/LINUX/EMBEDDED 2007. 11. 16. 23:40
//zmodem 전송을 위해 설치
# apt-get install lrzsz (06.08.09 13:26)

# apt-get install build-essential

# wget ftp://ftp.trolltech.com/qt/source/qt-embedded-2.3.7.tar.gz
# wget ftp://ftp.trolltech.com/qt/source/qt-x11-2.3.2.tar.gz
# wget ftp://ftp.trolltech.com/qtopia/source/qtopia-free-1.7.0.tar.gz
# wget ftp://ftp.trolltech.com/freebies/tmake/tmake-1.11.tar.gz
=========================================================

sudo apt-get install gcc-3.3

그 후에 gcc-4.1을 실행하느냐 gcc-3.3을 실행하느냐를 결정하기 위해서는 아마 /usr/bin/ 디렉터리의 gcc, g++, cpp 등의 파일의 링크를 조절해주시면 될 것입니다.

=========================================================

QT/X11를 설치하다 보면 아래와 같이 qxml.h에서 에러가 발생하는 경우가 있습니다. 저 같은 경우 qt-x11-2.3.2를 설치하다 경험했습니다.

xml/qxml.h:214: warning: 'class QXmlReader' has virtual functions but non-virtual destructor
xml/qxml.h:402: warning: 'class QXmlContentHandler' has virtual functions but non-virtual destructor
xml/qxml.h:419: warning: 'class QXmlErrorHandler' has virtual functions but non-virtual destructor
xml/qxml.h:428: warning: 'class QXmlDTDHandler' has virtual functions but non-virtual destructor
xml/qxml.h:436: warning: 'class QXmlEntityResolver' has virtual functions but non-virtual destructor
xml/qxml.h:443: warning: 'class QXmlLexicalHandler' has virtual functions but non-virtual destructor
xml/qxml.h:456: warning: 'class QXmlDeclHandler' has virtual functions but non-virtual destructor
xml/qxml.cpp:1518: warning: unused parameter 'ret'
/qt/qtx-2/include/qvaluestack.h: In member function 'T QValueStack<T>::pop() [with T = QMap<QString, QString>]':
xml/qxml.cpp:513: instantiated from here
/qt/qtx-2/include/qvaluestack.h:57: error: cannot convert 'QValueListIterator<QMap<QString, QString> >' to 'const char*' for argument '1' to 'int remove(const char*)'
/qt/qtx-2/include/qvaluestack.h: In member function 'T QValueStack<T>::pop() [with T = QString]':
xml/qxml.cpp:2502: instantiated from here
/qt/qtx-2/include/qvaluestack.h:57: error: cannot convert 'QValueListIterator<QString>' to 'const char*' for argument '1' to 'int remove(const char*)'
make[2]: *** [xml/qxml.o] 오류 1
make[2]: Leaving directory `/qt/qtx-2/src'
make[1]: *** [sub-src] 오류 2
make[1]: Leaving directory `/qt/qtx-2'
make: *** [init] 오류 2

이 에러가 발생하는 이유는 qt 버전은 낮고 q++ 버전이 높기 때문인데, q++이 버전업하면서 문법체크가 엄격해 졌기 때문이라고 합니다. 이럴 때에는 qt-x11-2.3.2의 파일 중에 아래의 내용을 수정한 후 다시 설치하면 해결됩니다.

]# vi src/tools/qvaluestack.h

class Q_EXPORT QValueStack : public QValueList
{
public:
QValueStack() {}
~QValueStack() {}
void push( const T& d ) { append(d); }
T pop()
{
T elem( this->last() );
if ( !this->isEmpty() )
this->remove( this->fromLast() ); // this-> 를 추가합니다.
return elem;
}
T& top() { return this->last(); }
const T& top() const { return this->last(); }
};



=========================================================

QTopia 설치 중 에러


In file included from kernel/qt.h:32,
from allmoc.cpp:16:
/qt/qte/include/qstring.h: In member function `uchar& QChar::cell()':
/qt/qte/include/qstring.h:166: error: cannot bind packed field `((QChar*)this)->QChar::cl' to `uchar&'
/qt/qte/include/qstring.h: In member function `uchar& QChar::row()':
/qt/qte/include/qstring.h:167: error: cannot bind packed field `((QChar*)this)->QChar::rw' to `uchar&'
In file included from kernel/qt.h:62,
from allmoc.cpp:16:
/qt/qte/include/qsortedlist.h: In destructor `QSortedList<type>::~QSortedList()':
/qt/qte/include/qsortedlist.h:51: error: there are no arguments to `clear' that depend on a template parameter, so a declaration of `clear' must be available
/qt/qte/include/qsortedlist.h:51: error: (if you use `-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
make[1]: *** [allmoc.o] 오류 1
make[1]: Leaving directory `/qt/qte/src'
make: *** [sub-src] 오류 2

웹 검색을 해 보니, 에러가 발생한 이유가 재밌습니다. gcc 컴파일러 버전이 2.9.x 버전에서는 이상 없는데, 3.4.x 버전부터 표준 문법을 더 잘 지키다 보니(?) 발생하는 문제라고 합니다. 예로, base::fuc() 을 this->fun()으로 바꾸면 된다는데, 이건 뭐 알아도 감당이 되어야 말이죠.

이런 이유로 최신 버전의 QTopia를 설치해 보기로 했습니다만 며칠 동안 정말 고생을 많이 했습니다. 지금은 겨우 성공했습니다만 그동안에 만났던 수많은 오류 중에 저를 무척이나 괴롭혔던, 그래서 기억에 남는 오류와 해결 방법을 정리해 보았습니다.

오류 1

QT는 QT/X11, QT/Embedded, QTopia로 나뉩니다. QT/X11과 QT/Embedded를 설치 완료하고 이제 QTopia만 설치하면 되는데, 이런 에러가 발생하더군요.

/usr/lib/gcc/arm-linux/3.4.3/../../../../arm-linux/sys-include/linux/videodev2.h:436: error: parse error before '*' token /usr/lib/gcc/arm-linux/3.4.3/../../../../arm-linux/sys-include/linux/videodev2.h:438: error: parse error before '*' token /usr/lib/gcc/arm-linux/3.4.3/../../../../arm-linux/sys-include/linux/videodev2.h:439: error: parse error before '}' token /usr/lib/gcc/arm-linux/3.4.3/../../../../arm-linux/sys-include/linux/videodev2.h:810: error: field `win' has incomplete type In file included from mvc.c:37: /usr/lib/gcc/arm-linux/3.4.3/../../../../arm-linux/include/videodev.h:225: error: parse error before '*' token /usr/lib/gcc/arm-linux/3.4.3/../../../../arm-linux/include/videodev.h:226: error: conflicting types for 'clipcount' /usr/lib/gcc/arm-linux/3.4.3/../../../../arm-linux/sys-include/linux/videodev2.h:437: error: previous declaration of 'clipcount' was here /usr/lib/gcc/arm-linux/3.4.3/../../../../arm-linux/include/videodev.h:232: error: parse error before '}' token

정말 난감해서 어떻게 처리할지 몰랐는데, (주)FALINUX의 유영창이사님께서 컴파일러가 만들어진 시점의 커널 소스와 QT 프로그램이 만들어질 때의 커널 소스의 차이로 발생하는 문제라며, 436: error: parse error before '*' token 에서 말을 해 주듯이 '*' token 앞에 있는 키워드에 대해 컴파일러가 알 수 있도록 소스를 수정하라는 도움 말씀을 주셨습니다.

문제의 행에 '*"의 앞은 __user 라는 문장이 있었고, 이 문장을 검색해 보니 compiler.h 에 있네요. 해서 videoodev.h 헤더 파일을 사용하는 모든 파일에 대해 compiler.h 를 추가해 줌으로써 문제를 해결할 수 있었습니다.

   설치 중 에러를 막기 위해 qtopia 소스를 수정합니다.

]# vi ./src/3rdparty/libraries/libavformat/grab.c

<linux/videodev.h> 전에 <linux/compiler.h>를 삽입합니다.

#include <linux/compiler.h>
#include <linux/videodev.h>

]# vi ./src/applications/camera/videocaptureview.cpp

역시 <linux/videodev.h> 전에 <linux/compiler.h>를 삽입합니다.

#include <linux/compiler.h>
#include <linux/videodev.h>
저는 정말이지 QTopia의 소스까지 수정하게 될 줄은 생각지도 못했습니다. 그저 받는 대로 설치하는 것인 줄로만 알았는데 이번에 이런 생각을 고칠 수 있었습니다.

오류 2

오류 1을 잡고 다시 QTopia를 설치하는데 역시 또 에러가 나더군요.

cd games/fifteen && make -f Makefile
make[4]: Entering directory `/qt/qpe-arm/src/games/fifteen'
make[5]: Entering directory `/qt/qpe-arm/src/games/fifteen'
arm-linux-g++? -o fifteen .obj/release-shared/fifteen.o .obj/release-shared/main.o .obj/release-shared/moc_fifteen.o?? -L/usr/local/arm/2.95.3/arm-linux/include/uuid/ -ljpeg -lqtopia2 -lqtopia -lqpe -L/qt/qpe-arm/lib -L/root/qt/qte-2.3.10//lib -lqte
/usr/local/arm/2.95.3/arm-linux/bin/ld: warning: libuuid.so.1, needed by /qt/qpe-arm/lib/libqpe.so, not found (try using -rpath or -rpath-link)
/qt/qpe-arm/lib/libqtopia.so: undefined reference to `uuid_generate'
collect2: ld returned 1 exit status
make[5]: *** [fifteen] 오류 1
make[5]: Leaving directory `/qt/qpe-arm/src/games/fifteen'
make[4]: *** [all] 오류 2
make[4]: Leaving directory `/qt/qpe-arm/src/games/fifteen'
make[3]: *** [sub-games-fifteen] 오류 2
make[3]: Leaving directory `/qt/qpe-arm/src'
make[2]: *** [sub-src-components_pro] 오류 2
make[2]: Leaving directory `/qt/qpe-arm/src'
make[1]: *** [all] 오류 2
make[1]: Leaving directory `/qt/qpe-arm/src'
make: *** [all] 오류 2


관련 함수가 e2fsprogs이고, 제가 설치한 버전이 1.40.2 버전이라 혹시 최신 버전이라서 그런가 하고 다시 가장 많이 눈에 띄는 1.36 버전으로 바꾸어 설치해 보았습니다. 그러나 역시 똑같은 오류만 발생할 뿐이었습니다.

그 렇다면, tmake때문일까 하는 생각에 tmake 1.11로 다시 처음부터 다시 설치해 보았습니다. 역시 같은 오류가 발생. 믿는 것이라고는 웹 검색이라 찾아보니 이 문제로 고생하시는 분들이 많더군요. 모두 질문을 올렸습니다만 답변이 담긴 글은 딱 하나였습니다. 멈추지마라 블로그:: Qtopia 설치 글로, 이분이 해결한 방법은,
]# ln -s libuuid.so libuuid.so.1
이 었습니다. 그러나 저는 libuuid.so.1 이 이미 정상적으로 생성되어 있었습니다. 그래서 또다시 e2fsprogs를 다시 설치해 보았으나 역시 헛고생을 했고, 거의 포기할 생각마저 하게 되었는데, 예전에 Windows-XP를 원격 데스크탑으로 연결하고 파이어버드라는 데이터베이스 서버를 설치했던 기억이 생각이 났습니다.

원격 데스크탑에서 설치하면 제대로 설치가 안 되었던 것이죠. 물론 같은 계정으로 설치했음에도 설치는 되도 실행이 제대로 되지 않아 고생했었거든요.

솔직히 말씀드리면 오류 2 때문에 설치를 반복하는 순간에도 이 생각이 계속 머릿 속을 멤돌았습니다. 그러나 리눅스에서 설마하는 생각에 그냥 넘겼던 것이죠.

시스템 터미널다시 한 번 힘을 내서 텔넷이 아닌 시스템에서 직접 터미널을 이용하여 설치했습니다.
그리고 아무 문제없이 설치할 수 있었습니다. ㅡㅡ;
혹 제가 리눅스를 Virtual PC 2007을 사용하기 때문인지 모르겠습니다. 또한 같은 종류의 가상 PC 프로그램인 VmWare에서도 똑 같은 문제가 있는지 모르겠습니다만 텔넷에서 설치하다가 오류가 발생하면 /usr/arm-linux/lib의 내용을 보려고 ls -al하면 아래와 같이 에러가 나더군요.

[root@jwCentOS lib]# ls -al ls: error while loading shared libraries: librt.so.1: ELF file OS ABI invalid

혹 QTopia 설치 중에 uuid_generate 오류를 만나시거나 기타 이상하게 설치가 안 되시면 텔넷이 아닌 시스템에서 직적 터미널을 이용하여 설치해 보십시오.

Posted by 블루아레나
0. 개요
현재 Embedded Linux기반에서 GUI를 구현하기 위해서 많은 고민들을 하는 개발자들이
많을 것입니다. 또한 자기에게 적합한 GUI Framework를 선정하였더라도 어떻게 그러한
Framework을 적용해서 개발해야하는지에 대한 개발절차를 알지 못 해 처음 시작시 막막해하는 그러한 분

들을 위해 필자가 그동안 개발해온 방법을 통해 알려드리고자 합니다.
(이 말은 Qt/E나 기존 다른분의 강좌내용과 다소 다를 수 있다는것을 의미합니다.)
여러가지 많은 GUI Platform중 필자가 다루어본 Qt에 대한 내용만 다루어보고
그중 Qt의 가장최신 버전인 Qtopia core 4버전을 기준으로 작성됩니다.
Qtopia core 4는
기존 Qt/Embedded 2.x --> Qt/Embedded 3.x를 통해 넘어온 Qt에서 이름만 변경된것입니다.
기존 Qtopia가 Phone, PDA를 뜻하는것이라 용어에 혼동을 느끼지 않으셨으면 합니다.


1. 개발환경 설정하기
Embedded Linux개발환경은 이미 잘 알려진데로 Host PC에서 크로스컴파일러로 컴파일하고
그 결과물을 Target 보드에 NFS등을 통해 실행하는 형태입니다.
Qt역시 마찬가지이므로 Host PC에서 크로스 컴파일하기 위한 환경을 구성해 놓아야 합니다.
이에관련된 여러가지 문서가 많겠지만 필자의 경우 다음과 같은 절차를 통해 준비합니다.

1.1 Host PC에 Qt크로스 컴파일 하기
대부분 크로스 컴파일과정은 굉장히 복잡했었는데 Qtopia core 4에서는 아주 간단하게 끝납니다.
기존의 모든 Qt크로스 컴파일 문서는 그냥 잊으시고
Trolltech 사이트에서 그냥 Qtopia core 4에 관련된 소스를 받으셔서 크로스 컴파일 하시면 됩니다.
Qt를 X11용으로 컴파일 할 필요도 없고 단지 이것만 하시면 됩니다.

1.2 Host PC에 qt-4용 designer를 설치하기
이것은 host PC에서 qt용 GUI를 만들기 위해서 designer를 활용하기 위해서 인데
필자의 ubuntu system에서는 아래와 같이 설치만 하면 됩니다.
$ sudo apt-get install libqt4-core
$ sudo apt-get install libqt4-debug
$ sudo apt-get install libqt4-dev
$ sudo apt-get install libqt4-gui
$ sudo apt-get install qt4-designer
$ sudo apt-get install qt4-dev-tools

1.3 이제 모든 준비가 완료되었습니다.
기존 Qt포팅문서가 복잡한 이유는 qvfb등을 활용하기 위해서 였는데, 필자의 경험상 이것은 전혀
불필요한 작업이었습니다.
qvfb를 통해 host pc에서 미리 그 결과를 검증해볼 수 있다는 장점은 실제 개발에 있어서
실제 target 기기에만 존재하는 device장치나 속도문제로 인해 오히려 아무의미가 없었기 때문에
이걸 깨달은 시점이후부터는 반드시 실제기기에서만 작업을 합니다.
물론 qvfb가 유용할때가 가끔 있을 수도 있는데, 이런경우에는
ubuntu등의 배포판에는 이미 들어있어서 그걸 그냥 설치해서 이용해도 무관합니다.

2. 개발과정
이제 실제 Qt용 프로그램 제작과정을 살펴보도록 하겠습니다.
MS Windows플랫폼에서 Visual Studio를 써보거나 보신분들은 이와 비슷한 리눅스 GUI개발환경인
KDevelop을 떠올리며 이를 이용해서 개발에 검토하시는 분들이 있습니다.
하지만 필자의 경우에는 KDevelop이나 여타 다른 도구의 도움없이 Qt의 디자이너 + 커맨드라인 + VIM만
이용해서 개발을 합니다.
필자 역시 초기에 Kdevelop등을 이용해서 편하게 개발해보려고 노력을 많이 하였으나
Embedded Linux머신이 x86용이 아닐경우 KDevelop등의 편리한 디버거는 아무런 의미가 없었고
모든 업무가 윈도우즈 중심으로 이루어지는 현실에 있어서 X-windows와 windows를 번갈아 가면서
사용하는것 역시(KVM을 써도 마찬가지) 문제가 많았습니다.
하지만 윈도우에서 리눅스 터미날로 여러가지를 연결해서 개발통합환경의 여러개의 소스코드 띄우기와
Qt designer를 이용하면 Kdevelop부럽지 않게 모든것을 해결 할 수가 있었습니다.
(물론 Qt Designer를 이용하려면 리눅스화면으로 돌아가서 처리해야 하긴 하지만요...)

이제부터 실제 제가 작성하는 과정을 통해서 한번 살펴보도록 하겠습니다.
아래의 그림은 필자가 만들어 볼 화면입니다.


2.1 designer로 ui화면 작성
아래와 같이 실행해서 qt designer를 실행해 보도록 합니다.
$ designer-qt4

위와같이 실행을 하면 아래와 같은 화면이 나옵니다.
만약 안나온다면 앞서 1.2에서 이야기 한데로 시스템에 설치가 제대로 안된것입니다.


위의 화면에서 Dialog with Buttons Bottom이라고 선택된 상태에서 Create버튼을 누릅니다.
Create버튼을 누르면 아래와 같은 화면이 생성이 됩니다.


이제 생성된 화면에 Label, LineEdit를 차례대로 붙여넣겠습니다.
먼저 아래의 그림이 보이는 도구박스에서 Label아이콘을 선택하여 드래그해서 폼에다가 올립니다.



위와 같이 모두 배치가 되었다면 TextLabel이라는 글자 위에서 마우스 오른쪽 버튼을 눌러서
Change Text를 선택합니다. 아래와 같은 화면에서 ID라고 바꾸어 씁니다.

마찬가지로 처음 보여진 그대로 Login화면을 완성해 봅니다.



위와같이 완성이 되었나요?
이제 위에서 바꾼것과 비슷하게 콘트롤의 이름을 바꾸어 봅니다.
바꾸고자 하는 콘트롤 위해서 Change Object Name을 이용해서 바꾸어 봅니다.


모두 바꾸었다면 메뉴에서 LoginFrm.ui이름으로 저장을 하고 빠져나갑니다.
모두 완성되었습니다.

2.2 소스코드 작성하기
2.2.1 main.cpp 작성
아래와 같이 소스코드를 입력합니다.
#include <QApplication>
#include "LoginFrm.h"

int main(int argc, char** argv)
{
   QApplication app(argc, argv);

   LoginFrm frm;
   frm.exec();

   return app.exec();
}

2.2.2 LoginFrm.h 작성
#ifndef [u]LOGINFRM_H[/u]
#define [u]LOGINFRM_H[/u]

#include "ui_LoginFrm.h"

class LoginFrm : public QDialog
{
   Q_OBJECT
private:
   Ui::LoginFrm ui;

public:
   LoginFrm(QWidget* parent = NULL);

protected slots:
   void ok();
   void cancel();
};

#endif

2.2.3 LoginFrm.cpp 작성
#include "LoginFrm.h"
#include <QMessageBox>

LoginFrm::LoginFrm(QWidget* parent/*=NULL*/) : QDialog(parent)
{
   ui.setupUi(this);
   connect( ui.ok, SIGNAL(clicked()), this, SLOT(ok()) );
   connect( ui.cancel, SIGNAL(clicked()), this, SLOT(cancel()) );
}

void LoginFrm::ok()
{
   QMessageBox::information(this, "Login", "ok");
}

void LoginFrm::cancel()
{
   QMessageBox::information(this, "Login", "cancel");
}

2.3 컴파일하기
2.2와 같이 모든 소스코드를 저장하고 나서 이제 프로젝트 파일을 생성해봅니다.
리눅스에서는 Makefile을 이용해서 컴파일 하도록 되어 있는데, 이 Makefile이라는것이 작성하는
방법이 복잡해서 Qt에서는 Qt용 프로젝트를 위한 자동생성도구를 갖추고 있습니다.
이 자동생성도구 qmake를 이용하면 다음과같이 프로젝트 파일과 Makefile을 생성할 수 있습니다.

(아래부터 실제 qmake를 이용해서 결과를 살펴볼때 qmake-qt4처럼 -qt4가 붙은것을 보실 수 있습니다.
이것은 ubuntu이기때문에 그런것인데, ubuntu에서는 qt3와 qt4의 qmake파일명이 같기때문에
구분하기 위해서 이렇게 binary이름을 바꾸어 넣고 qmake라는 명령은 단순히 qmake-qt3나 qmake-qt4라는
파일의 symblolic link형태로 존재합니다.)

2.3.1 프로젝트 생성
다음과 같이 qmake-qt4 -project를 입력하게 되면 자동으로 해당 디렉토리명.pro라는 파일이 생성됩니다

.
만약 프로젝트를 하다가 중간에 소스가 추가/삭제가 되면 다시 -project옵션을 통해 자동으로
갱신할 수 있고, 직접 pro파일을 수정해서 쓰셔도 됩니다.
$ qmake-qt4 -project
$ cat ex.pro
######################################################################
# Automatically generated by qmake (2.01a) ? 8? 24 17:43:07 2007
######################################################################

TEMPLATE = app
TARGET =
DEPENDPATH += .
INCLUDEPATH += .

# Input
HEADERS += LoginFrm.h
FORMS += LoginFrm.ui
SOURCES += LoginFrm.cc main.cpp

2.3.2 프로젝트 파일을 통해 Makefile을 생성
2.3.1에서 생성된 pro파일을 근거로 Makefile을 생성하는것은 qmake-qt4라고 그냥 입력하시면 됩니다.
$ qmake-qt4
$ ls -al Makefile
-rw-r--r-- 1 korone korone 6552 2007-08-24 17:43 Makefile

2.4 이제 컴파일을 해봅니다.
$ make
g++ -c -pipe -O2 -Wall -W -D_REENTRANT  -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -

I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtCore -

I/usr/include/qt4/QtGui -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -I. -o LoginFrm.o

LoginFrm.cc
g++ -c -pipe -O2 -Wall -W -D_REENTRANT  -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -

I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtCore -

I/usr/include/qt4/QtGui -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -I. -o main.o

main.cpp
/usr/bin/moc-qt4 -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -I/usr/share/qt4/mkspecs/linux-g++ -I.

-I/usr/include/qt4/QtCore -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -

I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -I. LoginFrm.h -o moc_LoginFrm.cpp
g++ -c -pipe -O2 -Wall -W -D_REENTRANT  -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -

I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtCore -

I/usr/include/qt4/QtGui -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -I. -I. -o moc_LoginFrm.o

moc_LoginFrm.cpp
g++  -o ex LoginFrm.o main.o moc_LoginFrm.o    -L/usr/lib -lQtGui -lQtCore -lpthread

위 과정이 끝나면 실제파일명이 생성되는데, 필자의 경우 ex라는 디렉토리내에서 생성해서
ex라는 실행결과를 얻었습니다.

$ ./ex

라고 입력하여 아래와 같이 처음의 화면과 같이 실행이 되는지 확인해보세요.


3. Embedded Linux에서 실행하기
2번까지의 과정은 모두 X86에서 직접 컴파일 실행하는것이었지만
Embedded Linux에서 실행하는것은 조금 다른 크로스 컴파일을 해야 합니다.
위의 결과에서 생성된 ex라는 실행파일을 얻기위해서는 컴파일할때 크로스컴파일러와 크로스컴파일된
Qt가 필요합니다.
크로스 컴파일된 Qt는 다음과 같은 과정을 통해 얻고 컴파일 할 수 있습니다.
(이 문서의 핵심은 Qt포팅이 아니므로 자세한 것은 생략합니다. 하지만 그렇다고 해서 아래의
내용이 틀린내용이 아닙니다. 필자의 경우 아래의 형태로만 해서 모든 준비가 끝났으니까요.)

3.1 Qt컴파일 설치
3.1.1 http://trolltech.com/developer/downloads/qtopia/coregpl 사이트에서 qtopia를 다운로드
4.3.1.tar.gz

3.1.2 다운로드 받은 파일을 /opt/qt-4.3.1에다가 압축해제
root@korone-desktop:# cd /opt/qt-4.3.1

3.1.3 컴파일을 위한 환경변수 설정
root@korone-desktop:/opt/qt-4.3.1# export QTDIR=`pwd`
root@korone-desktop:/opt/qt-4.3.1# export LD_LIBRARY_PATH=$QTDIR/lib

3.1.4 컴파일 환경설정
아래의 경우에는 -embedded x86 -little-endian에서 볼 수 있듯이 x86용으로 컴파일 하는 것입니다.
만약 arm, mips등으로 컴파일 하기 위해서는 이 부분을 수정해 주서야 합니다.
root@korone-desktop:/opt/qt-4.2.2# ./configure -prefix /opt/qt-4.2.2 -embedded x86 -little-endian -release -no-largefile -no-accessibility -no-qt3support -qt-zlib -qt-gif -qt-libpng -no-libmng -qt-libjpeg -no-nis -no-cups -qt-freetype -depths 16,24,32

3.1.5 컴파일
root@korone-desktop:/opt/qt-4.3.1# make sub-src

3.1.6 컴파일이 끝나면
target보드에 /opt/qt-4.3.1디렉토리를 생성하고 lib디렉토리를 통째로 복사해 놓음
(이때 strip을 하시는것을 잊으시면 안됩니다. 안하시면 아마도 NAND또는 NOR를 쓸경우 메모리가
부족해 질 수도 있습니다.
복사외에도 실행할때마다 그냥 Host PC에 있는것을 NFS링크로 하면 복사를 하지 않아도 편하게
사용할 수 있습니다.)

3.2 위오같이 Qt에대한 크로스 컴파일 설정이 모두 완료되었다면
2.2에서 살펴본 소스코드를 크로스 컴파일 용으로 컴파일하는것은 굉장히 쉽습니다.

3.2.1 먼저 기존 컴파일된 내용을 초기화 시킴
$ make clean

3.2.2 크로스컴파일용 makefiile생성
아래를 주의할것은 아래의 디렉토리는 조금전 Qt를 크로스 컴파일한 결과가 있는 디렉토리입니다.
$ /opt/qt-4.2.2/bin/qmake
$ make

3.3.3 이제 컴파일을 해보시면 해당 target용으로 생성된 binary를 확인할 수 있습니다.
이것을 실제 target으로 옮기거나 nfs를 통해 실행해 보시면 됩니다.


간단히 생각했던 문서가 막상정리하려니 꽤 복잡합니다.
혹시 부족한 부분이나 틀린부분에 대해서 제게 알려주시면 감사하겠습니다.
감사합니다.

korone.net
조병완( korone a t g mail. co m)
Posted by 블루아레나
getty(1M)               System Administration Commands               getty(1M)



NAME

       getty - set terminal type, modes, speed, and line discipline

SYNOPSIS

       /usr/lib/saf/ttymon [-h] [-t timeout] line [ speed [ type [linedisc]]]

/usr/lib/saf/ttymon -c file

DESCRIPTION

       getty sets terminal type, modes, speed, and line discipline. getty is a
symbolic link to /usr/lib/saf/ttymon. It is included for compatibility
with previous releases for the few applications that still call getty
directly.

getty can only be executed by the super-user, (a process with the user
ID root). Initially getty prints the login prompt, waits for the user’s
login name, and then invokes the login command. getty attempts to adapt
the system to the terminal speed by using the options and arguments
specified on the command line.

Without optional arguments, getty specifies the following: The speed
of the interface is set to 300 baud, either parity is allowed, NEWLINE
characters are converted to carriage return-line feed, and tab expan‐
sion is performed on the standard output. getty types the login prompt
before reading the user’s name a character at a time. If a null charac‐
ter (or framing error) is received, it is assumed to be the result of
the user pressing the BREAK key. This will cause getty to attempt the
next speed in the series. The series that getty tries is determined by
what it finds in /etc/ttydefs .

OPTIONS

       The following options are supported:

-h If the -h flag is not set, a hangup will be forced by setting the
speed to zero before setting the speed to the default or a speci‐
fied speed.

-t timeout
Specifies that getty should exit if the open on the line succeeds
and no one types anything in timeout seconds.

-c file
The -c option is no longer supported. Instead use
/usr/sbin/sttydefs -l to list the contents of the /etc/ttydefs
file and perform a validity check on the file.

OPERANDS

       The following operands are supported:

line The name of a TTY line in /dev to which getty is to attach
itself. getty uses this string as the name of a file in the /dev
directory to open for reading and writing.

speed The speed argument is a label to a speed and TTY definition in
the file /etc/ttydefs. This definition tells getty at what speed
to run initially, what the initial TTY settings are, and what
speed to try next, (should the user press the BREAK key to indi‐
cate that the speed is inappropriate). The default speed is 300
baud.

type and linedisc
These options are obsolete and will be ignored.

FILES

       /etc/ttydefs


ATTRIBUTES

       See attributes(5) for descriptions of the following attributes:


+-----------------------------+-----------------------------+
| ATTRIBUTE TYPE | ATTRIBUTE VALUE |
+-----------------------------+-----------------------------+
|Availability |SUNWcsr |
+-----------------------------+-----------------------------+

SEE ALSO

       ct(1C), login(1), sttydefs(1M),  ttymon(1M),  ioctl(2),  attributes(5),
tty(7D)
Posted by 블루아레나
INIT(8)               Linux System Administrator's Manual              INIT(8)



NAME

       init, telinit - 초기프로세스 제어

SYNOPSIS

       /sbin/init [ -t sec ] [ 0123456SsQq ]
/sbin/telinit [ -t sec ] [ 0123456sSQqabc ]

DESCRIPTION

   Init
Init 프로세스는 모든 프로세스의 아버지다. 이것은 /etc/inittab
파일(inittab(5) 참조)을 찾아, 지정한 스크립트를 실행한다. 이 파일에는
사용자가 접속할 수 있도록 getty 처리를 하는데, 이때 init가 사용된다.
또한 이 파일은 특정 시스템에 필요한, 자동으로 실행되어야 하는
프로세스들을 제어한다.

runlevel이란 존재하는 프로세스의 선택된 그룹만을 허락하는 시스템의
소프트웨어 환경이다. 각각의 runlevelinit에 의해 생성되는
프로세스들은 /etc/inittab 파일에정의된다. Initrunlevel이 0부터 6,
S 또는 s인 여덟 종류 중 하나에 존재 할 수 있다. runlevel 값은 시스템
관리자가 /sbin/telinit를 실행해 바뀐다. telinit는 runlevel을
바꾸어라는 신호를 init에게 알린다.

커널 부팅이 끝나면, 마지막으로 init가 실행되는데, 이때 /etc/inittab
파일을 찾아 그 안에 정의된 initdefault (inittab(5) 참조) 부분을 읽는다.
그리고 그곳에 정의된 runlevel을 현재 level로 하여 나머지 작업을
계속한다. 이때, /etc/inittab 파일이 없거나, initdefault 정의가 없으면,
콘솔에직접 runlevel을 입력해야 한다.

runlevelSs이면, 단일 사용자 모드가 진행되면, 이때는 /etc/initttab
파일이 필요없다. 단일 사용자 모드에섦/dev/console에 의해 /bin/sh
호출된다.

단일 사용자 모드가 되면, init는 /etc/ioctl.save에 지정한 콘솔의
ioctl(2)을 읽는다. 이때, 이 파일이 없으면, init는 라인을 9600 baud,
CLOCAL로 초기한다. 단일 사용자 모드를 떠나면, init는 현재 콘솔의
ioctl 설정을 /etc/ioctl.save 파일에 저장하고, 다음 단일 사용자 모드에 다시 사용한다.

다중 사용자 모드로 들어가게 되면, init는 먼저 사용자가 로그인 할 수
있는 마운트된 파일 시스템의 사용을 위해 boot, bootwait 부분을 처리하고,
다음, 나머지 부분들을 처리한다. (inittab에정의되고 있음)

한 새로운 프로세스를 시작할 때는 먼저 /etc/initscript 파일이 있는지
확인을 하고, 있다면, 그 스크립트에 따라 프로세스를 시작한다.

각 하위 프로세스들이 끝날 때, init는 /var/run/utmp, /var/log/wtmp
파일있다면, 그 파일에 그 프로세스들의 마침 정보들(언제 끝났고, 왜
끝났고... 이런 정보)을 기록한다.

지정한 그 프로세스를 모두 실행 한 뒤, init는 그 프로세스를 마칠
의존적인 프로세스 중 하나나,powerfail 시그날이나, 시스템의 runleve
바꾸는 /sbin/telinit에 보내는 시그날을 기다린다. 이 셋 중 하나가
발생했을 때, init/etc/inittab 파일을 다시 읽는다. 이 파일에는
언제든지 새로운 항목이 추가 될 수 있다. 하지만 그 효과는 위에언급한
그 세가지 경우가 되어 init가 그 파일을 읽을 때 나타낫 이런 상황이
아닌데도 /etc/inittab 파일을 읽어야 할 경우에는 Qq 명령을 사용한다.

만약 단일 사용자 모드가 아닌데, powerfail 시그날이 발생하면, init
/etc/inittab 파일에특별하게 지정된
powerfail 부분을 실행한다.

runlevel이 바뀌었을 때, 그 새로운 runlevel에 대해특별히 대처하지 않게
지정된 모든 프로세스에게 init는 경고 시스날인 SIGTERM을 보낸다. 그리고
나 5초동안 기다리고는 종료 시그날인 SIGKILL 을 그 프로세스들에게
보낸다. 이때, init는 그 프로세스들을 위해 원래 만들어진. 같은
프로세스 그룹 안에 남아 있다고 가정한다는 것을 주의하라. 만약 어떤
프로세스가 자신의 프로세스 그룹을 바꾸었다면, 이 프로세스는 위에 언급한 시그날들을 받지 못한다. 이런 프로세스들은 사용자가 직접
종료해야한다.

telinit
/sbin/telinit/sbin/init에 링크되어 있는 명령이다. 이것은 한 문자의
명령행 인자와 적당한 작업을 수행할 signals init를 가진다. 여기사용할
수 있는 한 문자 명령행 인자는 다음과 같다. /sbin/telinit:

0,1,2,3,4,5,6
/sbin/init에게 runlevel이 바뀌었음을 알린다.

a,b,c /etc/inittab 파일에지정한 a,b,c runlevel 부분을 처리하라고
init에게 알린다.

Q or q /sbin/init/etc/inittab 파일을 다시 읽도록 지시한다.

S or s /sbin/init에게 단일 사용자 모드로 전환하라고 알린다.

또한 init가 TERM 시그날을 보내고 나몇 초를 기다린 후, KILL 시그날을
프로세스들에게 보낼지를 지정할 수 있다. 초기값은 5초다. 이 것은 -t sec
옵션으로 지정한다.

/sbin/telinit 명령은 단지 시스템 관지자에 의해섯호출 될 수 있다.

RUNLEVELS

       init와  관계되는  runlevel은 0, 1, 6이다. 0은 시스템 종료에, 6은 시스템
재시동(reboot)에, 1은 단일 사용자 모드에 사용된다. runlevel S는 바로
처리 되지 않고, runlevel 1로 바뀌었을 때 처리 되는 부분에처리된다.
자세한 이야기는 shutdown(1), inittab(5) 매뉴얼 페이지를 참조한다.

runlevel 7-9도 사용할 수 있지만, 이 문셀【는 다루지 않는다. 이것은
"전통적인" Unix 환경에섦사용되지 않는 값들이기 때문이다. 일반적으로
runlevel Ss 값이 runlevel 7-9와 같은 역활을 한다. 이것은 단지 하나의
별칭으로 사용된다. 이 풀그림 제작자가 sysvinit를 만들때 사용한
시스템에이 값들을 사용하기 때문에 남겨두었을 뿐이다.

FILES

       /etc/inittab
/etc/initscript
/dev/console
/etc/ioctl.save
/var/run/utmp
/var/log/wtmp
/dev/initctl

ENVIRONMENT

       init에섦다음과 같은 환경 변수를 사용한다.

PATH 초기값: /bin:/usr/bin:

INIT_VERSION
init의 버전 정보. 이것은 init 스크립트 작성에요용하게 쓰인다.

RUNLEVEL
시스템의 현재 runlevel.

PREVLEVEL
이전 runlevel.(runlevel 전환 때에 요용하게 쓰인다.)

BOOTFLAGS

       부트  관리자(예,  LILO)에 다음 인자들을 사용할 수도 있고, 생략할 수도
있다.

S, single
단일 사용자 모드로 부팅한다. 이 모드에섦 /etc/inittab 파일을
검사하고, 단일 사용자 모드의 쉘이 시작되기 전에, rc 스크립트가
일반적으로 실행된다.


1-5 지정한 runlevel로 부팅한다.


-b, emergency
다른 어떠한 시작 스크립트 없이 바로 단일 사용자 모드로 부팅한다.


CONFORMING TO

       Init는 System V init와 호환이 된다.  이것은  /etc/init.d,  /etc/rc{run-
level}.d 경로안에 있는 스크립트들을 실행한다. 자신의 시스템에
적용하려면, 먼저 /etc/init.d 경로 안에 있는 스크립트들이 어떻게 작동할
것인지에 대해이야기하고 있는 README 파일을 읽어 보라.

WARNINGS

       init는  어떤  프로세스가  실행될 당시에 소속되어 있는 프로세스 그룹안에
계속 있다고 가정한다. 그렇기 때문에, 만약 그 프로세스가 그 그룹에 더
이상 소속되지 않는다면, runlevel이 바뀌었어 그 프로세스를 마쳐야 할때,
제대로 마칠수 없게 된다.

DIAGNOSTICS

       만약 2분 동안 10번 이상 init가 계속 해호출 된다면, init는 이런 상태를
오류로 가정한다. 그리고는 시스템 콘솔에 오류 메시지를 보여준다. 그리고,
5분간 프로세스 생성을 중지하고, 발생되는 시그날을 받는다. 이것은 시스템
리소스의 낭비를 막기 위한 조치이다.

AUTHOR

       Miquel  van  Smoorenburg  (miquels [AT] cistron.nl),  initial manual page by
Michael Haardt (u31b3hs [AT] pool.de).

SEE ALSO

       getty(1), login(1), sh(1), who(1),  shutdown(1),  kill(2),  inittab(5),
initscript(5), utmp(5)
Posted by 블루아레나

INITTAB(5)     Linux System Administrator's Manual     INITTAB(5)

          NAME
                 inittab - 시스템 운영 시작에서 사용되는 init 프로세스의 처
                 리 방법을지정하고 있는 파일.

          DESCRIPTION
                inittab 파일은 시스템이 가동될 때 일반적인 운영 방법의  처
                 리에대한 것을 설명하고 있는 파일이다. (예를 들면, /etc/rc,
                 gettys.. 등의처리). init 프로세스는 다양한 runlevels을  구
                 별해서사용한다. 이 runlevels은 시스템의 부팅과 종료등에 사
                 용된다.  runlevels 값은06이며,ondemand 위해A,B,
                 쓰 인다. inittab 파일의 내용은 다음과 같은 형식을 취한다.

                        id:runlevels:action:process

                 `#'로 시작하는 문장은 주석으로 처리된다.

                 id     inittab 안에서의 각 항목들에 대한 식별자. 최대 4 자
                        리.  (libc의 버전이 5.2.18보다 낮은 버전이나, a.out
                        라이브러리로컴파일 했다면, 사용할 수 있는 최대 문자
                        갯수는 2개다.

                        주 의: getty나 다른 로그인 프로세스의 사용에서는 id
                        필드에는그 프로세스에서 사용하는 tty의 끝자리 숫 자
                        가 와야한다.  예를 들면,tty11. 그렇지 않으면 바
                        르게 작동되지않을 수도 있다.

                 runlevels
                        진행할 runlevel 지정.

                 action action 지정

                 process
                        실행할 프로세스 지정. 이 필드에 `+' 문자가 제일  앞
                        에   오면, init는 그 처리과정에서 utmp, wtmp 처리를
                        하지 않게 한다.  이것은 gettys에서 스스로 utmp/wtmp
                        를  처리할 경우 필요하다.  사용하는 gettys를 확인하
                        기 바란다.

                 action에서 사용할 수 있는 값은 다음과 같다.

                 respawn
                        그 프로세스가 종료되면 항상 다시 시작하게 한다.(예,
                        getty)

                wait   지정한 runlevel이 되면 그 프로세스가 실행되고, init
                        는 그 프로세스가 종료되기를 기다린다.

                once   지정한 runlevel이 되면 한번만 그 프로세스를 실행 한
                        다.

                boot    시 스 템  부팅 때에 그 프로세스를 실행한다. 이때는
                        runlevel 값이무시된다.

                 bootwait
                        시스템 부팅 때에 그 프로세스가 실행되는 데,   이 때
                        init 는 그   프 로 세 스가 종료되기를 기다린다.(예,
                        /etc/rc).  이때는 runlevel 값이 무시된다.

                off    아무것도 아니다. 단지 id만 존재하는 것뿐.

                 ondemand
                        지정한 ondemand runlevel이 호출 될 때마다 그 프로세
                        스를 실행한다.  하지만 runlevel 값은 바뀌지 않는다.
                        ondemand runlevel 값은 'a', 'b', 'c' 이다.)

                 initdefault
                        시스템 부팅 뒤에 실행될 runlevel을 지정한다.  만 약
                        이 부분이 없으면, 어떤 runlevel로 실행할 것이지, 콘
                        솔에서 물어본다. process 필드는 무시된다.

                 sysinit
                        시스템 부팅을 할 때에 그 프로세스가 실행된다.  이것
                        은boot, bootwait로 지정된 프로세스보다먼저 실행된
                        다. process 필드는 무시된다.

                 powerwait
                       init가 SIGPWR 시그날을 받았을 때 그 프로세스가 실행
                        된다.  SIGPWR은 전원 공급에 문제가 생겼을 때 발생하
                        는 시그날이다. Init는 그 프로세스 작업이 끝날 때까
                        지 아무 작업도 하지 않는다.

                 powerfail
                       powerwait 와 같지만, init는 그 프로세스 작업이 끝나
                        기를기다리지 않는다.

                 powerokwait
                       init가 SIGPWR 시그날을 받았을 때 그 프로세스가 실행
                        된다.  OK라는 단어를 포함하고 있는 /etc/powerstatus
                        파일이 SIGPWR 시그날을 제공한다.

                 ctrlaltdel
                       init가 SIGINT 시그날을 받았을 때 그 프로세스가 실행
                        된 다.   SIGINT 는   시 스 템   콘 솔 에서 누군가가
                       CTRL-ALT-DEL 글쇠를눌렀을 때 발생하는 시스날 이 다.
                        이것은 전형적으로컴퓨터를 리부팅하거나, 단일 사용자
                        모드를 사용하기 위해서사용된다.

                 kbrequest
                        콘솔 글쇠판에서 특별하게 지정된 글쇠가 눌려졌을 때,
                        발 생하는 한 시그날을 init가 받았을 때, 그 프로세스
                        를 실행한다.
                        이 부분에 대한 이야기는 아직 여기서 자세히 다루지는
                        못 한다.  좀더 자세한 정보를 원하면 kbd-x.xx 팻키지
                        의 문서들을참고한다. (이 문서는 kbd-0.91 팻키 지 를
                        바 탕 으로 쓰여졌다.)  보통, 글쇠지정은 "Spawn_Con-
                        sole" action으로 한다.  예를 들어, Alt-윗화살표글쇠
                        를  지정하고 싶으면, 글쇠지정파일(keymap)에 다음 내
                        용을 추가한다.

                        alt keycode 103 = Spawn_Console

                 하나의 프로세스가 각각 다른 runlevel에서도 같이 실행 되 게
                 하 려 면, runlevel 필드에는 다른 runlevel 들을 함께 지정할
                 수 있다.  예,123.ondemand 값으로 지정한는A,B,C도 마찬
                 가 지다. action 값이sysinit,boot,bootwait로 지정되어 있
                 으면 그 runlevel 값은 무시된다.

                 runleve 값이 바뀌었을 때, 그 새로 바뀐 runlevel에 대한  처
                 리   과정을따로 지정하지않았다면, SIGTERM, SIGKILL과 함께,
                 그 프로세스는 종료된다.

          EXAMPLES
                 이것은 옛날 linux에서 사용하던 inittab 파일이다.

                        # inittab for linux
                        id:1:initdefault:
                        rc::bootwait:/etc/rc
                        1:1:respawn:/etc/getty 9600 tty1
                        2:1:respawn:/etc/getty 9600 tty2
                        3:1:respawn:/etc/getty 9600 tty3
                        4:1:respawn:/etc/getty 9600 tty4

                 이 파일은 시스템이 부팅되는 동안/etc/rc 파일을 실행하 고,
                 tty1-tty4에서 getty를 실행한다.

                 다 음 부분은 다른 runlevel에서의 각 설정들을 지정한다(주석
                 부분을 참고).

                        # 2 단계 정의
                        id:2:initdefault:

                        # 최우선으로 시스템 초기화
                        si::sysinit:/etc/rc.d/bcheckrc

                        # runlevel 0,6은 각각 halt와 reboot, 1은 단일 사용자 모드
                        l0:0:wait:/etc/rc.d/rc.halt
                        l1:1:wait:/etc/rc.d/rc.single
                        l2:2345:wait:/etc/rc.d/rc.multi
                        l6:6:wait:/etc/rc.d/rc.reboot

                        # "3 finger salute"에서 어떻게....
                        ca::ctrlaltdel:/sbin/shutdown -t5 -rf now

                        # runlevel 2&3: 콘솔 getty, level 3: 모뎀 getty
                        1:23:respawn:/sbin/getty tty1 VC linux
                        2:23:respawn:/sbin/getty tty2 VC linux
                        3:23:respawn:/sbin/getty tty3 VC linux
                        4:23:respawn:/sbin/getty tty4 VC linux
                        S2:3:respawn:/sbin/uugetty ttyS2 M19200

          FILES
                 /etc/inittab

          AUTHOR
                 Init   was   written    by    Miquel    van    Smoorenburg
                 (miquels@cistron.nl),  the  manual  page  was  written  by
                 Sebastian    Lederer     (lederer@francium.informatik.uni-
                 bonn.de)     and     modified     by     Michael    Haardt
                 (u31b3hs@pool.informatik.rwth-aachen.de).

          SEE ALSO
                 init(8), telinit(8)

Posted by 블루아레나