2010年10月4日 星期一

[Linux] 不聽使喚的Proxy for APT

如果在特殊的環境裡面(如:學校,公司)
使用APT常常會需要proxy來幫忙下載軟體包,可是有時候明明已經修好改proxy路徑,卻不聽使喚。APT有時候很搞怪阿。
通常更換APT的proxy有

/etc/apt/apt.conf

裡面填寫:
Acquire::http::proxy "http://XXX.XXX.XXX:3128/";
即可。
不過有時候不會動。(棍!

或是去GUI填寫
Network proxy
然後按下去"apply System-wide"
即可
不過有時候也不會動。(幹!!

執行之後會噴
"111 Connection refused"

也就是說他還是讀取舊的或是不正確的proxy,原因在於apt讀取的是
$http_proxy <--這個全域變數

echo $http_proxy
可以看到。

修改法
export http_proxy=http://XXX.XXX.XXX:3128
增加到全域去即可。

當然重新開terminal會不見
可以考慮寫進去

/.bashrc
裡

2010年6月2日 星期三

[Linux] 你不知道的 echo

靠腰~~~
是我自己不知道的echo....  T__T

感覺有個小BUG死在這個小細節....  而且還不是我弄的

code 裡面用system call 的echo 跟 console 下面手打的反應竟然不同....

Orz... 用男人問了一下echo 才知道 囧>
通常echo就是拿來回呼你打入的字串,或者是把字串傳入某個目的檔
如: echo "bejo" > bejo.txt

(題外話: 還搞不清楚 " " 符號 跟 ' ' 在echo 使用上有差別嗎?)

echo command 也是有參數的

-e: 允許用跳脫符號 ( \ )
-n: 結束不要自動換行(預設會)
-E: 不允許用跳脫符號(預設)


看起來沒啥問題就出在一些tty dev用echo 餵參數的時候會卡在換行,特殊符號等等

所以應該要
echo -ne "bejo is \"8787\"\n" > /dev/ttyXXX
要加上參數...  嗚~~真痛O__Q

紀錄幾個跳脫常用的

\n 換行
\a 發出逼逼聲
\b 往前刪除一個字( backspace)
\r 往前整行刪掉


特別的是
\0NNN NNN是十進位 可以echo 出 ascii 上的字元
例如:
echo -e "\0100" 印出 @

\xHH HH 是16進位
echo -e "\x40" 效果跟上面的一樣 印出@

詳細對照可以
man ascii 查詢

------------------------
echo 也可以改變console顏色
分為前景跟背景

echo -e "\E[31;42mBEJO\n"

m後面就是跟著你想顯示的文字內容
前景是紅 31
背景是綠 42
數字對調沒差,因為定義不重疊

我用烏幫兔玩一下然後...console 變的很噁心,可以用
echo -ne \E[0m
加在字尾也可
echo -e "\E[31;42mBEJO\E[0m"
復原

下面是網路查到對應表:
-------------------------------
    前  背
黑 30 40
紅 31 41
綠 32 42
黃 33 43
藍 34 44
青 36 46
白 37 47

聽說不是每個終端機都一樣,阿災~

2010年6月1日 星期二

[Linux] Ethernet driver 骨架

算一算已經自願調到driver team 好一陣子了,從user space 寫到kernel space感覺上似乎沒改變太多,每天還是看code,需要動手大改的機會都不多,大概這就是系統廠的宿命。

不過誰說工作要求才能寫,XD 最近邊debug ethernet driver,乾脆就動手自己寫一個註冊net device...

這樣就更清楚了整個flow了。
底下附上的code都是拿掉硬體IO reg 等等相關,一來只是要紀錄如果從無到有寫一個,二來硬體資料百百款跟vendor拿到spec 在接上就可以,有空再補哩。

net device 的註冊已經是很普遍了,只要自己建好下面幾個function 就可以動了。
當然
不包含NAPI,沒寫 poll,沒有ioctl (通常拿來改MAC), device status, config 等等都沒有XD
-----------------
static void do_bth_tx(u_char *buffer, u_short len)
static void do_bth_rx(void)
static irqreturn_t bth_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static int bth_open(struct net_device *dev)
static int bth_stop(struct net_device *dev)
static int bth_xmit(struct sk_buff *skb, struct net_device *dev)
void bth_tx_timeout(struct net_device *dev)
int bth_init(struct net_device *dev)
static int __init bth_dev_init(void)
static void __exit bth_dev_exit(void)

-----------------------------------------------------------------------------
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <asm/irq.h>
#include <asm/io.h>

struct bth{  

    spinlock_t lock;
}; // 裡面要建構硬體私有的宣告,不需要的都拿掉了。

static struct net_device *bth_dev = NULL;

static void do_bth_tx(u_char *buffer, u_short len)
{
    //接硬體的部份拿掉了
    char shortpkt[ETH_ZLEN];

    if(len < ETH_ZLEN)
    {
        memset(shortpkt, 0X0, ETH_ZLEN);
        memcpy(shortpkt, buffer, len);
        len = ETH_ZLEN;
        buffer = shortpkt;
    }
    printk("%x\n", buffer);
    printk("bth_tx_done the bth dev! \n");
}

static void do_bth_rx(void)
{
    struct net_device *dev = bth_dev;
//    struct bth *bthx = (struct bth *)dev->priv;
    struct sk_buff *skb;
   
    int frame_len = 1500; // it needs read form phy
   
    skb = dev_alloc_skb(frame_len + 2);
    skb_reserve(skb, 2);
    skb->dev = dev;
    skb_put(skb, frame_len);

    skb->protocol = eth_type_trans(skb, dev);
    netif_rx(skb);
   
    dev->trans_start = jiffies;
    printk("bth_packet_receive the bth dev!\n");
}

static irqreturn_t bth_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
//中斷產生時呼叫,內容化簡
    do_bth_rx();
    return IRQ_HANDLED;
}

static int bth_open(struct net_device *dev)
{
// ifconfig up 會呼叫
    if(request_irq(dev->irq, &bth_interrupt, 0, dev->name, dev))
        return -EAGAIN;
    netif_start_queue(dev);
    printk("open the bth dev! \n");
    return 0;
}

static int bth_stop(struct net_device *dev)
{
//ifconfig down 會呼叫
    netif_stop_queue(dev);
    free_irq(dev->irq, dev);
    printk("bth dev STOP!!! \n"); 
    return 0;
}

static int bth_xmit(struct sk_buff *skb, struct net_device *dev)
{
    struct bth *bthx = (struct bth *)dev->priv;
    unsigned long flags;
   
    spin_lock_irqsave(&bthx->lock, flags);
   
    dev->stats.tx_bytes += skb->len;
    dev->stats.tx_packets++;
    do_bth_tx(skb->data,skb->len);
    dev->trans_start = jiffies;
   
    spin_unlock_irqrestore(&bthx->lock, flags);
   
    printk("hard start xmit the bth dev! \n");  
    return 0;
}

void bth_tx_timeout(struct net_device *dev)
{
//tx timeout 的時候呼叫
    printk("TIMEOUT the bth dev! \n"); 
    dev->trans_start = jiffies;
    netif_wake_queue(dev);
}
int bth_init(struct net_device *dev)
{
//這裡接上,基本上就可以看到interface了
    struct bth *bthx;
    int i;
    unsigned char mac_addr[6] = {0x00, 0x11, 0x22, 0x33, 0x99, 0x99}; // 通常是從REG或另外的記憶體讀出,這裡寫死
    bthx = (void *)kmalloc(sizeof(struct bth), GFP_KERNEL);
    memset(bthx, 0, sizeof (struct bth));
   
    if (!dev)
    {
        printk(": unable to allocate etherdev\n");
        return 1;
    }
    ether_setup(dev);
   
    dev->priv = bthx;
    dev->open         = bth_open;
    dev->stop         = bth_stop;
    dev->hard_start_xmit  = bth_xmit;
    dev->tx_timeout = bth_tx_timeout;
    for (i = 0; i < 6; i++)
        dev->dev_addr[i] = mac_addr[i];
    return 0;
}

static int __init bth_dev_init(void)
{
    bth_dev = alloc_netdev(sizeof(struct bth), "bth%d", bth_init);
    register_netdev(bth_dev);
    printk("init the bth dev! \n");

    return 0;
}

static void __exit bth_dev_exit(void)
{
    unregister_netdev(bth_dev);
    free_netdev(bth_dev);
    kfree(bth_dev->priv);
    printk("bth dev exit!! \n");
}

module_init(bth_dev_init);
module_exit(bth_dev_exit);


2010年4月30日 星期五

[Linux] 少用但是你被卡住時好用的指令 fuser and lsof

小微微常常刪檔或是改檔的時候會跟你靠腰說"檔案正在使用中...",讓你不能刪除檔案,但有時候還是不知道誰在用,linux下面也有。

fuser

Show which processes use the named files, sockets, or filesystems

lsof
list open files

多好用?
欲哭無淚的時候,很好用.....
紀錄幾個常用用法

fuser -v -mu /home/bejo
fuser -v -mu /proc


-v: 不加沒辦法閱讀啦
查看目錄或是檔案被誰用。查proc妙用無窮(疑?
也可以用來砍掉再用的process,不過...

lsof -i
-i 查哪些程式在用網路資源...(上次TFTP就是這樣找出來的 囧>)

lsof -u root
查root用了哪些東西

組合起來就可以用

lsof -u root -a -i
查root開了哪些網路程式
-a: 用來組合其他條件,例如 -i

有程式亂活動馬上就知道@__@!!!


2010年4月28日 星期三

[小微微]開機指令檔/關機指令檔

最近想放棄WINXP換系統.....
可是發現我一窮二白...買不起W7

只好整理開機流程加快一下系統O__Q
XP系統如果想在登入帳號之前執行使用者想要執行的動作,如COPY檔案、檢查檔案、撥PPPoE連線等等

埋在"啟動"資料夾、排程、系統服務都不適當

應該要放在
開始=>執行=>gpedit.msc (就是群組原則啦)
電腦設定=>windows設定=>將 [開機指令檔] 指向 想執行的程式(*.BAT也可)。

這也提供[關機指令檔] (用新增的) 可以在關機的時候做。
類似linux的S60_XXX,S99_XXX 開機執行,跟rc file的執行階段不大一樣。

會在Windowns登入使用者之前就執行。

看來想換DX10來打電動要再久一點了.....(哭哭

2010年4月26日 星期一

[語言] 沒營養的 - do{} while(0)

看code 有時候會看到沒營養的
do{ XXX } while(0)

直覺上會覺得很北七...  顯然北七的只是表面...
這種寫法常見在

#define

如
#define BEJO(x) {a(x-2);b(x);} while(0)
#define a(x) printf("%d\n", x)
#define b(x) printf("%d\n", x)

如果這樣寫
#define BEJO(x) a(x-2);b(x);
那
if(x >0 )
   BEJO(x);
else
.....
會被展開成
if(x >0 )
   a(x-2);b(x);;
else
.....

當場就b(x)爆炸了.....

那如果這樣寫
#define BEJO(x) {a(x-2);b(x)}
就...
if(x >0 )
   {a(x-2);b(x)};
else
.....

那如果這樣寫
#define BEJO(x) {a(x-2);b(x);}
就...
if(x >0 )
   {a(x-2);b(x);};
else
.....

不管怎麼寫~~都有可能會被呼叫者誤用到爆炸
按照
本來BEJO(x); <-- 會加分號的習性

do{} while(0)

剛剛好...
if(x >0 )
   BEJO(x);
else
.....
會被展開成
if(x >0 )
   {a(x-2);b(x);} while(0);
else
.....

很安全.....

2010年3月23日 星期二

[語言] Select 小紀末

select()

最近碰到一點小小厘清。

select 時間塞給他NULL跟0的差別。
什麼? 0 跟 NULL 不是ㄧ樣嗎?不ㄧ樣就是不ㄧ樣,筆畫還差很多咧。
如果資料一直在進FD倒是沒差太多,如果資料斷斷續續你又擺了個while LOOP,
那就會有很討厭的現象了,最近差點被dev沒回應搞死Orz

從"函式庫辭典挖ㄧ段"來寫程式證明:

--
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

int main(void)
{
        fd_set rfds;
        struct timeval tv;
        int retval;
        char buf[1024];
        bzero(buf, sizeof(buf));
        
        while(1)
        {
            FD_ZERO(&rfds);
            FD_SET(0, &rfds);

            tv.tv_sec = 0;
            tv.tv_usec = 0;

            retval = select(1, &rfds, NULL, NULL, &tv);
            if(retval == -1)
                    perror("select error !!!\n");
            else if(retval)
                    printf("Data is available NOW!!\n");

            if(FD_ISSET(0, &rfds))
            {
                    read(0, buf, sizeof(buf));
                    printf("Message: %s \n", buf);
                    break;
            }else
                    printf("No date\n");
        }
        return 0;
}
--
給0的時候馬上就回報FD沒有資料可以讀取
--
            retval = select(1, &rfds, NULL, NULL, NULL);
給NULL的時候會select會停住直到FD有資料可用。
是有一點點差別的。

PS.
通常都會這樣寫,另外弄一個*tvp增加彈性
(sec, usec 秒數是相加)
    struct timeval tv, *tvp;
    if(XXX)
        tvp = NULL;
    else
    tvp = &tv
    tv.tv_sec = secs;
    tv.tv_usec = tv.tv_sec/1000000;
    tv.tv_usec %= 1000000;
    retval = select(1, &rfds, NULL, NULL, tvp);