星期四, 12月 29, 2005
C 的隱藏structure
還是在廠商的code看到,----- 應該大家都已經知道。
這是為了隱藏structuer 的內部結構用的方法(應該不是甚麼好動機),通常用在廠商只願意提供object file (或library archive)讓RD link。又不願意release出 要用作library 參數用的stucture內部構造。
但是這個structure屬於library module內部所需,不希望外界的code會access(Read/Write)到structure內部的資料。所以外部的code : application 主體(main.c) :
因為C的structure 參數一律傳遞pointer,所以對structure內部結構了不了解不影響compile的動作。
在模組話程式設計裏,這樣的module設計是不好的,叫做??? coupled 。
這是為了隱藏structuer 的內部結構用的方法(應該不是甚麼好動機),通常用在廠商只願意提供object file (或library archive)讓RD link。又不願意release出 要用作library 參數用的stucture內部構造。
arg.h:上面的例子, library中包含兩個module : liba.c, libb.c,一個作create working space用,一個依照working space的內容來操作。共同需要的就是workingspace : struct arg 這個structure。
struct arg{
char data;
....
};
liba.c:
#include <arg.h>
int lib_get_arg(struct arg **pp)
{
*p=malloc(.....);
...
}
int lib_clean_arg(struct arg *p)
{
free(p);
...
}
libb.c:
#include %lt;arg.h%gt;
int operation(struct arg *p, int oprtation)
{
*p=.....
... = *p...
}
但是這個structure屬於library module內部所需,不希望外界的code會access(Read/Write)到structure內部的資料。所以外部的code : application 主體(main.c) :
extern int lib_get_arg(struct arg **p);這樣compile不會過,因為struct arg 沒有宣告,但是又不知道struct arg的內容到底是甚麼,所以就:
extern int lib_clean_arg(struct arg *p);
extern int operation(struct arg *p,int operation);
struct arg;告訴compile 是一個structure,內容不知道,這樣就可以了。
因為C的structure 參數一律傳遞pointer,所以對structure內部結構了不了解不影響compile的動作。
在模組話程式設計裏,這樣的module設計是不好的,叫做??? coupled 。
C 的printf debug output , 使用 __FILE__和__LINE__
從廠商的code看到的。----- 或許很多programmer 都已經知道了。
沒有ICE的場合,常常要用printf將message送出去。
配合C 的predefined macro __FILE__ 和 __FILE__ 可以做出漂亮的debug output message。
所以用
上面的例子就是在test.c 的121行。
沒有ICE的場合,常常要用printf將message送出去。
配合C 的predefined macro __FILE__ 和 __FILE__ 可以做出漂亮的debug output message。
__FILE__ 代表目前source code file name,是一個字串(char*)
__LINE__ 代表目前的行數,是integer。
所以用
printf("[%s:%d] error here!!\n",__FILE__, __LINE__);可以輸出:
[test.c:121] error here!!這樣在多module (.c) file的場合,也可以迅速的知道message是由那一個module(.c) file送出的,乃至於是在source code中的第幾行,都可以知道。
上面的例子就是在test.c 的121行。
星期三, 12月 28, 2005
Copy 部份的binary 檔出來 -- 或說是 砍掉檔案的某一部份
因為有廠商送demo image,竟然將bootloader 和 kerenl + root 合在一起的rom image送過來,
這樣就沒辦法mount rootfs 進來看,而且也會破壞掉我原來的bootloader,
所以還是把他分開來。
本以為是用objdump, objcopy,但是這兩個tool好像能對有symbol table, sector information的檔案格式(obj) 操作。
最後,只有想到這個 : dd 這個command
dd 的man 說 option 有..
這 樣就可以把orgimage的後半部份(從0x00280000開始)copy出來。
如果是要copy 前半段,就用count=
另外記一下,分割的方法..split
合併就用' cat' 啦
這樣就沒辦法mount rootfs 進來看,而且也會破壞掉我原來的bootloader,
所以還是把他分開來。
本以為是用objdump, objcopy,但是這兩個tool好像能對有symbol table, sector information的檔案格式(obj) 操作。
最後,只有想到這個 : dd 這個command
dd 的man 說 option 有..
ibs=BYTES 每次讀取BYTES bytes所以我要從file 的0x00280000 開始copy,copy到最後,command是...
if=FILE 從FILE 讀入資料(如果沒指定,就是從stdin)
of=FILE 輸出到FILE (如果沒指定,就輸出到stdout)
skip=BLOCKS 跳過開頭BLOCKS ibs單位的資料不要copy
$ dd if=orgimage of=kandr ibs=64k skip=40因為0x10000 = 64k, 0x28 = 40.
這 樣就可以把orgimage的後半部份(從0x00280000開始)copy出來。
如果是要copy 前半段,就用count=
$dd if=orgimage of=head ibs=1M count=4就是copy orgimage的前4M出來到head。
另外記一下,分割的方法..split
split -b 1m mySong.mp3 mySong會把mySong.mp3 分成1M大小的mySone00,mySong01...
合併就用' cat' 啦
cat mySong00 mySong01 mySong02 > mySong.mp3
星期二, 12月 27, 2005
PAT, PMT in MPEG2 Stream :筆記
在做DVB播放時,出現的option和information,有這兩個字: PMT, PAT。所以google一下:
ES : Elementary Stream - 經過壓縮後的節目內容Audio ES,Video ES。
PES : Packetized Elememtary Stream,將ES由一個連續的stream分成一個一個packet後的packet。
TS : Transport Stream - 實際傳輸的Stream。由一連串的TS packet組成。
PID : TS Packet 中,用來代表這一個Packet 的資料ID的欄位。
Synch : TS Stream中用來代表TS Packet開頭的byte
PAT : Program Associate Table
PMT : Program Mapping Table
eedesign的這一篇有很好的概論,說明MPEG TS (Transport Stream)。
一般的攝影裝置,輸出都是BT601(270Mbps)。
利用ISO/IEC13818 作Video Coding,壓縮到3~5Mbps。
壓縮後的Video, Audio 資料都是Elementary Stream(Video ES, Audio ES)。
ES被切割成很多小小的packet。稱作Packetized Elementary Stream (Video PES, Audio PES)。
這 些PES,經由Multiplexer混在一起,成為單一的stream,就是Transport Stream (TS)。並且加上Information Packet (Table),例如EPG (Electronic Program Guide),PSI (Program Specific Information),SI (Service Informaion)再裡面,這些額外的資訊是提工接收端的demux將TS中的ES解出來用的。
一個TS並沒有規定只能包含多少節目,depends on 用來傳輸TS的頻寬(bandwidth)。
台灣的band width是6MHz,所以一個TS可以包含三個SDTV 節目。
ref中有一張圖(圖四)。是很好的說明。
一個TS可用的bandwidth是4Mbps ~ 7Mbps。內含
找到TS中的同步byte 0x47
找到PSI的PAT, PAT中有所有PMT的PID,利用這個PID找到PMT,一個program有一個PMT。
經由PMT找到PES的PID。利用PID挑出TS中所需要觀看的Video/Audio PES。
挑出需要的PES後,開始Decode,decode時要參考Stream中的clock information : PCR, PTS和PES中的DTS(Decode Time Stamps)。
upsdn的這一篇有進一步的說明 :
TS的一個packet有188 bytes,分為head 和load。
Head 內含Synch byte,PID
Synch Byte(0x47)代表Packet的開頭
PID 代表這一個TS packet的內容類別。
Load 部份就是資料的實際內容。
解碼的動作就是先找到PAT 的packet,PAT封包的PID固定是0x00。
PAT 封包的內容(load)是每個program 的PMT 的PID。以下是一個PAT封包的例子:
之後的就是各個program的PMT所在packet的PID。可以看到第20個program的PMT在PID=200的TS pocket中。
Decoder接著去找PID=200的TS pocket,其中包含的是program 20的節目內容,如:
Decoder知道Video, Audio 的PID後,就可以將收到的TS pocket,取出PID =500的部份,丟到Video decoder中,將PID=510的pocket丟到Audio decoder中。
Hardware support ,上一篇的內容會說到hardware support decoding的動作。
利用一個內建的lookup table,和TS pocket hardware分段的動作,解出PID。
並且利用look up table決定這個pid要處理的方式(送到Video, Audio decoder或是丟棄)。
PID=0,解出,更新look up table的Video,Audio PID。
PID=? 經果lookup table篩選出需要的PID,送到解壓縮模組。
這一頁是英文的說明,附TS pocket的圖解,和MPEG2 stream的部份。
ISO 文件要錢,這裡 有ISO 13818-1文件(pdf)可以下載。這一篇文件就是說明這些協定的實際格式。
當初google pmt pat 沒有很多資料,原來要google : pmt pat decode。
這樣資料就很多。
ES : Elementary Stream - 經過壓縮後的節目內容Audio ES,Video ES。
PES : Packetized Elememtary Stream,將ES由一個連續的stream分成一個一個packet後的packet。
TS : Transport Stream - 實際傳輸的Stream。由一連串的TS packet組成。
PID : TS Packet 中,用來代表這一個Packet 的資料ID的欄位。
Synch : TS Stream中用來代表TS Packet開頭的byte
PAT : Program Associate Table
PMT : Program Mapping Table
eedesign的這一篇有很好的概論,說明MPEG TS (Transport Stream)。
一般的攝影裝置,輸出都是BT601(270Mbps)。
利用ISO/IEC13818 作Video Coding,壓縮到3~5Mbps。
壓縮後的Video, Audio 資料都是Elementary Stream(Video ES, Audio ES)。
ES被切割成很多小小的packet。稱作Packetized Elementary Stream (Video PES, Audio PES)。
這 些PES,經由Multiplexer混在一起,成為單一的stream,就是Transport Stream (TS)。並且加上Information Packet (Table),例如EPG (Electronic Program Guide),PSI (Program Specific Information),SI (Service Informaion)再裡面,這些額外的資訊是提工接收端的demux將TS中的ES解出來用的。
一個TS並沒有規定只能包含多少節目,depends on 用來傳輸TS的頻寬(bandwidth)。
台灣的band width是6MHz,所以一個TS可以包含三個SDTV 節目。
ref中有一張圖(圖四)。是很好的說明。
-----
Video PES-->| |
Audio PES-->| mux |------ TS1..------------
Data PES--->| | |
PSI ------->| | | ----
------ -----| |
/|\ PCR(Program Clock TS2..--| |==>
| Reference ) TS3..--| | DVB
STC | |
(System Timer Clock) ----
一個TS可用的bandwidth是4Mbps ~ 7Mbps。內含
Video : 2~6Mbps目前DVB-C/S/T的bandwidh是
Audio : 32 ~ 384kbps
Data : -- depends--
PSI/SI : 0~1Mbps
Cable : 38.153MbpsDecoder的動作,ref 的圖五是很好的說明
Satelite : 38.015Mbps
Terrestrial : 4.98~31.67Mbps
找到TS中的同步byte 0x47
找到PSI的PAT, PAT中有所有PMT的PID,利用這個PID找到PMT,一個program有一個PMT。
經由PMT找到PES的PID。利用PID挑出TS中所需要觀看的Video/Audio PES。
挑出需要的PES後,開始Decode,decode時要參考Stream中的clock information : PCR, PTS和PES中的DTS(Decode Time Stamps)。
upsdn的這一篇有進一步的說明 :
TS的一個packet有188 bytes,分為head 和load。
Head 內含Synch byte,PID
Synch Byte(0x47)代表Packet的開頭
PID 代表這一個TS packet的內容類別。
Load 部份就是資料的實際內容。
解碼的動作就是先找到PAT 的packet,PAT封包的PID固定是0x00。
PAT 封包的內容(load)是每個program 的PMT 的PID。以下是一個PAT封包的例子:
Program index, PID其中program 0固定是NIT (Network Information Table)。從上面的例子看,NIC在PID=122的TS Packet中。
0 122
1 60
,, ,,
20 200
之後的就是各個program的PMT所在packet的PID。可以看到第20個program的PMT在PID=200的TS pocket中。
Decoder接著去找PID=200的TS pocket,其中包含的是program 20的節目內容,如:
PES , PID這個例子說明節目20,內涵一個Video 資料,在PID=200的TS pocket中,有兩個語音信號(雙語音),各在PID 510, 512的TS pocket中。
Video 500
Audio 510
Audio2 512
PCR 500
....
Private 540
Decoder知道Video, Audio 的PID後,就可以將收到的TS pocket,取出PID =500的部份,丟到Video decoder中,將PID=510的pocket丟到Audio decoder中。
Hardware support ,上一篇的內容會說到hardware support decoding的動作。
利用一個內建的lookup table,和TS pocket hardware分段的動作,解出PID。
並且利用look up table決定這個pid要處理的方式(送到Video, Audio decoder或是丟棄)。
PID=0,解出,更新look up table的Video,Audio PID。
PID=? 經果lookup table篩選出需要的PID,送到解壓縮模組。
這一頁是英文的說明,附TS pocket的圖解,和MPEG2 stream的部份。
ISO 文件要錢,這裡 有ISO 13818-1文件(pdf)可以下載。這一篇文件就是說明這些協定的實際格式。
當初google pmt pat 沒有很多資料,原來要google : pmt pat decode。
這樣資料就很多。
- 這個 http://www.tvtechnology.com/ 是TV 相關的網站,還有雜誌,好像是free的喔。
- dvbsnoop http://dvbsnoop.sourceforge.net/ linux的application,使用dvb api (2.6 kernel 內建)。用來解析TS 的pid, pmt 資訊,還可以將TS stream 解出binary file 存成file。
- 這一篇 http://www.techonline.com/community/ed_resource/feature_article/14706 是DVB Primer
- http://www.dvb.org/ 看名字就知道,是有關DVB的org。
- http://www.linuxtv.org/ 是一個在linux上看TV的project。
台灣的數位電視頻道,ChannelSpace是6MHz ?
DvbT不都是8MHz的嗎?
用廠商的sample program怎麼樣都無法播放。
但是3rd party的demo program竟然可以。
感謝Linux的open structure,用3rd party的program tune好後, suspend。
用sample program的player部份play是OK。
所以專注在tuner部份。
雖然Demo program的document真的少,又像猜謎一樣。
但是一個一個try,還是可以暸解是甚麼用途。
==<所以把Tuner的status print 出來...... ??? NoCarrier !!!!
真是高興呀。
再度感謝3rd party software rd有print msg的態度,和Linux platform的open structure。
從run time log中對照SDK的setting properties,一個一個的照著Set。
結果?
==>竟然是Channel Spacing !!
我本以為這是最無關的,大概是在甚麼Fft, Hierarchy,,,,的。
竟然。
所以設好後,Status就是Carrier OK------雖然有些Signel Strength是負值。
所以一個一個,照著 這個網站的表格tune一下各個頻道,結果:
用廠商的sample program怎麼樣都無法播放。
但是3rd party的demo program竟然可以。
感謝Linux的open structure,用3rd party的program tune好後, suspend。
用sample program的player部份play是OK。
所以專注在tuner部份。
雖然Demo program的document真的少,又像猜謎一樣。
但是一個一個try,還是可以暸解是甚麼用途。
==<所以把Tuner的status print 出來...... ??? NoCarrier !!!!
真是高興呀。
再度感謝3rd party software rd有print msg的態度,和Linux platform的open structure。
從run time log中對照SDK的setting properties,一個一個的照著Set。
結果?
==>竟然是Channel Spacing !!
我本以為這是最無關的,大概是在甚麼Fft, Hierarchy,,,,的。
竟然。
所以設好後,Status就是Carrier OK------雖然有些Signel Strength是負值。
所以一個一個,照著 這個網站的表格tune一下各個頻道,結果:
...很蠢的是,從網站的表格可以看出,channel spacing真的是6MHz。
533 : CTV (-1)
545 : 公視
557 : 民視(-8)
581 : 台視(-4)
593 : 華視(-12)
星期四, 12月 22, 2005
NFS ROOT : Linux , 使用NFS 作為rootfs
在kernel source的Document中就有一篇nfsroot.txt。照著裡面作就可以。
因為nfsroot是要mount nfs 上的path作為root,所以在此之前,他的root filesystem是不存在的。
所以nfs file system support 要build in在kernel中,不可以用 Module (.0)的方式(因為,.o 要放在那?)。
當然,網路 driver 也要內建(例如,你用rtl8192too,就要選 '*',不可以選'M')。
kernel 有mount nfs的能力後,接著就要"通知"kenel 是要用nfs 作為rootfs,並且要到那裡去mount nfs。這要靠kernel command line來完成:
告訴kernel 使用nfs作為rootfs,server path = /nfsroot:
nfs server=10.3.5.166
gw=10.3.4.254
netmask=255.255.252.0
hostname=""
使用eth0
不使用autoconfig來取的ip
rebuild kernel, config bootloader,用這個kernel boot。
以 這個embedd system來說,他的bootloader內建romfs filesystem,會在flash中找romfs signature,並且找到romfs中的linux.bin.gz來開機,所以就要把build好的kernel.bin壓縮後,再用 genromfs 產生一個裡面只有linux.bin.gz這個檔案的romfs image,燒在flash中。讓bootloader能用這個linux image來開機。
接著就是server端,要準備好rootfs(可以使用genext2fs)。
修改nfs server的exports file
就可以看到client以NFS 作為 rootfs 開機成功了。
所以重點只有...
設定好kernel參數,裝備好需要的driver。
讓kernel開機。
一切就OK了。
NFS export出去的folder也可以用symbolic link
但 是要注意每次變更link後要重新啟動nfs-kernel-server才行。
我以前總覺得疑惑,mount root的動作有點雞生蛋,蛋生雞的感覺。因為/dev 是在 root 下,但是 root都還沒起來,kernel又怎麼去找 root 的 /dev 來mount 呢?
看 了init 的source code 才知道,init 的do_mounts( )裡面已經建好了 device name 對 device major/minor number的table,不需要由/dev去找。所以在/dev還沒建立好以前,kernel已經可以知道device的major/minor number是甚麼了。
知道major/minor number後,就可以到driver table中找到正確的device driver 了。
一個問題:
exports:
這樣使用nfsroot開機的機器(10.3.5.123)要mount /home/charles/sgm時會出現error :
另一個
從configure和Makefie看來,使用nfs 作為roorfs,只有kernel boot command 有關。
(當然,kernel要build nfs file system和network driver)
因為nfsroot是要mount nfs 上的path作為root,所以在此之前,他的root filesystem是不存在的。
所以nfs file system support 要build in在kernel中,不可以用 Module (.0)的方式(因為,.o 要放在那?)。
當然,網路 driver 也要內建(例如,你用rtl8192too,就要選 '*',不可以選'M')。
kernel 有mount nfs的能力後,接著就要"通知"kenel 是要用nfs 作為rootfs,並且要到那裡去mount nfs。這要靠kernel command line來完成:
告訴kernel 使用nfs作為rootfs,server path = /nfsroot:
root=/dev/nfs設定nfs server address和path:
nfsroot=10.3.5.166:/nfsroot設定client的 ip=10.3.5.123
nfs server=10.3.5.166
gw=10.3.4.254
netmask=255.255.252.0
hostname=""
使用eth0
不使用autoconfig來取的ip
ip=10.3.5.123:10.3.5.166:10.3.4.254:255.255.252.0::eth0:off這樣kernel 的動作就算ok了。
rebuild kernel, config bootloader,用這個kernel boot。
以 這個embedd system來說,他的bootloader內建romfs filesystem,會在flash中找romfs signature,並且找到romfs中的linux.bin.gz來開機,所以就要把build好的kernel.bin壓縮後,再用 genromfs 產生一個裡面只有linux.bin.gz這個檔案的romfs image,燒在flash中。讓bootloader能用這個linux image來開機。
接著就是server端,要準備好rootfs(可以使用genext2fs)。
修改nfs server的exports file
10.3.5.123 /nfsroot(rw)重新啟動nfs server:
#/etc/init.d/nfs-kernel-server resartOK,現在可以叫client 開機。
就可以看到client以NFS 作為 rootfs 開機成功了。
所以重點只有...
設定好kernel參數,裝備好需要的driver。
讓kernel開機。
一切就OK了。
NFS export出去的folder也可以用symbolic link
# ln -s /nfsroot /home/develop/release1這樣就可以輕易的讓linux使用不同的rootfs。
或是
# ln -s /nfsroot /home/develop/test
但 是要注意每次變更link後要重新啟動nfs-kernel-server才行。
我以前總覺得疑惑,mount root的動作有點雞生蛋,蛋生雞的感覺。因為/dev 是在 root 下,但是 root都還沒起來,kernel又怎麼去找 root 的 /dev 來mount 呢?
看 了init 的source code 才知道,init 的do_mounts( )裡面已經建好了 device name 對 device major/minor number的table,不需要由/dev去找。所以在/dev還沒建立好以前,kernel已經可以知道device的major/minor number是甚麼了。
知道major/minor number後,就可以到driver table中找到正確的device driver 了。
一個問題:
exports:
/nfsroot 10.3.5.123(rw)但是
/home/charles/sgm 10.3.5.123(rw)
nfsroot--> /home/charles/sgm/root也就是說 nfsroot實際是另一個export path的sub folder。
這樣使用nfsroot開機的機器(10.3.5.123)要mount /home/charles/sgm時會出現error :
mount: nfs warning: mount version newer than kernel...雖然從fail message中看不出原因是這個...
NFS: mount program didn't pass remote address!
failed, reason given by server: Permission denied
mount: nfsmount failed: Bad file descriptor
mount: Mounting 10.3.5.166:/home/charles/sigma on /tmp/sigma failed: Invalid arg
ument
另一個
從configure和Makefie看來,使用nfs 作為roorfs,只有kernel boot command 有關。
(當然,kernel要build nfs file system和network driver)
Memo : 紀錄一下能作的事..
- fb + QT embedded
- NFS root OK
- 用direct register read/write 看associate memory 和 parallel spi 的動作
- 用microwin + ir 寫file manager
- usb flash driver OK
- try UART1 GPIO 為什麼不能動
from tuner 的 sample application 開始。
一個一個試....
(document 實在是太少了呀....) OK - 原來是ChannelSpacing 的關係,應該要是6MHz(default是8MHz)。
切換每個PAT中的PMT。
另一個web base 的msn - e-messenger
好像功能比microsoft的web base msn 還多,
但是在不知名的網站中輸入password,總是有點毛毛的。
不曉得突破firewall 的能力有沒有比較強。
但是在不知名的網站中輸入password,總是有點毛毛的。
不曉得突破firewall 的能力有沒有比較強。
星期一, 12月 19, 2005
Linux : Enable USB device - Mass Storage.
USB device filesystem 有點像/proc filesystem。是在runtime create。
Kernel Config中,Preliminary USB Device Filesystem 要Enable。
linux啟動後,用mount 指令來create usb device filesystem:
Mass Storage Devices .....
順便紀錄一下,今天 ..
microwindow 測試OK,可以正常工作。
IR remote 測試OK,
usb 測試,因為板子上好像有一個transformer沒焊,所以....
Kernel Config中,Preliminary USB Device Filesystem 要Enable。
linux啟動後,用mount 指令來create usb device filesystem:
#mount -t usbdevfs none /proc/bus/usb這樣/proc/bud下就會出usb 這一個folder,裡面會有devices,drivers兩個檔案。
none 只是為了顯示用,有些人為了好看,會用usbfs 代替
Mass Storage Devices .....
順便紀錄一下,今天 ..
microwindow 測試OK,可以正常工作。
IR remote 測試OK,
usb 測試,因為板子上好像有一個transformer沒焊,所以....
星期五, 12月 16, 2005
uclinux : 再找一次,Kernel command line: 的地方
想知道Kernel 怎麼依照boot argument 去找root file system,其實是想要再試試 root NFS。
boot message 有一行:
因為是lds - link script,所以找Makefile ,看看最後的link command.....
Linux 分成boot, init 和 ? N 大塊target。最後link起來成為linux kernel。
Makefile 最後將這部份產生System.map 這個map file,所以查查這個map file 裡面的symbol table,是不是有__setup_start,__setup_end這兩個mark...
在include/linux/int.h 中定義了..
init/main.c 就可以用:
所以我要找的應該是"root="字串,function是 root_dev_setup ---- name_to_kdev_t ,
使用root_dev_names[],裡面第一項就是"nfs",也就是說boot argument 是"root=/dev/nfs"
查這個name_to_kdev_t function就是要找到boot device的device number。
交給root_dev_setup設定給ROOT_DEV這個變數。
這樣查code發現,經過linker 作安排的code,要trace比較不容易。但是很多code好像都是這樣,像LinuxBIOS的init function也是。用function array的方式,一個一個call。
這樣的方法有一個問題是,array中的function 不可以有依賴關係。也就是 先後次序。因為用loader script 沒法安排啟動的順序。
boot message 有一行:
Kernel command line : root=/dev/blkmem/0所以先找到"Kernel command line" 這一行是從那裡出來的,因為是boot messsage,所以從init 開始找:
$ cd init結果告訴我是main.c,less main.c 用 " /Kernel command" 找到..
$ grep "Kernel command line" *.c
setup_arch(&command_line);command_line 是local variable。所以取得位置是在setup_arch(),找..一個一個目錄的找..
printk("Kernel command line: %s\n", saved_command_line);
$ grep setup_arch arch -r出現真的在arch 目錄。到arch/arm
$ grep setup_arch * -r原 來是在kernel/setup.c.. parse_cmdline( )把meminfo 的資料處理後,交給cmdline_p,parse_cmdline 處理boot argument的 "mem="和"initrd=" 兩個argument。所以setup_arch只是將boot argument 從public static variable中取出,交給這個cmdline_p,並且處了他需要知道的幾個boot argument。
include/linux/init.h: extern struct kernel_parm__setup_start, __setup_end;然後在
arch/armnommu/vmlinux-arm0.lds.in: __setup_start = .;和vmlinux.lds , vmlinux-armv.lds.in 也有。 所以應該又是用類似boot loader一樣,在link時將init argument -- init function pair locate 在image特定位置。
因為是lds - link script,所以找Makefile ,看看最後的link command.....
Linux 分成boot, init 和 ? N 大塊target。最後link起來成為linux kernel。
Makefile 最後將這部份產生System.map 這個map file,所以查查這個map file 裡面的symbol table,是不是有__setup_start,__setup_end這兩個mark...
900a2300 ? __setup_start果 然有,找一下__setup_root_dev_setup 這一個symbol : 在init/do_mounts.c,要用root_dev_setup 來找,因為__setup_ 開頭字樣是在所有function 宣告完後,用__setup ( )macro重新安排過,產生一個kernel_param 的structure 資料,放在 .setup.init 節區。
900a2308 ? __setup_debug_kernel
900a2310 ? __setup_quiet_kernel
900a2318 ? __setup_load_ramdisk
900a2320 ? __setup_readonly
900a2328 ? __setup_readwrite
900a2330 ? __setup_root_dev_setup
900a2338 ? __setup_root_data_setup
900a2340 ? __setup_fs_names_setup
900a2348 ? __setup_nohlt_setup
900a2350 ? __setup_hlt_setup
900a2358 ? __setup_reboot_setup
.......
900a23e0 ? __setup_netdev_boot_setup
900a23e8 ? __setup_netdev_boot_setup
900a23f0 ? __initcall_alignment_init
900a23f0 ? __initcall_start
900a23f0 ? __setup_end
在include/linux/int.h 中定義了..
#define __setup(str, fn) static char __setup_str_##fn[] __initdata = str; static struct kernel_param __setup_##fn __attribute__((unused)) __initsetup = { __setup_str_##fn, fn }這樣的定義,配合do_mounts.c中的..
.....
#define __initsetup __attribute__ ((unused,__section__ (".setup.init")))
static int __init root_dev_setup(char *line)將root_dev_setup function和"root=" 字串放在 .setup.init 節區。這樣,所有boot argument 字串和setup function,自動就會形成一個array,排列在__setup_start, __setup_end 之間。
{
int i;
char ch;
ROOT_DEV = name_to_kdev_t(line);
memset (root_device_name, 0, sizeof root_device_name);
if (strncmp (line, "/dev/", 5) == 0) line += 5;
for (i = 0; i < sizeof root_device_name - 1; ++i)
{
ch = line[i];
if ( isspace (ch) || (ch == ',') || (ch == '\0') ) break;
root_device_name[i] = ch;
}
return 1;
}
__setup("root=", root_dev_setup);
init/main.c 就可以用:
static int __init checksetup(char *line)一一check boot command字串內容是否有符合,call 對應的function。
{
struct kernel_param *p;
p = &__setup_start;
do {
int n = strlen(p->str);
if (!strncmp(line,p->str,n)) {
if (p->setup_func(line+n))
return 1;
}
p++;
} while (p < &__setup_end);
return 0;
}
所以我要找的應該是"root="字串,function是 root_dev_setup ---- name_to_kdev_t ,
使用root_dev_names[],裡面第一項就是"nfs",也就是說boot argument 是"root=/dev/nfs"
查這個name_to_kdev_t function就是要找到boot device的device number。
交給root_dev_setup設定給ROOT_DEV這個變數。
這樣查code發現,經過linker 作安排的code,要trace比較不容易。但是很多code好像都是這樣,像LinuxBIOS的init function也是。用function array的方式,一個一個call。
這樣的方法有一個問題是,array中的function 不可以有依賴關係。也就是 先後次序。因為用loader script 沒法安排啟動的順序。
星期四, 12月 15, 2005
GEM318 : Guardian Enclosure Manager Controller
GEM318 是SCSI 介面的 SAF-TE controller。支援
有I2C interface 作master或slave用。
當master時,GEM318可以讀取I2C的週邊,如LM75,EEPROM。
當slave用時,host/master可以經由這個介面讀取GEM318偵測的資料。
有I2C interface 作master或slave用。
當master時,GEM318可以讀取I2C的週邊,如LM75,EEPROM。
當slave用時,host/master可以經由這個介面讀取GEM318偵測的資料。
解決問題的log : romfs signature 與romfs auto probe..
環境:loader + linux kernel in ROMFS.
flash 中:
bootloader : 在flash的特定區域找romfs 的開頭字串(signature),loader內涵romfs filesystem,找到romfs 中的linux image。
Linux boot後,從boot argument中知道是從/dev/blkmem0中找rootfs。(blkmem driver內建flash的address map),所以kernel 啟動後也一樣在flash 中找romfs 的signature,,但是bootloader知道romfs真的起始位置(因為romfs也是他燒進flash的)。linux kernel 就不知道,所以他是從flash的開始位置開始找.......
這樣就有問題了: 如果我在bootloader內含一個romfs signature字串?
如果loader的code image真的很巧的包含一個romfs signature ?
linux kernel就會搞錯了。
以下就是這個問題:
因為在bootloader中enable network功能,所以size增加了,0x10000不夠,所以我重新規劃
這就是上一次燒錄的romfs 起始位置,
<STAGE2是空的>
因為bootloader在燒錄loader自己和ROMFS時,只有erase需要的部份。所以才造成這個"殘留"問題。
--- 後來手動(在loader中enable all function,增加了erase arbitrary region)erase 了46030000 - 4603FFFF這一個sector後,就正常boot 了。
flash 中:
46000000 LOADERROMFS 中有linux kernel image (gzipped),這個bootloader是將kernel image 放在romfs中,bootloader要"認識"romfs,所以可以在romfs中找到linux image,把他解開。放到ram中,執行。
46010000 STAGE2
46030000 ROMFS
bootloader : 在flash的特定區域找romfs 的開頭字串(signature),loader內涵romfs filesystem,找到romfs 中的linux image。
Linux boot後,從boot argument中知道是從/dev/blkmem0中找rootfs。(blkmem driver內建flash的address map),所以kernel 啟動後也一樣在flash 中找romfs 的signature,,但是bootloader知道romfs真的起始位置(因為romfs也是他燒進flash的)。linux kernel 就不知道,所以他是從flash的開始位置開始找.......
這樣就有問題了: 如果我在bootloader內含一個romfs signature字串?
如果loader的code image真的很巧的包含一個romfs signature ?
linux kernel就會搞錯了。
以下就是這個問題:
因為在bootloader中enable network功能,所以size增加了,0x10000不夠,所以我重新規劃
46000000 LOADERbootloader boot OK。但是kernel boot時卻找錯romfs...他認為romfs在46030000....
46020000 STAGE2
46040000 ROMFS
這就是上一次燒錄的romfs 起始位置,
<STAGE2是空的>
因為bootloader在燒錄loader自己和ROMFS時,只有erase需要的部份。所以才造成這個"殘留"問題。
--- 後來手動(在loader中enable all function,增加了erase arbitrary region)erase 了46030000 - 4603FFFF這一個sector後,就正常boot 了。
Debian : Install tftp server - tftpd
tftp 是一個很簡單的file transfer protocol,他使用udp,並且沒有很多handshaking,authorization的機制,Client 所需要的code比較檢單,所以常常用在許多resource limited 的embedded system 中,或是用在開機的時候。
因為tftp 不是一個常常會使用的服務,所以以standalone dameon的方式執行會一直站住記憶體,所以建議使用inetd的方式來安裝。
tftpd 的default安裝方式也是這樣(tftpd好像沒有辦法用daemon的方式安裝)
測 試,測試要安裝tftp (client)
---實際上client這一端我沒測試。
因為tftp 不是一個常常會使用的服務,所以以standalone dameon的方式執行會一直站住記憶體,所以建議使用inetd的方式來安裝。
tftpd 的default安裝方式也是這樣(tftpd好像沒有辦法用daemon的方式安裝)
#aptitude install tftpd安裝完後,/etc/inetd.conf 檔會有一行是tftpd的invoke 命令。最後一個argument是tftp 的export 目錄。debian default是 /boot,一般是用/tftpboot,所以要修改一下:
tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /tftpboot之後要reload inetd:# /etc/init.d/inetd reload這樣就OK了。
測 試,測試要安裝tftp (client)
#aptitude install tftp將一些file放到/tftpboot中測試傳送,client已經可以開始連線:
$tftp 10.3.7.xxxOK
tftp>get xxxxxxx
---實際上client這一端我沒測試。
星期二, 12月 13, 2005
領導人? Solution
從電子時報看到這次商周,對紐約人壽董事長的訪談中,他的回答..
(我本來想寫 "有效的改進作法",後來想想,好像連"沒效的改進作法"也沒聽過..)
領導人都在抱怨的話,下面的人不就要去死了?
你可以說我不喜歡這樣的數字,這樣的數字不好看,獲利應該成長多一些,但這不是有效的管理,有效的管理是指,跟你的經理人說,我不喜歡這數字,但有三、四種做法可以改變這數字。哇,天哪,你有遇過那一個領導者真的能給你 改進的作法?
領導者的責任不只是指出問題,還要跟員工一起合作解決問題。你不能只把球丟給其他人,站在一旁抱怨。
(我本來想寫 "有效的改進作法",後來想想,好像連"沒效的改進作法"也沒聽過..)
領導人都在抱怨的話,下面的人不就要去死了?
USB to Serial adaptor : Linux driver
想要在Linux 上使用USB轉RS232的cable。Google一下,發現kernel已經支援很多chip了。在
查ATEN USB的chip好像是prolific的pl2303。在driver folder下的pl2303.c。
所以 應該 有支援。
driver/usb/serial目錄下。
查ATEN USB的chip好像是prolific的pl2303。在driver folder下的pl2303.c。
所以 應該 有支援。
星期日, 12月 11, 2005
星期五, 12月 09, 2005
又到日月潭....
上次因為龍王颱風,沒住成,只好再去一次。
這次一樣先到豐原買牛丫糖。就是這一家:
然後就出發往鹿港去....先到 龍山寺...
果然是古老的建築,可能是快不行了,所以開始整修..
但是還是可以進去...
廁所也一樣有開放:
龍山寺有導覽,上面寫...該到摸乳巷去看看....這個擠滿排隊的人的地方,就是摸乳巷了
真的是很窄,而且中間一段更窄,
這是旁邊正在蓋得利停車場,這樣就不用到處找停車的地方..
繼續往前走,有一家店擠了很多人..
原來是玉珍齋...有賣很多糕餅類的東西..
下一個點,就是"隘門"..
一路上,都是奇怪的商店,
大家都往這裡去...鹿港天后宮的牌樓..
進去後,原來是小吃的聚集地。
路底就是媽祖廟
果然也是歷史悠久..
還有一個專門解說的阿伯...
....其實他只是遊客...
裡面還有鹿港故時候的地圖....當然,每次有甚麼照相的景點,就一定會有一個大頭,待在那兒不肯走....
古色古香的媽祖廟,廁所可是很現代化的喔...
鹿港的騎樓有統一規劃,地板上都會有一個圖樣..
這樣,鹿港的行程就結束了...接著,往集集去,因為要買梅子...
以往免費停車的好地點,被拿來當競選總部,所以沒的停了..
買完梅子,,,這是集集車站的廁所。
車站外,有一群黑衣人在辦音樂會...
所以小火車雕像變成這樣...
然後,,,,就到飯店了,到的時候已經是晚上了..
房間挺不錯的,
每個房間都有面湖的小陽台..
第二天,遊湖,一人200,先到玄光寺..
路半路上的小狗
路上可以看到待會要去的拉魯島
這就是玄光寺
這是玄光寺的....?
這個...就是Stanley一直不肯承認進去住過的飯店...
這一家人,要提的是那個小弟弟...到拉魯島要下船時,小弟很臭屁的說: 爸爸不要扶我,我自己會下...結果,在眾人的面前,小弟弟用力一跳,本以為很帥氣,結果.....鞋子掉了,掉到船下Q_Q......
船長還說: 小弟弟,日月潭的魚不吃鞋子喔....
這...小弟長大會有陰影吧。從此失去自信。好可憐。
拉魯島逛完後就回到德化社。
接著就是往慈恩塔,,,,570 公尺的階梯。
這個是慈恩塔...
有幾層?
這是可以爬上去的
從塔頂可以看到日月潭的全景
運氣好(?)還會看到想不開的老外..
他是想要到...這裡嗎?
其實還是蠻美麗的..
慈恩塔繼續往下走,就是常常在日曆看到的...文武廟.
因為921的關係,到處都是煥然一新....
也有像日本的廟宇一樣,買個風鈴(?),寫下心願,掛在妙的屋簷下..
因為到處都在整修..所以只好回家..經過清水休息站..看看現在魚缸養的是? 又換了。汰換率真高.
這次一樣先到豐原買牛丫糖。就是這一家:
然後就出發往鹿港去....先到 龍山寺...
果然是古老的建築,可能是快不行了,所以開始整修..
但是還是可以進去...
廁所也一樣有開放:
龍山寺有導覽,上面寫...該到摸乳巷去看看....這個擠滿排隊的人的地方,就是摸乳巷了
真的是很窄,而且中間一段更窄,
這是旁邊正在蓋得利停車場,這樣就不用到處找停車的地方..
繼續往前走,有一家店擠了很多人..
原來是玉珍齋...有賣很多糕餅類的東西..
下一個點,就是"隘門"..
一路上,都是奇怪的商店,
大家都往這裡去...鹿港天后宮的牌樓..
進去後,原來是小吃的聚集地。
路底就是媽祖廟
果然也是歷史悠久..
還有一個專門解說的阿伯...
....其實他只是遊客...
裡面還有鹿港故時候的地圖....當然,每次有甚麼照相的景點,就一定會有一個大頭,待在那兒不肯走....
古色古香的媽祖廟,廁所可是很現代化的喔...
鹿港的騎樓有統一規劃,地板上都會有一個圖樣..
這樣,鹿港的行程就結束了...接著,往集集去,因為要買梅子...
以往免費停車的好地點,被拿來當競選總部,所以沒的停了..
買完梅子,,,這是集集車站的廁所。
車站外,有一群黑衣人在辦音樂會...
所以小火車雕像變成這樣...
然後,,,,就到飯店了,到的時候已經是晚上了..
房間挺不錯的,
每個房間都有面湖的小陽台..
第二天,遊湖,一人200,先到玄光寺..
路半路上的小狗
路上可以看到待會要去的拉魯島
這就是玄光寺
這是玄光寺的....?
這個...就是Stanley一直不肯承認進去住過的飯店...
這一家人,要提的是那個小弟弟...到拉魯島要下船時,小弟很臭屁的說: 爸爸不要扶我,我自己會下...結果,在眾人的面前,小弟弟用力一跳,本以為很帥氣,結果.....鞋子掉了,掉到船下Q_Q......
船長還說: 小弟弟,日月潭的魚不吃鞋子喔....
這...小弟長大會有陰影吧。從此失去自信。好可憐。
拉魯島逛完後就回到德化社。
接著就是往慈恩塔,,,,570 公尺的階梯。
這個是慈恩塔...
有幾層?
這是可以爬上去的
從塔頂可以看到日月潭的全景
運氣好(?)還會看到想不開的老外..
他是想要到...這裡嗎?
其實還是蠻美麗的..
慈恩塔繼續往下走,就是常常在日曆看到的...文武廟.
因為921的關係,到處都是煥然一新....
也有像日本的廟宇一樣,買個風鈴(?),寫下心願,掛在妙的屋簷下..
因為到處都在整修..所以只好回家..經過清水休息站..看看現在魚缸養的是? 又換了。汰換率真高.
訂閱:
文章 (Atom)
網誌存檔
-
▼
2005
(620)
-
▼
12月
(30)
- 有趣的作法
- C 的隱藏structure
- C 的printf debug output , 使用 __FILE__和__LINE__
- Copy 部份的binary 檔出來 -- 或說是 砍掉檔案的某一部份
- PAT, PMT in MPEG2 Stream :筆記
- 台灣的數位電視頻道,ChannelSpace是6MHz ?
- NFS ROOT : Linux , 使用NFS 作為rootfs
- Memo : 紀錄一下能作的事..
- 另一個web base 的msn - e-messenger
- Linux : Enable USB device - Mass Storage.
- uclinux : 再找一次,Kernel command line: 的地方
- GEM318 : Guardian Enclosure Manager Controller
- 解決問題的log : romfs signature 與romfs auto probe..
- Debian : Install tftp server - tftpd
- 領導人? Solution
- USB to Serial adaptor : Linux driver
- 歷史的作用
- 又到日月潭....
- TV Card 相關資料
- 基準電子 : NAS solution..
- Freevo : 除了MythTV外,另一個Linux Media Center package
- Amazing !!! 人形機器人格鬥戰.. ROBO-ONE
- SAF-TE : SCSI Access Fault-Tolerant Encolsure Inte...
- 建立新事業: 本期天下雜誌 - 成長的賭局
- 愚蠢的規定
- Linux的eMule : aMule
- google一下候選人...
- 好笑的
- Mobile Phone Test function, equipement
- Intersil RTC : X1205
-
▼
12月
(30)