/***************************************
主編號與次編號major與minor
***************************************/
dev_t型態 定義在<linux/types.h>
這三個定義在<linux/kdev_t.h>
MAJOR(dev_t dev);
MINOR(dev_t dev);
MKDEV(int major , int minor);
//取得&釋放裝置編號2.6版
<linux/fs.h> 定義的
//給定主編號
1.int register_chrdev_region(dev_t first , unsigned int count , char *name);
ex: register_chrdev_region( MKDEV(major,minor) , 1 , "char_reg" );
第一個參數:要配置的裝置號碼 (次編號通常是0)
第二個參數:申請連續裝置編號的總數
第三個參數:出現在/proc/devices與sysfs的名稱 (2.6以上 sysfs /sys/module/..)
回傳值: 0表示成功 負值表示失敗
//自動給主編號
2.int alloc_chrdev_region(dev_t *dev , unsigned int firstminor , unsigned int count , char *name);
ex: alloc_chrdev_region( &dnoev , 0 , 1 , "char_reg" );
第一個參數:僅供輸出的參數,當配置成功,此參數持有配置的裝備編號
第二個參數:你想申請的第一個次編號 (通常是0)
第三個參數:申請連續裝置編號的總數
第四個參數:出現在/proc/devices與sysfs的名稱 (2.6以上 sysfs /sys/module/..)
回傳值: 0表示成功 負值表示失敗
//釋放裝置編號
3.void unregister_chrdev_region(dev_t first , unsigned int count);
ex: unregister_chrdev_region( MKDEV(major,minor) , 1 );
第一個參數:配置的裝置號碼 (次編號通常是0)
第二個參數:申請連續裝置編號的總數
//取得&連結&釋放裝置編號2.4版
<linux/fs.h> 定義的
//取得裝置編號&連結
1.int register_chrdev(unsigned int major, const char *name , struct file_operations *fops );
ex: major=register_chrdev( 0 , "char_reg" , &fops );
第一個參數:為0時,給kernel自動分配; 其他值就是給定的主編號
第二個參數:出現在/proc/devices與sysfs的名稱 (2.6以上 sysfs /sys/module/..)
第三個參數:將裝置編號連結到驅動程式的作業功能,後面會說明
回傳值: 為major號碼 負值表示失敗
//釋放裝置編號
2.int unregister_chrdev(unsigned int major , const char *name );
ex: unregister_chrdev( major , "char_reg" );
第一個參數:主編號
第二個參數:出現在/proc/devices與sysfs的名稱 (2.6以上 sysfs /sys/module/..)
}
2009年2月24日 星期二
2009年2月22日 星期日
密技偷看initrd.gz 或.img 或ramdisk.gz
偷看initrd.gz 或.img 或ramdisk.gz
cp -af /boot/initrd-2.4.20-8.img .
mv initrd-2.4.20-8.img initrd.gz
gunzip initrd.gz
mkdir tmp
mount -o loop initrd tmp
--->tmp目錄下就是RH9的initrd內容
--->修改或參考
umount tmp
gzip initrd
mv initrd.gz initrd-2.4.20-8.img
cp -af /boot/initrd-2.4.20-8.img .
mv initrd-2.4.20-8.img initrd.gz
gunzip initrd.gz
mkdir tmp
mount -o loop initrd tmp
--->tmp目錄下就是RH9的initrd內容
--->修改或參考
umount tmp
gzip initrd
mv initrd.gz initrd-2.4.20-8.img
磁片版linux
磁片檔案結構
***************
MBR
ldlinux.sys
zImage
initrd.gz
syslinux.cfg
***************
過程
#mkdosfs /dev/fb0
#syslinux /dev/fb0 做出 MBR 和 ldlinux.sys
製作busybox
#tar zxfv busybox-1.1.3.tar.gz
#make menuconfig 改 .config
#make;make install
mkdir缺的檔案
/proc /dev /etc
打包 做出initrd.gz
( #mke2fs #dd if=/dev/ram9 of=initrd )
製作kernel
make menuconfig裡的ramdisk和initrd要啟動
改.config
make dep
make zImage 做出zImage
寫syslinux.cfg
開機讀ldlinux.sys後會讀syslinux.cfg
複製到磁片
design the new driver in make menuconfig
design the new driver
1.driver程式中的進入點和結束點要用以下寫法
int __init test_init(void) { }
void __exit test_exit(void) { }
module_init(test_init);
module_exit(test_exit);
2.Modify for menuconfig
Character Driver
– 2.4: kernel/drivers/char/Config.in
– 2.6: Kernel/drivers/char/Kconfig
/usr/src/linux-2.4.x /drivers/char/Config.in
tristate ‘My test module' CONFIG_HELLO
/usr/src/linux-2.6.x /drivers/char/Kconfig
config HELLO
tristate “My test module"
help
This is my test module
3.Add the New Item in the Makefile
Character Driver
– kernel/drivers/char/Makefile
/usr/src/linux-2.4.x /drivers/char/Makefile
obj-$(CONFIG_HELLO) += test.o
/usr/src/linux-2.6.x /drivers/char/Makefile
obj-$(CONFIG_HELLO) += test.o
2009年2月20日 星期五
編譯toolchain和kernel
1. 使用RH9的Kernel config build linux-2.4.20
2. 使用自訂的Kernel config build linux-2.4.20
進階 : 改Makefile init/main.c
3. build 自己的toolchain在過程中,試驗若只有C compiler 是否能build kernel
最終需build出i386-linux toolchain
3-0 clean /usr/local
3-1 kernel header file
3-2 binutils
3-3 gcc-temp ----->試驗build kernel
3-4 glibc
3-5 gcc-final
***中途若有出錯 回3-0
crosstool
adduser xxx
passwd xxx
用xxx登入
tar zxf crosstool-0.43.tar.gz
更改demo-i686.sh , gcc-3.2.3-glibc-2.2.5.dat , i386.dat
./demo-i686.sh
試圖下載gcc , glibc , binutils , kernel
可以先放在downloads
最終的tool /opt/crosstool
mkdir -p /opt/crosstool -p 沒有就創
chown xxx:xxx /opt/crosstool
完成後可加上PATH=$PATH:/opt
刪除kernel
make modules_install
/lib/modules/2.4.20-my
make install
/boot/vmlinux-2.4.20-my
/boot/system.map-2.4.20-my
/boot/initrd-2.4.20-my.img
修改/boot/grub/grub.conf
my-i386-linux-toolchain
/user/local
#rm -rf /usr/local
#mkdir /usr/local
crosstool-i386-linux-toolchain
/opt/crosstool
2009年2月13日 星期五
按鈕穩壓
void KeyScan(void)
{
KeyStatus = *((volatile unsigned char *)( 0x8000000 + 0xB00)) ; // read from the sw_key
if( KeyStatus != 0xFF ) // 按下按鍵
{
unpressed = 0;
if( KeyTemp != KeyStatus ) //按鍵值 是否同上次一樣
{
KeyTemp = KeyStatus; // 不一樣
pressed = 1;
}
else
{
pressed = pressed + 1; // 一樣 pressed 按下按鍵 的數量 +1
if( pressed == intKeyTot ) // 判斷 是否為 穩態 了 #define intKeyTot 1500
KeyData = KeyTemp; // 取 按鍵值
}
}
unpressed++;
if( unpressed == intKeyTot )
{
pressed = 0;
unpressed = 0;
KeyTemp = 0xff;
KeyData = 0xff;
}
}
{
KeyStatus = *((volatile unsigned char *)( 0x8000000 + 0xB00)) ; // read from the sw_key
if( KeyStatus != 0xFF ) // 按下按鍵
{
unpressed = 0;
if( KeyTemp != KeyStatus ) //按鍵值 是否同上次一樣
{
KeyTemp = KeyStatus; // 不一樣
pressed = 1;
}
else
{
pressed = pressed + 1; // 一樣 pressed 按下按鍵 的數量 +1
if( pressed == intKeyTot ) // 判斷 是否為 穩態 了 #define intKeyTot 1500
KeyData = KeyTemp; // 取 按鍵值
}
}
unpressed++;
if( unpressed == intKeyTot )
{
pressed = 0;
unpressed = 0;
KeyTemp = 0xff;
KeyData = 0xff;
}
}
2009年2月5日 星期四
正規表示法
正規表示法RE
1. ^開頭字串
2. 結尾字串$
3. . 任意字元
4. [字元集合] => 取一個字元 ex: [0-9]
5. [^字元集合] => 反集合取一字元
6. \{n\} => 出現n次
7. \{n,m\} => 出現n~m次
8. \跳托字元
9.* 表示0~多個字元
? 表示0或1次
+ 表示 >=1 次以上 這是擴充型 要用egrep
10. \<單字\> 找文章單字用的
\< 開頭單字
\> 結尾單字
ex: 找 ip
192.168.32.44
grep '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' XXX
ex: 找電話
0944-123456
grep '09[0-9]\{2\}-[0-9]\{6\}' XXX
ex: 日期 月-日-年
12-22-97
grep '[01][0-9]-[0-3][0-9]-[0-9]\{\2}' XXX
ex: 日期 月-日-年 改成 年-月-日
用()來區分項次
12-22-97
sed 's/RE/新字串/'
sed 's/\([01][0-9]\)-\([0-3][0-9]\)-\([0-9]\{\2}\)/\3-\1-\2/' XXX
ex:日期 沒加g只會改第一個
12-22-97 09-15-98
sed 's/RE/新字串/g'
sed 's/\([01][0-9]\)-\([0-3][0-9]\)-\([0-9]\{\2}\)/\3-\1-\2/g' XXX
ex:電話 02-21234567 改成(02)21234567
sed 's/\(02\)-\([0-9]\{8\}\)/(\1)\2/g' XXX
ex:電話 02-21234567 改成(02)2123-4567
sed 's/\(02\)-\([0-9]\{4\}\)\([0-9]\{4\}\)/(\1)\2-\3/g' XXX
ex:e-mail 帳號@字串.xxx.xxx (xxx可能好幾次)
grep '[a-z,A-Z,0-9][a-z,a-Z,0-9,_,.]*@[a-z,A-Z,0-9].*\..*' test1
================
grep
-n 顯示列號
-c 顯示列數
-i 忽略大小寫
-l 只顯示檔名
-o 只顯示比對到的RE
-v 顯示不符合的
1. ^開頭字串
2. 結尾字串$
3. . 任意字元
4. [字元集合] => 取一個字元 ex: [0-9]
5. [^字元集合] => 反集合取一字元
6. \{n\} => 出現n次
7. \{n,m\} => 出現n~m次
8. \跳托字元
9.* 表示0~多個字元
? 表示0或1次
+ 表示 >=1 次以上 這是擴充型 要用egrep
10. \<單字\> 找文章單字用的
\< 開頭單字
\> 結尾單字
ex: 找 ip
192.168.32.44
grep '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' XXX
ex: 找電話
0944-123456
grep '09[0-9]\{2\}-[0-9]\{6\}' XXX
ex: 日期 月-日-年
12-22-97
grep '[01][0-9]-[0-3][0-9]-[0-9]\{\2}' XXX
ex: 日期 月-日-年 改成 年-月-日
用()來區分項次
12-22-97
sed 's/RE/新字串/'
sed 's/\([01][0-9]\)-\([0-3][0-9]\)-\([0-9]\{\2}\)/\3-\1-\2/' XXX
ex:日期 沒加g只會改第一個
12-22-97 09-15-98
sed 's/RE/新字串/g'
sed 's/\([01][0-9]\)-\([0-3][0-9]\)-\([0-9]\{\2}\)/\3-\1-\2/g' XXX
ex:電話 02-21234567 改成(02)21234567
sed 's/\(02\)-\([0-9]\{8\}\)/(\1)\2/g' XXX
ex:電話 02-21234567 改成(02)2123-4567
sed 's/\(02\)-\([0-9]\{4\}\)\([0-9]\{4\}\)/(\1)\2-\3/g' XXX
ex:e-mail 帳號@字串.xxx.xxx (xxx可能好幾次)
grep '[a-z,A-Z,0-9][a-z,a-Z,0-9,_,.]*@[a-z,A-Z,0-9].*\..*' test1
================
grep
-n 顯示列號
-c 顯示列數
-i 忽略大小寫
-l 只顯示檔名
-o 只顯示比對到的RE
-v 顯示不符合的
depmod
有相依性的程式
在程式中需多上
**************************
* EXPORT_SYMBOL(symbol); *
**************************
告知公開的函式
make後
再把*.ko檔放入depmod搜索路徑內
/lib/modules/2.6.9/kernel/drivers/.....
在打上指令
depmod -ae
來讓/lib/modules/2.6.9/modules.dep檔建立相依關係
最後再用modprobe -V xxxx 來讓相依檔都載入核心
移除用modprobe -r xxxx移除
相依檔也會移除
###############################
第二種方法
不好用
用的人少
**************************
* request_module("xxxx") *
**************************
還要多標頭檔linux/kmod.h
移除也沒辦法一次移除
要一個一個來
因為沒相依
但載入都會一起進去
2009年2月4日 星期三
para改變數值在insmod時
在程式中
都有設定初值
如果直接
insmod para.ko
變數就直接用預設的初值
要給值則用
insmod para.ko 變數名稱=??? 這樣
如
insmod para.ko myint=35
或
insmod para.ko myarr="33,66"
或
insmod para.ko mybyte=1 mystring="abc"
等方法
para2多上版本判斷
新版的module_param(myint,int,S_IRWXU);
會在/sys/module/para/
等下產生資料檔案
########################################
[root@localhost para2]# cat para.c
#include < linux/version.h >
#include < linux/kernel.h >
#include < linux/module.h >
#include < linux/init.h >
static int myint=10;
static int myarr[2]={2.45};
static char mybyte='a';
static char *mystring = "YAYAYA";
#if LINUX_VERSION_CODE>KERNEL_VERSION(2,6,0)
//判斷版本 版本可用uname -r看
//版本比2.6.0新的才用這個
static int num_myintArray=0;
//num_myintArray用來判斷insmod時設的arr值有幾個
/*
最後參數 可用下列等等改權限也可用數字四碼
最後參數為0表示不會在/sys/module/XXXX/下出現檔案
S_IRWXU = S_IRUSR | S_IWUSR | S_IXUSR
S_IRWXG = S_IRGRP | S_IWGRP | S_IXGRP
S_IRWXO = S_IROTH | S_IWOTH | S_IXOTH
*/
//以下為新版用法 多了一個變數還有改成小寫
module_param(myint,int,S_IRWXU);
module_param_array(myarr,int,num_myintArray,0777);
module_param(mybyte,byte,0777);
module_param(mystring,charp,0); //charp 陣列用
#else
MODULE_PARM(myint,"i");
MODULE_PARM(myarr,"1-2i");
MODULE_PARM(mybyte,"b");
MODULE_PARM(mystring,"s");
#endif
MODULE_PARM_DESC(myint,"this is int");
MODULE_PARM_DESC(myaaa,"this is aaa");
static int __init hello_init(void){
printk("<1>Hello, World!!myint %i\n",myint);
#if LINUX_VERSION_CODE>KERNEL_VERSION(2,6,0)
printk("<1>got myarr %d\n",num_myintArray);
#endif
printk("<1>Hello, World!!myarr %i %i\n",myarr[0],myarr[1]);
printk("<1>Hello, World!!mybyte %i\n",mybyte);
printk("<1>Hello, World!!mystring %s\n",mystring);
return 0;
}
static void __exit hello_exit(void){
printk("<1>Bye!Bye!!\n");
}
module_init(hello_init);
module_exit(hello_exit);
[root@localhost para2]#
#################################
[root@localhost para2]# cat Makefile
obj-m += para.o
all:
make -C /lib/modules/2.6.9/build M=/mnt/driver/para2 modules
clean:
make -C /lib/modules/2.6.9/build M=/mnt/driver/para2 clean
[root@localhost para2]#
##############################
Feb 4 20:08:20 localhost kernel: Hello, World!!myint 10
Feb 4 20:08:20 localhost kernel: got myarr 0
Feb 4 20:08:20 localhost kernel: Hello, World!!myarr 2 0
Feb 4 20:08:20 localhost kernel: Hello, World!!mybyte 97
Feb 4 20:08:20 localhost kernel: Hello, World!!mystring YAYAYA
Feb 4 20:08:30 localhost kernel: Bye!Bye!!
para多上變數
#######################
[root@localhost para]# cat para.c
#include < linux/kernel.h >
#include < linux/module.h >
#include < linux/init.h >
static int myint=10;
static int myarr[2]={2.45};
static char mybyte='a';
static unsigned short myshort=1;
static long mylong=9999;
static char *mystring="karta";
MODULE_PARM(myint,"i");
MODULE_PARM(myarr,"1-2i");
MODULE_PARM(mybyte,"b");
MODULE_PARM(myshort,"h");
MODULE_PARM(mylong,"l");
MODULE_PARM(mystring,"s");
/*
MODULE_PARM(var,type);
type可用很多表示 上面已列出差不多了
*/
MODULE_PARM_DESC(myint,"this is int");
MODULE_PARM_DESC(myaaa,"this is aaa");
//MODULE_PARM_DESC 這個訊息在用modinfo可以看到
/*
[root@localhost para]# modinfo para.ko
filename: para.ko
parm: myint:this is int
parm: myaaa:this is aaa
vermagic: 2.6.9 686 REGPARM gcc-3.4
depends:
[root@localhost para]#
*/
static int __init hello_init(void){
printk("<1>myint is=%i\n",myint);
//用%i 和 %d是一樣的
printk("<1>myarr is=%i %i\n",myarr[0],myarr[1]);
printk("<1>mybyte is=%i\n",mybyte);
printk("<1>myshort is=%hi\n",myshort);
printk("<1>mylong is=%li\n",mylong);
printk("<1>mystring is=%s\n",mystring);
return 0;
}
static void __exit hello_exit(void){
printk("<1>Bye!Bye!!\n");
}
module_init(hello_init);
module_exit(hello_exit);
[root@localhost para]#
#######################
[root@localhost para]# cat Makefile
obj-m += para.o
all:
make -C /lib/modules/2.6.9/build M=/mnt/driver/para modules
clean:
make -C /lib/modules/2.6.9/build M=/mnt/driver/para clean
[root@localhost para]#
#######################
Feb 4 19:46:53 localhost kernel: myint is=10
Feb 4 19:46:53 localhost kernel: myarr is=2 0
Feb 4 19:46:53 localhost kernel: mybyte is=97
Feb 4 19:46:53 localhost kernel: myshort is=1
Feb 4 19:46:53 localhost kernel: mylong is=9999
Feb 4 19:46:53 localhost kernel: mystring is=karta
Feb 4 19:53:23 localhost kernel: Bye!Bye!!
[root@localhost para]#
hello world 3 #ifdef
一樣是分開成兩個檔案
再多上#ifdef的用法
[root@localhost driver]# cd hello3
[root@localhost hello3]# ls
Makefile start.c stop.c
###########################################################
[root@localhost hello3]# cat start.c
#include < linux/kernel.h >
#include < linux/module.h >
#include < linux/init.h >
static int __init hello_init(void){
#ifdef __TEST__
printk("<1>Hello, World!!TEST\n");
#else
printk("<1>not __TEST__\n");
#endif
return 0;
}
module_init(hello_init);
[root@localhost hello3]#
###########################################################
[root@localhost hello3]# cat stop.c
#include < linux/kernel.h >
#include < linux/module.h >
#include < linux/init.h >
static void __exit hello_exit(void){
printk("<1>Bye!Bye!!\n");
}
module_exit(hello_exit);
[root@localhost hello3]#
###########################################################
[root@localhost hello3]# cat Makefile
obj-m += startstop.o
startstop-objs := start.o stop.o
EXTRA_CFLAGS += -D__TEST__
# makefile上多上這行等於是#define __TEST__
# 或等於在gcc上 多加上-D__TEST__這行
all:
make -C /lib/modules/2.6.9/build M=/mnt/driver/hello3 modules
clean:
make -C /lib/modules/2.6.9/build M=/mnt/driver/hello3 clean
[root@localhost hello3]#
hello world 2 單一hello.c檔變兩個
[root@localhost driver]# cd hello2
[root@localhost hello2]# ls
Makefile start.c stop.c
關鍵在Makefile
##########################################################
[root@localhost hello2]# cat start.c
#include < linux/kernel.h >
#include < linux/module.h >
#include < linux/init.h >
static int __init hello_init(void){
printk("<1>Hello, World!!\n");
return 0;
}
module_init(hello_init);
[root@localhost hello2]#
##########################################################
[root@localhost hello2]# cat stop.c
#include < linux/kernel.h >
#include < linux/module.h >
#include < linux/init.h >
static void __exit hello_exit(void){
printk("<1>Bye!Bye!!\n");
}
module_exit(hello_exit);
[root@localhost hello2]#
##########################################################
[root@localhost hello2]# cat Makefile
obj-m += startstop.o
startstop-objs := start.o stop.o
all:
make -C /lib/modules/2.6.9/build M=/mnt/driver/hello2 modules
clean:
make -C /lib/modules/2.6.9/build M=/mnt/driver/hello2 clean
[root@localhost hello2]#
hello world
第一個的程式 hello world for device drivers
#######################################################
[root@localhost hello]# cat hello.c
#include < linux/kernel.h >
#include < linux/module.h >
#include < linux/init.h >
static int __init hello_init(void){
printk("<1>Hello, World!!\n");
return 0;
}
static void __exit hello_exit(void){
printk("<1>Bye!Bye!!\n");
}
module_init(hello_init);
module_exit(hello_exit);
[root@localhost hello]#
#######################################################
[root@localhost hello]# cat Makefile
obj-m += hello.o
all:
make -C /lib/modules/2.6.9/build M=/mnt/driver/hello modules
# 上列可改成
# make V=1 -C /lib/modules/`uname -r`/build M=`pwd` modules
# #號為註解
clean:
make -C /lib/modules/2.6.9/build M=/mnt/driver/hello clean
[root@localhost hello]#
#######################################################
[root@localhost hello]# insmod hello.ko
Hello, World!!
[root@localhost hello]# rmmod hello
Bye!Bye!!
[root@localhost hello]#
#######################################################
[root@localhost hello]# cat hello.c
#include < linux/kernel.h >
#include < linux/module.h >
#include < linux/init.h >
static int __init hello_init(void){
printk("<1>Hello, World!!\n");
return 0;
}
static void __exit hello_exit(void){
printk("<1>Bye!Bye!!\n");
}
module_init(hello_init);
module_exit(hello_exit);
[root@localhost hello]#
#######################################################
[root@localhost hello]# cat Makefile
obj-m += hello.o
all:
make -C /lib/modules/2.6.9/build M=/mnt/driver/hello modules
# 上列可改成
# make V=1 -C /lib/modules/`uname -r`/build M=`pwd` modules
# #號為註解
clean:
make -C /lib/modules/2.6.9/build M=/mnt/driver/hello clean
[root@localhost hello]#
#######################################################
[root@localhost hello]# insmod hello.ko
Hello, World!!
[root@localhost hello]# rmmod hello
Bye!Bye!!
[root@localhost hello]#
訂閱:
文章 (Atom)