2010年9月15日 星期三

建立自己的 Linux開機圖片

轉自這位大大的文章
http://sites.google.com/site/myembededlife/Home/s3c2440/add-linux-logo

在 Linux中,預設的開機圖片,在左上角有隻小企鵝,大小為 80x80 pixel,格式為 ppm,
現在我想要改成整個畫面都顯示自己的圖片:

1. 取得一張 png的圖片
# sudo apt-get install netpbm
# pngtopnm ur_picture.png | ppmquant -fs 223 | pnmtoplainpnm > logo_linux_clut224.ppm

2. 此時就會在本地資料夾產生一個名為 logo_linux_clut224.ppm的圖片,把它取代掉原本的小企鵝,
linux_source_tree/driver/video/logo/logo_linux_clut224.ppm
3. 重新編繹 kernel,產生 zImage
4. 完成

不要顯示開機訊息:
e -c "noinitrd console=/dev/null console=ttymxc0,115200 root=/dev/mmcblk0p1 rw wvga=mxcfb:800x480-16M@50"

2010年7月13日 星期二

build a rootfs of jaunty for arm

之前用 Emdebian建立一個基本的 rootfs for arm,不過 Nabe大大說用 Emdebian裝套件似乎都不是很順利,就是用 apt-get install packages有時都會發生不可預期的事情,所以就用 Ubuntu來建立 for arm的 rootfs

步驟跟之前建立 Emdebian都很類似,注意要改成紅色的部份。

rootfs install
Root$ mkdir -p ~/Emdebian
Root$ cd ~/Emdebian
Root$ debootstrap --arch=armel --foreign --include=vim,openssh-server jaunty rootfs/ http://ports.ubuntu.com


kernel modules install
Root$ cd $Kenrel_dir
Root$ make INSTALL_MOD_PATH=~/Emdebian/rootfs modules_install

***這邊的$Kenrel_dir 就是上一篇文章ltib所編出來的kernel位置($ur_ltib_location/ltib/rpm/BUILD/linux-2.6.31 /)。


rootfs setup
Root$ cp /usr/bin/qemu-arm-static ~/Emdebian/rootfs/usr/bin/
Root$ chroot ~/Emdebian/rootfs /bin/sh
I have no name!$ /debootstrap/debootstrap --second-stage
I have no name!$ passwd root (新增一下 root密碼)
I have no name!$ exit
Root$ cd ~/Emdebian/rootfs
Root$ echo "proc /proc proc none 0 0" >> etc/fstab
Root$ echo $your_hostname > etc/hostname
Root$ cd etc/event.d/
Root$ cp -rf tty1 ttymxc0
Root$ vim ttymxc0
把 tty1改成 ttymxc0,buad rate改成 115200
Root$ printf "auto lo eth0\niface lo inet loopback\niface eth0 inet dhcp\n" >> etc/network/interfaces
Root$ tar jcvf ../basic-debian.tar.bz2 . (做個備份)
Root$ cd ..
Root$ tar jxvf basic-debian.tar.bz2 -C /media/disk/ && sync && sync (假設SD卡巳經準備好了)
Root$ umount /dev/sdb


最後,重新開機吧,寶貝!

2010年6月25日 星期五

mini2440_buttons.c driver study

下面是 mini2440_buttons driver的完整程式。
#include < linux/module.h>
#include < linux/kernel.h>
#include < linux/fs.h>
#include < linux/init.h>
#include < linux/delay.h>
#include < linux/poll.h>
#include < linux/irq.h>
#include < asm/irq.h>
#include < linux/interrupt.h>
#include < asm/uaccess.h>
#include < mach/regs-gpio.h>
#include < mach/hardware.h>
#include < linux/platform_device.h>
#include < linux/cdev.h>
#include < linux/miscdevice.h>
#include < linux/sched.h>
#include < linux/gpio.h>

#define DEVICE_NAME     "buttons"

struct button_irq_desc {
    int irq;
    int pin;
    int pin_setting;
    int number;
    char *name;   
};

static struct button_irq_desc button_irqs [] = {
    {IRQ_EINT8 , S3C2410_GPG(0) ,  S3C2410_GPG0_EINT8  , 0, "KEY0"},
    {IRQ_EINT11, S3C2410_GPG(3) ,  S3C2410_GPG3_EINT11 , 1, "KEY1"},
    {IRQ_EINT13, S3C2410_GPG(5) ,  S3C2410_GPG5_EINT13 , 2, "KEY2"},
    {IRQ_EINT14, S3C2410_GPG(6) ,  S3C2410_GPG6_EINT14 , 3, "KEY3"},
    {IRQ_EINT15, S3C2410_GPG(7) ,  S3C2410_GPG7_EINT15 , 4, "KEY4"},
    {IRQ_EINT19, S3C2410_GPG(11),  S3C2410_GPG11_EINT19, 5, "KEY5"},
};
static volatile char key_values [] = {'0', '0', '0', '0', '0', '0'};

static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

static volatile int ev_press = 0;


static irqreturn_t buttons_interrupt(int irq, void *dev_id)
{
    struct button_irq_desc *button_irqs = (struct button_irq_desc *)dev_id;
    int down;

    // udelay(0);
    down = !s3c2410_gpio_getpin(button_irqs->pin);

    if (down != (key_values[button_irqs->number] & 1)) { // Changed

    key_values[button_irqs->number] = '0' + down;
   
        ev_press = 1;
        wake_up_interruptible(&button_waitq);
    }
   
    return IRQ_RETVAL(IRQ_HANDLED);
}


static int s3c24xx_buttons_open(struct inode *inode, struct file *file)
{
    int i;
    int err = 0;
   
    for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {
    if (button_irqs[i].irq < 0) {
        continue;
    }
        err = request_irq(button_irqs[i].irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH,
                          button_irqs[i].name, (void *)&button_irqs[i]);
        if (err)
            break;
    }

    if (err) {
        i--;
        for (; i >= 0; i--) {
        if (button_irqs[i].irq < 0) {
        continue;
        }
        disable_irq(button_irqs[i].irq);
            free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);
        }
        return -EBUSY;
    }

    ev_press = 1;
   
    return 0;
}


static int s3c24xx_buttons_close(struct inode *inode, struct file *file)
{
    int i;
   
    for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {
    if (button_irqs[i].irq < 0) {
        continue;
    }
    free_irq(button_irqs[i].irq, (void *)&button_irqs[i]);
    }

    return 0;
}


static int s3c24xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
{
    unsigned long err;

    if (!ev_press) {
    if (filp->f_flags & O_NONBLOCK)
        return -EAGAIN;
    else
        wait_event_interruptible(button_waitq, ev_press);
    }
   
    ev_press = 0;

    err = copy_to_user(buff, (const void *)key_values, min(sizeof(key_values), count));

    return err ? -EFAULT : min(sizeof(key_values), count);
}

static unsigned int s3c24xx_buttons_poll( struct file *file, struct poll_table_struct *wait)
{
    unsigned int mask = 0;
    poll_wait(file, &button_waitq, wait);
    if (ev_press)
        mask |= POLLIN | POLLRDNORM;
    return mask;
}


static struct file_operations dev_fops = {
    .owner   =   THIS_MODULE,
    .open    =   s3c24xx_buttons_open,
    .release =   s3c24xx_buttons_close,
    .read    =   s3c24xx_buttons_read,
    .poll    =   s3c24xx_buttons_poll,
};

static struct miscdevice misc = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = DEVICE_NAME,
    .fops = &dev_fops,
};

static int __init dev_init(void)
{
    int ret;

    ret = misc_register(&misc);

    printk (DEVICE_NAME"\tinitialized\n");

    return ret;
}

static void __exit dev_exit(void)
{
    misc_deregister(&misc);
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("FriendlyARM Inc.");


下面用程式碼片段,拆開來一步一步學習。

首先,先說linux device driver的架構,大致上的linux device driver,都會長的像下面這樣,
#include < linux/module.h>
#include < linux/kernel.h>
#include < linux/fs.h>
#include < linux/init.h>
#include < linux/delay.h>
#include < linux/poll.h>
#include < linux/irq.h>
#include < asm/irq.h>
#include < linux/interrupt.h>
#include < asm/uaccess.h>
#include < mach/regs-gpio.h>
#include < mach/hardware.h>
#include < linux/platform_device.h>
#include < linux/cdev.h>
#include < linux/miscdevice.h>
#include < linux/sched.h>
#include < linux/gpio.h>

static int s3c24xx_buttons_open(struct inode *inode, struct file *file)
{
...
}

static int s3c24xx_buttons_close(struct inode *inode, struct file *file)
{
...
}

static int s3c24xx_buttons_read(struct file *filp, char __user *buff, size_t count, loff_t *offp)
{
...
}

static struct file_operations dev_fops = {
    .owner   =   THIS_MODULE,
    .open    =   s3c24xx_buttons_open,
    .release =   s3c24xx_buttons_close,
    .read    =   s3c24xx_buttons_read,
};

static struct miscdevice misc = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = DEVICE_NAME,
    .fops = &dev_fops,
};

static int __init dev_init(void)
{
    int ret;

    ret = misc_register(&misc);

    printk (DEVICE_NAME"\tinitialized\n");

    return ret;
}

static void __exit dev_exit(void)
{
    misc_deregister(&misc);
}

module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("FriendlyARM Inc.");

2010年6月20日 星期日

mini2440 study (cross complie tool chain)

1. 下載cross compiler
使用code sourcery所提供的 toolchains,需注意的是,這個 toolchains的版本是 arm-2009q1-203-arm-none-linux-gnueabi-i686-pc-linux-gnu,這個版本對於 mini2440的 CPU(arm920t)來說太新,因為 arm920t是 ARMv4T的架構,是幾年前的產品了,所以需要對 toolchains做點修改。

2. 下載後,找個地方解壓縮
# tar -jxvf arm-2009q1-203-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 -C /opt/

3. 新增環境變數:
# export PATH=$PATH:/opt/usr/local/arm/4.3.3/bin

4. 修改變數名,將 "arm-none-linux-gnueabi-"開頭改成 "arm-linux-"開頭
ln -s arm-none-linux-gnueabi-gdbtui arm-linux-gdbtui
ln -s arm-none-linux-gnueabi-addr2line arm-linux-addr2line
ln -s arm-none-linux-gnueabi-gprof arm-linux-gprof
ln -s arm-none-linux-gnueabi-ar arm-linux-ar
ln -s arm-none-linux-gnueabi-as arm-linux-as
ln -s arm-none-linux-gnueabi-nm arm-linux-nm
ln -s arm-none-linux-gnueabi-ld arm-linux-ld
ln -s arm-none-linux-gnueabi-c++ arm-linux-c++
ln -s arm-none-linux-gnueabi-objcopy arm-linux-objcopy
ln -s arm-none-linux-gnueabi-c++filt arm-linux-c++filt
ln -s arm-none-linux-gnueabi-cpp arm-linux-cpp
ln -s arm-none-linux-gnueabi-ranlib arm-linux-ranlib
ln -s arm-none-linux-gnueabi-objdump arm-linux-objdump
ln -s arm-none-linux-gnueabi-readelf arm-linux-readelf
ln -s arm-none-linux-gnueabi-size arm-linux-size
ln -s arm-none-linux-gnueabi-gcov arm-linux-gcov
ln -s arm-none-linux-gnueabi-strings arm-linux-strings
ln -s arm-none-linux-gnueabi-gdb arm-linux-gdb
ln -s arm-none-linux-gnueabi-strip arm-linux-strip
ln -s arm-none-linux-gnueabi-sprite arm-linux-sprite


(重點)5. 在 /opt/usr/local/arm/4.3.3/bin/ 資料夾裡新增三個 shell script,將 toolchains降為 armv4t版本
arm-linux-g++的shell script內容:
#!/bin/sh
arm-none-linux-gnueabi-g++ -march=armv4t $*


arm-linux-gcc的shell script內容:
#!/bin/sh
arm-none-linux-gnueabi-gcc -march=armv4t $*


arm-linux-gcc-4.3.3的shell script內容:
#!/bin/sh
arm-none-linux-gnueabi-gcc-4.3.3 -march=armv4t $*


6. 修改權限
# chmod +x arm-linux-g++
# chmod +x arm-linux-gcc
# chmod +x arm-linux-gcc-4.3.3


7. 查看是否成功
# arm-linux-gcc -v

2010年5月30日 星期日

Use Linux shell scipt to build a small embedded root file system for arm

之前的文章有用 Emdebian的 debootstrap手動建立一個嵌⼊式小型的rootfs for arm,整個流程下來有點繁瑣,
如果只是久久產生一次 rootfs那倒還好,但如果是時常需要新的話,一直重覆的動作會瘋掉,所以,在Linux下,
要避免掉重覆的動作,最好的法就是寫成 shell script,剛好在網路有看到人家寫好的,就拿來用,外加改成自己想要的,

參考的網址,
How to Cross Compile a Kernel and Create the Debian Root File Store

自己改的,
gen_root3.sh

有改到的,列一下,怕自己忘記,
1. url=http://ftp.tw.debian.org/debian <-- 改網址,原本是hk香港的

2. kernel_version=2.6.31.5 <-- 要依照目前的 kernel版本,如果是28,就變2.6.28.XX

3. eth=static
address=140.92.XXX.XXX
netmask=255.255.255.0
gateway=140.92.XXX.XXX <-- 改成靜態的網址 /etc/network/interface

4. newhostname=sam-debian <-- /etc/hostname

5. extra_debs=openssh-server <-- 你想要安裝的其他檔案

6. root_partition=/dev/mmcblk0p1 <-- SD卡開機,/etc/fstab

7. #support for imx51 board about ttymxc0 node
file=dev/ttymxc0
echo Creating $file
mknod -m 755 $file c 207 16 <-- 增加板子需要的node

file=etc/securetty
echo Creating $file
echo "ttymxc0" >> $file <-- 重要!!! 一定要加!!!不然就算接UART,畫面也不會有東西

8. 在 /etc/inittab的地方,原本是
#1:2345:respawn:/sbin/getty 115200 ttyS0 -->
改成
1:2345:respawn:/sbin/getty 115200 ttymxc0


接下來,作好的 rootfs,做成 SD卡開機,第一次開機會比較久,因為原本還要做
./debootstrap/debootstrap --second-stage這個動作,已經被改成一開機就會執行,(你會發現被放在根目錄的 stage2)
之後,它會自己重開機,帳號一開始為 root

2010年5月12日 星期三

smplayer and mplayer for arm

建立一個簡單的distribution for arm (續)

這裡繼續完成之前系統所需要的rootfs,我主要是用Emdebian。

Host: Ubuntu 9.10 karmic for x86
Target: Debian 5.0 lenny for arm

有許多東西,是從Nabe大大的網誌學到的
http://nabeko-notebook.blogspot.com/2010/04/emdebian-on-arm-by-debootstrap.html


直接開始吧!
rootfs install
Root$ mkdir -p ~/Emdebian
Root$ cd ~/Emdebian
Root$ debootstrap --arch=armel --foreign --include=vim,openssh-server lenny rootfs/ http://www.emdebian.org/grip/


kernel modules install
Root$ cd $Kenrel_dir
Root$ make INSTALL_MOD_PATH=~/Emdebian/rootfs modules_install

***這邊的$Kenrel_dir 就是上一篇文章ltib所編出來的kernel位置($ur_ltib_location/ltib/rpm/BUILD/linux-2.6.31/)。


rootfs setup
Root$ cp /usr/bin/qemu-arm-static ~/Emdebian/rootfs/usr/bin/
Root$ chroot ~/Emdebian/rootfs /bin/sh
I have no name!$ echo "proc /proc proc none 0 0" >> etc/fstab
I have no name!$ echo $your_hostname > etc/hostname
I have no name!$ echo 'deb http://www.emdebian.org/grip/ lenny main' >> etc/apt/sources.list
I have no name!$ echo 'deb http://ftp.tw.debian.org/debian lenny main' >> etc/apt/sources.list
I have no name!$ mknod dev/console c 5 1
I have no name!$ mknod dev/ttymxc0 c 207 16 (imx51 板子上UART 1的裝置節點)
I have no name!$ export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
I have no name!$ /debootstrap/debootstrap --second-stage
I have no name!$ echo ttymxc0 >>etc/securetty
I have no name!$ printf "T0:123:respawn:/sbin/getty 115200 ttymxc0\n" >> /etc/inittab
I have no name!$ exit
Root$ cd ~/Emdebian/rootfs
Root$ tar jcvf ../basic-debian.tar.bz2 . (做個備份)
Root$ cd ..
Root$ tar jxvf basic-debian.tar.bz2 -C /media/disk/ && sync && sync (假設SD卡巳經準備好了)
Root$ umount /dev/sdb

到現在為止,一個基本的rootfs巳經差不多完成了,只是等等還有些東西要再調一下。


boot from imx51 board
開機後,會發現一些問題,
1. 系統的網路預設會讀取 eth0 node,但找不到,後來發現是只有 eth1,而不是 eth0。
---> 原因在於,當初整個系統是用 chroot完成的,而在本機的電腦上就巳經有 eth0這個節點,所以,如果要再建立一個網路節點,系統就會給 "eth1"。
解決方法,
sh-3.2# vim /etc/udev/rules.d/70-persistent-net.rules

# PCI device 0x1969:0x1026 (ATL1E)
#mark thie line
#SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:23:54:0d:2d:
3c", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

#change eth1 to eth0
# Unknown net device (/devices/platform/fec.0/net/eth0) (fec)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:04:9f:01:00:b
3", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"


2. enable network
sh-3.2# vim /etc/network/interfaces

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 140.92.XXX.XXX
netmask 255.255.255.0
gateway 140.92.XXX.XXX

sh-3.2# vim /etc/resolv.conf
#DNS server
nameserver 140.92.XXX.XXX


3. Qt env setup
如果之前有把QT porting進來,順便寫個script,讓電腦登⼊時,設定一下執行環境
sh-3.2# vim ~/.bashrc

export QTDIR=/ur_qt_location
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH

echo "moblin" | sudo -S chmod 777 /tmp
echo "moblin" | sudo -S chmod 777 /dev/fb0
echo "moblin" | sudo -S chmod 777 /dev/input/mice
echo "moblin" | sudo -S chmod 777 /dev/tty0

***之前巳經有提過,在沒有toucn screen 的情況下,用鍵盤和滑鼠代替,即一些權限的設定。


最後,重新開機吧,寶貝!

2010年3月30日 星期二

建立一個簡單的distribution for arm

在開始前,先大約介紹一下有用到的東西,
bootloader: redboot
kernel: 2.6.31 ltib for imx51
rootfs: emdebian or ubuntu rootstock
board: freescale imx51


1. 先編kernel。這裡是用freescale 對於這塊板子提供的其中一個工貝,叫ltib。可以想像它就像是LFS寫成一個shell script,幫你從頭到尾建立kernel及roorfs,省去cross compiler的時間。比較重要的是這個ltib是由freescale 所提供的,所以裡面有板子的BSP,及kernel的patch,不然ltib其實是個open project。
***這包ltib在freescale的文件中說,要在Ubuntu 9.04下執行,才能正常work!!!!***
1. Download package L2.6.31_09.12.00_SDK_source.tar.gz
2. tar xvf L2.6.31_09.12.00_SDK_source.tar.gz
3. cd L2.6.31_09.12.00_SDK_source
4. ./install
5. cd ltib
6. ./ltib -m config
7. 等一段時間......
8. 會出現一個要你選rootfs的畫面,選min profile就好(因為它很小,省時間,重點是最後根本不需要..)
9. 再東選選西選選,重點要選目前用的板子,imx51_babbage
10. ./ltib
11.等一段時間......
12.中間會出現kernel的menuconfig,選你要的drivers吧
13.選完後,再等一下,就會在目前的資料夾產生一堆東西
14.重要的兩個,分別是roofs 資料夾(rootfs/boot/zImage<--kernel),及rpm 資料夾(rpm/BUILD/linux-2.6.31<--kernel source tree and some modules)


2. 燒寫bootloader 及kernel
1. bootloader。在這裡是用redboot,你也可以用uboot,但在freescale 的教學文件中都是用redboot。
1. Download package L2.6.31_09.12.00_SDK_images_MX51.tar.bz2
2. tar xvf L2.6.31_09.12.00_SDK_images_MX51.tar.bz2
3. cd L2.6.31_09.12.00_SDK_images_MX51
4. tar xvf redboot_200952.tar.bz2
5. cd redboot_200952/bin
6. dd if=mx51_babbage_redboot.bin of=/dev/sdb && sync && sync (假設SD卡為 /dev/sdb)
7. cd $ur_ltib_location/ltib/rootfs/boot/
8. dd if=zImage of=/dev/sdb bs=512 seek=2048 && sync && sync

2. 分割SD磁區。這裡是要將kernel跟rootfs分開。
1. fdisk /dev/sdb
The number of cylinders for this disk is set to 8491.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)
Command (m for help): u
Changing display/entry units to sectors
Command (m for help): d
Selected partition 1
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number (1-4): 1
First sector (48-7744511, default 48): 8192
Last sector or +size or +sizeM or +sizeK (8192-7744511, default 7744511):

Using default value 7744511
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
WARNING: Re-reading the partition table failed with error 16: Device or
resource busy.
The kernel still uses the old table.
The new table will be used at the next reboot.

2. umount /dev/sdb1
3. mkfs.ext3 /dev/sdb1


所以,/dev/sdb1巳經被格式化為ext3,等著後面要做的rootfs,做好的rootfs,就可以放到這裡來。
且SD卡前面的4M,存放著bootload及kernel。

理論上來說,這張SD卡巳經可以開機,只需要設定一下redboot的參數,
開機時,趕按 ctrl+C,進⼊bootloader
RedBoot> fis init
RedBoot> fis create -n -b 0x100000 -f 0x100000 -l 0x300000 kernel
RedBoot> fconfig
Run script at boot: true
Boot script:
Enter script, terminate with empty line
>> fis load kernel
>> exec –c “noinitrd console=tty1 console=ttymxc0, 115200 root=/dev/mmcblk0p1 rw video=mxcfb:800x600-16@60”
>>
Boot script timeout (1000ms resolution): 1
Use BOOTP for network configuration: true
Default server IP address: 192.168.0.1
Board specifics: 0
Console baud rate: 115200
Set eth0 network hardware address [MAC]: false
GDB connection port: 9000
Force console for special debug messages: false
Network debug at boot time: false
Update RedBoot non-volatile configuration - continue (y/n)? y
... Read from 0x07ee0000-0x07eff000 at 0xeff80000: .
... Erase from 0xeff80000-0xeffa0000: .
... Program from 0x07ee0000-0x07f00000 at 0xeff80000: .
RedBoot>


重啟電腦,但一定會出現kernel panic,因為這時還沒有rootfs啊。

2010年3月17日 星期三

Qt embedded porting

這次是要將 QT proting到 freescale的板子上,大約列一下所用到的硬體及環境
1.Host: x86 with fedora 11
2.Target: freescale imx51 with ubuntu for arm
3.cross compiler tools: arm-2009q3-67-arm-none-linux-gnueabi-i686-pc-linux-gnu
4.Qt: qt-everywhere-opensource-src-4.6.2


網路上有很多資源,不過其中我試的是這位Simon大大的教學文章
http://zylix666.blogspot.com/2008/10/qt-embedded-porting-on-arm-platform.html

但在這之前,還有些設定要做,下列是我的作法及步驟
###先安裝cross compiler tools及設定好環境
1. 將下載下來的 arm-none-linux-gnueabi解壓縮
$ tar -xvf arm-2009q3-67-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2
2. 將其中的bin設定到$PATH當中
$ export PATH="$PATH":/home/sam/Download/arm/arm2009q3/bin
又或者想要一開terminal就載入環境變數
在~/.bashrc裡加入
$ export PATH="$PATH":/home/sam/Download/arm/arm2009q3/bin

3. 這時候在terminal直接打arm-none-linux,TAB兩下,如果有顯示出所有arm-linux-none- 相關執行檔,這樣表示環境變數設定成功

###開始安裝Qt embedded及設定
接下來的步驟,幾乎跟Simon大大的步驟一樣
1. 將下載下來的Qt embedded package解壓縮
$ tar -xvf qt-everywhere-opensource-src-4.6.2.tar.gz
2. 修改mkspecs/qws/linux-arm-g++/qmake.conf內的編譯器設定,將其設為目前所使用的tool chain
QMAKE_CC = arm-none-linux-gnueabi-gcc
QMAKE_CXX = arm-none-linux-gnueabi-g++
QMAKE_LINK = arm-none-linux-gnueabi-g++
QMAKE_LINK_SHLIB = arm-none-linux-gnueabi-g++
QMAKE_AR = arm-none-linux-gnueabi-ar cqs
QMAKE_OBJCOPY = arm-none-linux-gnueabi-objcopy
QMAKE_STRIP = arm-none-linux-gnueabi-strip

3. 然後執行:
$ ./configure -embedded arm -qt-zlib -qt-libpng -qt-gif -qt-libtiff -qt-libmng -qt-libjpeg -qt-freetype -no-openssl
$ make
$ make install

4. 安裝完,預設會安裝到/usr/local/下,會在這裡看到一個Trolltech的資料夾,會有一個QtEmbedded-4.6.2-arm,所有的需要的都在這裡
5. 將剛才編譯好的QtEmbedded-4.6.2-arm,上傳至target board上的root file system。並且放在/usr/local/Trolltech下,Trolltech資料夾在target board上要自己建
$ mkdir /usr/local/Trolltech
6. 要執行範例程式之前,先設定好環境參數:
$ export QTDIR=/usr/local/Trolltech/QtEmbedded-4.6.2-arm
$ export PATH=$QTDIR/bin:$PATH
$ export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH

7. 可在/usr/local /Trolltech/QtEmbedded-4.4.3-arm/example 或者是demos內找到一些可執行的範例
8. ***重點來了***,由於對方沒有給touch screen,所以我沒有編touch的driver, 也就是tslib for arm,取而代之,是用電腦的mouse及keyboard,但在執行Qt embedded的範例時,mouse及keyboard都不會動,花了很多時間找,網路都是用tslib,也就是有touch screen的硬體,所以需要下列方式解決:
$ QWS_MOUSE_PROTO=/dev/input/mice
$ QWS_KEYBOARD=/dev/tty0

9. ***執行範例,還是不會動***,看了營幕顯示的訊息表示,
'/dev/input/mice' permission deny
'/dev/tty0' permission deny

所以改了這兩的權限
$ chmod 777 /dev/input/mice
$ chmod 777 /dev/tty0

10. 這樣就可以動了,挑個範例試試
$ /usr/local/Trolltech/QtEmbedded-4.6.2-arm/demos/browser/browser -qws
注意要加上-qws這個flag

###編譯自己寫的程式且port到板子上
如果自己有寫個Qt的程式,假設程式是放在,/usr/local/Trolltech/QtEmbedded-4.6.2-arm/examples/Hello底下,想port到板子上,用下面的方法:
$ /usr/local/Trolltech/QtEmbedded-4.6.2-arm/bin/qmake -spec ../../mkspecs/qws/linux-arm-g++ -unix -o Makefile Hello.pro
此時在同個目錄會產生一個Makefile檔,再執行
$ make
就會編譯出一個Hello的binary file for arm,仔細一看,確實是ARM的執行檔
$ file ./Hello
$ Hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.16, not stripped

之後,就可以將這個執行檔搬到板子上了,且順利執行!

其中,板子上是安裝ubuntu 9.10 for arm 的版本,網路上下載的到,而且還是針對
freescale imx51這槐板子所做的,功能該有的都有,但由於desktop是用Gnome,對於
板子來說太肥,跑的不順,所以改裝LXDE,順多了…
sudo apt-get install lxde
本來是要調更多有關板子效能的問題,例如快速開機,或是砍掉多餘的service等,
但時間不多,所以只改了desktop的部份。

2010年2月14日 星期日

tty?? ttyn?? ttySn?? console??

之前對於/dev/下有關tty ttyn ttySn console搞混,
後來上網查了一些資料,有點感覺了....不過不知道對不對就是了XD

假設: 有一台主機,跟一台螢幕,而主機有2個com port

n=0.1.2.3.4.....等數字
/dev/console: 表示目前的螢幕,就是擺在桌上的那台螢幕
/dev/tty: 虛擬