2012年6月26日 星期二

The Linux Directory Structure Explained

在一開始使用Unix-like system時,對於其檔案系統架構。最為不了解,

 

The Filesystem Hierarchy Standard (FHS) defines the structure of file systems on Linux and other UNIX-like operating systems.


/ – The Root Directory
Everything on your Linux system is located under the / directory, known as the root directory.
/bin – Essential User Binaries
The /bin directory contains the essential user binaries (programs) that must be present when the system is mounted in single-user mode.
Applications such as Firefox are stored in /usr/bin, while important system programs and utilities such as the bash shell are located in /bin.
The /sbin directory is similar – it contains essential system administration binaries.
image
image
image
/boot – Static Boot Files
The /boot directory contains the files needed to boot the system – for example, the GRUB boot loader’s files and your Linux kernels are stored here. The boot loader’s configuration files aren’t located here, though – they’re in /etc with the other configuration files.
/cdrom – Historical Mount Point for CD-ROMs
It’s a temporary location for CD-ROMs inserted in the system. However, the standard location for temporary media is inside the /media directory.
/dev – Device Files
Linux exposes devices as files, and the /dev directory contains a number of special files that represent devices.
These are not actual files as we know them, but they appear as files – for example, /dev/sda represents the first SATA drive in the system.
image
/etc – Configuration Files
The /etc directory contains configuration files, which can generally be edited by hand in a text editor. Note that the /etc/ directory contains system-wide configuration files – user-specific configuration files are located in each user’s home directory.
image
/home – Home Folders
The /home directory contains a home folder for each user. For example, if your user name is bob, you have a home folder located at /home/bob. This home folder contains the user’s data files and user-specific configuration files.
/lib – Essential Shared Libraries
The /lib directory contains libraries needed by the essential binaries in the /bin and /sbin folder. Libraries needed by the binaries in the /usr/bin folder are located in /usr/lib.
/lost+found – Recovered Files
Each Linux file system has a lost+found directory. If the file system crashes, a file system check will be performed at next boot. Any corrupted files found will be placed in the lost+found directory, so you can attempt to recover as much data as possible.
/media – Removable Media
The /media directory contains subdirectories where removable media devices inserted into the computer are mounted.
For example, when you insert a CD into your Linux system, a directory will automatically be created inside the /media directory. You can access the contents of the CD inside this directory.
/mnt – Temporary Mount Points
Historically speaking, the /mnt directory is where system administrators mounted temporary file systems while using them. For example, if you’re mounting a Windows partition to perform some file recovery operations, you might mount it at /mnt/windows. However, you can mount other file systems anywhere on the system.
/opt – Optional Packages
The /opt directory contains subdirectories for optional software packages. It’s commonly used by proprietary software that doesn’t obey the standard file system hierarchy – for example, a proprietary program might dump its files in /opt/application when you install it.
/proc – Kernel & Process Files
The /proc directory similar to the /dev directory because it doesn’t contain standard files. It contains special files that represent system and process information.
image
/sbin – System Administration Binaries
The /sbin directory is similar to the /bin directory. It contains essential binaries that are generally intended to be run by the root user for system administration.
image
/selinux – SELinux Virtual File System
If your Linux distribution uses SELinux for security (Fedora and Red Hat, for example), the /selinux directory contains special files used by SELinux.
none.
/srv – Service Data
The /srv directory contains “data for services provided by the system.” If you were using the Apache HTTP server to serve a website, you’d likely store your website’s files in a directory inside the /srv directory.
image
/tmp – Temporary Files
Applications store temporary files in the /tmp directory. These files are generally deleted whenever your system is restarted and may be deleted at any time by utilities such as tmpwatch.
/usr – User Binaries & Read-Only Data
The /usr directory contains applications and files used by users, as opposed to applications and files used by the system. For example, non-essential applications are located inside the /usr/bin directory instead of the /bin directory and non-essential system administration binaries are located in the /usr/sbin directory instead of the /sbin directory
image
/var – Variable Data Files
The /var directory is the writable counterpart to the /usr directory, which must be read-only in normal operation. Log files and everything else that would normally be written to /usr during normal operation are written to the /var directory. For example, you’ll find log files in /var/log.
image

The Linux Directory Structure Explained



















簡單字元裝置驅動程式

以字元裝置驅動來學習,建立出寫一個linux裝置驅動的結構及楖念。
以下均是以CDK EVB上做為實例。而可能在其資料或macro等在不同環境可能也有所不同。


首先,在Linux底下分為三種的裝置驅動,分別為"字元"、"區塊"及"網路"。
其中字元及區塊的驅動的分別:
1.字元
指的是那些一次只能一個位元組來進行讀寫動作的的裝置,而且無法隨機讀取裝置記憶体中的任何一個位置上的資料。如:滑、鍵盤、序列埠等
2.區塊
可以從裝置中任意位置中讀寫一定長度資料的裝置,而且讀寫資料也不必按照先後順序。如:HD、SD 'USB HD.
其各裝置可在"/dev"中查看
image

看其檔案屬性的第一位字元,c,d,b;
及裝置的主裝置編號、次編號
)










主編號及次編號和稱為裝置編號。
而主編號用表示一個特定的驅動;次編號則是用來表示是那個裝置。
(如二個LED,使用主編號10,而第一個LED的次編號可設為1;另一個為2。如此就可以分別驅動
其在linux 2.6.19中,是以dev_t來做為其裝置的編號。
A.
image
B.其對於主編號、次編號的操作
MRJOR:取得主編號
MINOR:次編號
MKDEV:裝置編號
image
















C.靜態設定
因為在linux中已預設了一些裝置編號,在使用靜態時,需去查看
image
或是直接到/proc/device檔案中查看(目前已使用)
image 
D.動態設定
為了避免別台電腦的裝置衝突,建議使用動態
alloc_chrdev_region() 申請裝置號(靜態)
由其函數說明,可得其from為dev_t(必須已有其major number) count為個數; name則為其裝置名稱
image
而為了避免發生問題,更提供了alloc_chrdev_region申請裝置號(動態)
image
E.釋放字元裝置號碼
image

F.註冊裝置到系統
在申請裝置號碼後,將下來則是要將註冊裝置到系統
F.1 ,cdev struct來描述其字元裝置
image
Char device的Structure中,它可以看成是所有字元裝置的
主要結構,裡面是所有字元裝置的抽象元素。
struc kobject kobj //用於核心裝置驅動模型的管理。
struct module *owner;//指向包含該結構的模組指標,用於參考計數。
const struct file_operation *ops;//指向字元裝置操作函數集的指標。
struct list_head list;//將字元裝置連接成一個link list.
dev_t dev;//為該裝置的起始裝置號.
unsigned int count;//該裝置的數量.

其中各元素內容之定義。多在include/linux中 (file_operations= fs.h , kobject=Kobject.h)
list_head list是與inode structure中的i_devices(也為link list)有關
其在裝置檔案開啓時,系統中就會產生一個inode出來而從其inode中的i_cdev就可找到cdev的struct了
及其ops。
image
F.2
在linux中,將各裝置都視為一個file來操作。其存取相對應函式如下。
image
ower:指向擁有這結構模組的指標。用來維持模組的參考計數,當模組還在使用時,無法使用rmmod(初始為THIS_MODULE)
llseek():改變檔案中的讀寫位置,並將其新位置回。
read():從裝置中獲取資料,傳回其資料的位元組數。
write(): 寫資料到裝置中,傳回其寫入的位元組數。
open():開啓。
release():釋放裝置。只有其裝置的參考數為0時,才可以呼叫。通常用close()來關閉,但不一定call release()。
F.3 cdev與file_operations關係
   1: static struct socle_FPGA_Driver {

   2:     int busy;

   3:     dev_t FPGA_devt;

   4:     struct class *class;

   5:     struct class_device *class_dev;

   6:     struct cdev *cdev;

   7: } socle_FPGA;

在一個字元裝置的中,必定含有其cdev。

從cdev可以有file_opeations,dev_t dev等資訊。

F.4 inode(include/linux/fs.h)

image

inode/block/superblock

可以看成inode會對應一個或多個block.

inode為其檔案的屬性及位置; 而block則為其真正的資料.

而一個字元裝置也是一個檔案。故也有它的inode。

故在使用時,也會用到。如open()中是用inode指標。用得到該節點的資訊。

int (*open) (struct inode*,struct file*);

在struct inode中,重要的有

dev_t i_rdev,表示裝置對應裝置號

struct list_head i_devices,為裝置連接對應的cdev結構。

struct cdev * i_cdev,指向cdev裝置。







G.字元裝置的模版.

字元裝置的申請和cdev的註冊。


   1: struct xxx_dev //自定device struct

   2: {

   3: struct cdev cdev; //cdev struct

   4: ...

   5: };

   6:  

   7: static int __init xxx_init(void)

   8: {

   9: ...

  10: /*申請裝置號,當xxx_major不為0時,為靜能;否則為動態

  11: if(xxx_major)

  12:     result=register_chrdev_region(xxx_devno,1,"dev_name");

  13: else

  14:     {

  15:     result=alloc_chrdev_region(&xxx_devno,0,1,"dev_name");

  16:     xxx_major=(xxx_devno);//重新取得主編號

  17:     }

  18: //初始化cdev,並傳file_opearations

  19:     cdev_init(&xxx_dev.cdev,&xxx_fops);

  20:     dev->cdev.ower=THIS_MODULE; //指定所屬模組

  21:     err=cdev_add(&xxx_dev.cdev,xxx_devno,1); //註冊裝置

  22: }

  23:  

  24: static void __exit xxx_exit(void)

  25: {

  26:     cdev_del(&xxx+dev.cdev);//註消cdev

  27:     unregister_chrdev_region(xxx_devno,1);//釋放裝置號碼

  28: }




   1:  

   2: //file_opeartions

   3: static const struct file_operations xxx_fops=

   4: {

   5:     .owner=THIS_MODULE,

   6:     .read=xxx_read,

   7:     .write=xxx_write,

   8:     .ioctl=xxx_ioctl

   9: };

  10: //read opeartion

  11: //size為資料大小; ppos為其讀寫位置

  12: static ssize_t xxx_read(struct file *file,char __user *buf,size_t size,loff_t *ppos)

  13: {

  14:   ...

  15: copy_to_user(buf,...,..);

  16: ..

  17: put_user(...,buf);

  18: }

  19: //write opeartion

  20: static ssize_t xxx_write(struct file *file,char __user *buf,size_t size,loff_t *ppos)

  21: {

  22:   ...

  23: copy_from_user(buf,...,..);

  24: ..

  25: get_user(...,buf);

  26: }

  27: ///ioctl

  28: static long xxx_ioctl(struct file*file,unsigned int cmd,unsigned long arg)

  29: {

  30: ..

  31: switch(cmd)

  32:     {

  33:     case xx_cm1:

  34:         ..

  35:         break;

  36:     case xx_cm2:

  37:         ..

  38:         break;

  39:     default:

  40:         return -EINVAL;    

  41:     }

clip_image002

參考資料:

鳥哥的 Linux 私房菜Linux 磁碟與檔案系統管理

http://linux.vbird.org/linux_basic/0230filesystem.php#inode

code:





   1: //=========================摰儔include瑼?define瑼?======================

   2: #define SOCLE_FPGA_MAJOR        0     // 0: dynamic major number

   3: #define SOCLE_FPGA_MINOR        0     //甈∠楊??

   4: #define FPGA_START            0x1CB20000

   5: #define SIZE_OF_DEVICE        (0x4000*32)

   6:  

   7: #include<linux/sched.h>

   8: #include <linux/kernel.h>

   9: #include <linux/fs.h>                     //摰儔file蝯?

  10: #include <linux/types.h>

  11: #include <linux/module.h>

  12: #include <linux/cdev.h>

  13: #include <linux/device.h>

  14: #include <linux/ioport.h>

  15: #include <asm/uaccess.h>                  //copy from/to user

  16: #include <linux/ioctl.h>

  17: #include <asm/io.h>

  18: #include <asm/system.h>

  19: #include <asm/arch/regs-pwmt.h>

  20: #include <asm/arch/hardware.h>

  21:  

  22: //=======================================================================

  23:  

  24: //============================摰儔?航炊閮憿舐內?澆?========================

  25: //#define SOCLE_FPGA_DEBUG

  26: #ifdef SOCLE_FPGA_DEBUG

  27: #define FPGA_DBG(fmt, args...) printk(KERN_DEBUG "SOCLE_FPGA: " fmt, ## args)

  28: #else

  29: #define FPGA_DBG(fmt, args...)

  30: #endif

  31: //=======================================================================

  32:  

  33: //===============================摰儔鋆蔭蝺刻?=============================

  34: static int socle_FPGA_major = SOCLE_FPGA_MAJOR;  //銝餌楊??

  35: static int socle_FPGA_minor = SOCLE_FPGA_MINOR;  //甈∠楊??

  36: module_param(socle_FPGA_major, int, 644);

  37: module_param(socle_FPGA_minor, int, 644);

  38: //=======================================================================

  39:  

  40: //==========================摰儔??蝵桃?蝯??==========================

  41: static struct socle_FPGA_Driver {

  42:     int busy;

  43:     dev_t FPGA_devt;

  44:     struct class *class;

  45:     struct class_device *class_dev;

  46:     struct cdev *cdev;

  47: } socle_FPGA;

  48: //=======================================================================

  49:  

  50: static ssize_t socle_FPGA_read    (struct file *fd, char __user *buf, size_t size, loff_t *f_pos);

  51: static ssize_t socle_FPGA_write   (struct file *fd, const char __user *buf, size_t size, loff_t *f_pos);

  52: static int     socle_FPGA_ioctl   (struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg);

  53: static int     socle_FPGA_open    (struct inode *inodep, struct file *filep);

  54: static int     socle_FPGA_release (struct inode *inodep, struct file *filep);

  55: u32 val;    //?脣?霈€撖怎???

  56: volatile unsigned long  *FPGA_wSTART;

  57:  

  58: //===========================撽?蝔?????==============================

  59: static struct file_operations socle_FPGA_fops = {

  60:          .owner = THIS_MODULE,             //摰儔??linux/module.h>

  61:      .llseek =  no_llseek,            //銝祕雿lseek

  62:        .read = socle_FPGA_read,         //敺ernel-sapce?酌ser-space

  63:       .write = socle_FPGA_write,        //敺ser-space?逃ernel-space

  64:       .ioctl = socle_FPGA_ioctl,        //鋆蔭撠惇?誘

  65:        .open = socle_FPGA_open,         //??獢?

  66:     .release = socle_FPGA_release       //?鋆蔭瑼?

  67: };

  68: //=======================================================================

  69:  

  70: //=========================Application霈€????========================

  71: static int socle_FPGA_read(struct file *fd, char __user *buf, size_t size, loff_t *f_pos)

  72: {

  73:        val=ioread32(FPGA_wSTART);

  74:     mb();

  75:        copy_to_user(buf, &val,size);

  76:     return 0;

  77: }

  78: //=======================================================================

  79:  

  80: //=========================Application摮鞈?=========================

  81: static int socle_FPGA_write(struct file *fd, const char __user *buf, size_t size, loff_t *f_pos)

  82: {

  83:        copy_from_user(&val, buf, size);

  84:     iowrite32(val,FPGA_wSTART);

  85:     mb();

  86:     return 0;

  87: }

  88: //=======================================================================

  89:  

  90:  

  91: //============================摰儔撠惇?誘===============================

  92: static int socle_FPGA_ioctl(struct inode *inodep, struct file *filep, unsigned int cmd, unsigned long arg)

  93: {

  94:     

  95:     return 0;

  96: }

  97: //=======================================================================

  98:  

  99: //===================?箏?蝥?璆剝€脰?敹???????=========================

 100: //ex:瑼X鋆蔭?寞??隤扎€璅?蝵桀?憪???逆_op??蝑?

 101: static int socle_FPGA_open(struct inode *inodep, struct file *filep)

 102: {

 103:  

 104:     FPGA_DBG("socle_FPGA_open\n");

 105:  

 106:        return nonseekable_open(inodep,filep);

 107: }

 108: //=======================================================================

 109:  

 110:  

 111: //================?鋆蔭瑼??逵ile撠◤???鋡怨孛??===================

 112: //ex:?open?脣??審ilp->private_data?镼?

 113: static int socle_FPGA_release(struct inode *inodep, struct file *filep)

 114: {

 115:  

 116:     FPGA_DBG("socle_FPGA_release\n");

 117:     return 0;

 118: }

 119: //=======================================================================

 120:  

 121:  

 122: //=====================??cdev_init()???迨蝯?=======================

 123: static int socle_FPGA_setup_cdev(struct socle_FPGA_Driver *p_FPGA)

 124: {

 125:     int ret, err;

 126:  

 127:     p_FPGA->FPGA_devt = MKDEV(socle_FPGA_major, socle_FPGA_minor);

 128:     

 129:     if (socle_FPGA_major) {

 130:     ret = register_chrdev_region(p_FPGA->FPGA_devt, 1, "FPGA-Driver");

 131:     } else {

 132: ret = alloc_chrdev_region(&p_FPGA->FPGA_devt, socle_FPGA_minor, 1, "FPGA-Driver");

 133:         socle_FPGA_major = MAJOR(p_FPGA->FPGA_devt);

 134:         socle_FPGA_minor = MINOR(p_FPGA->FPGA_devt);

 135:     }

 136:     if (ret < 0)

 137:         return ret;

 138:  

 139:     p_FPGA->class = class_create(THIS_MODULE, "socle-FPGA-Driver");

 140:     if (IS_ERR(p_FPGA->class)) {

 141:        printk("socle_FPGA_setup_cdev: Can't create FPGA Driver class!\n");

 142:         ret = PTR_ERR(p_FPGA->class);

 143:         goto error1;

 144:     }

 145:     p_FPGA->cdev = cdev_alloc();        

 146:     if (NULL == p_FPGA->cdev) {

 147:         printk("socle_FPGA_setup_cdev: Can't alloc FPGA Driver cdev!\n");

 148:         ret = -ENOMEM;

 149:         goto error2;

 150:     }

 151:  

 152:     p_FPGA->cdev->owner = THIS_MODULE;

 153:     p_FPGA->cdev->ops = &socle_FPGA_fops;

 154:  

 155:     err = cdev_add(p_FPGA->cdev, p_FPGA->FPGA_devt, 1);

 156:     if (err) {

 157:         printk("socle_FPGA_setup_cdev: Can't add FPGA cdev to system!\n");

 158:         ret = -EAGAIN;

 159:         goto error2;

 160:     }

 161:  

 162: p_FPGA->class_dev = class_device_create(p_FPGA->class, NULL, p_FPGA->FPGA_devt, NULL, "FPGA-Driver");

 163:     if (IS_ERR(p_FPGA->class_dev)) {

 164:     printk("socle_FPGA_setup_cdev: Can't create FPGA class_dev to system!\n");

 165:         ret = PTR_ERR(p_FPGA->class_dev);

 166:         goto error3;

 167:     }

 168: printk("FPGA-Driver_class_dev info: FPGA-Driver (%d:%d)\n", MAJOR(p_FPGA->FPGA_devt), MINOR(p_FPGA->FPGA_devt));

 169:  

 170: //=================request_mem_region==========================

 171:        if(!request_mem_region(FPGA_START,SIZE_OF_DEVICE*4,"socle_FPGA"))

 172:            {

 173:             printk("error:Request_mem_region\n");

 174:             return -ENODEV;

 175:            }

 176: //========ioremap_nocache==========

 177:     FPGA_wSTART=(unsigned long *) ioremap_nocache(FPGA_START,SIZE_OF_DEVICE*4);

 178:  

 179:  

 180: printk("FPGA> socle_FPGA_ioport_write  : %p\n",FPGA_wSTART);

 181: //=============================================================================

 182:  

 183:  

 184:     return 0;

 185:  

 186: error3:

 187:     cdev_del(p_FPGA->cdev);

 188: error2:

 189:     class_destroy(p_FPGA->class);

 190: error1:

 191:     unregister_chrdev_region(p_FPGA->FPGA_devt, 1);

 192:     return ret;

 193: }

 194: //=======================================================================

 195:  

 196: //============================頛?詨??銵?=============================

 197: static int __init socle_FPGA_init(void)

 198: {

 199:     int ret = 0;

 200:  

 201:     socle_FPGA_setup_cdev(&socle_FPGA); //_init()???ocle_FPGA_setup_cdev

 202:  

 203:     return ret;

 204: }

 205: //=======================================================================

 206:  

 207: //===========================?頂蝯梯酉瘨酉??==============================

 208: static void socle_FPGA_remove_cdev(struct socle_FPGA_Driver *p_FPGA)

 209: {

 210:     class_device_unregister(p_FPGA->class_dev);

 211:     cdev_del(p_FPGA->cdev);

 212:     class_destroy(p_FPGA->class);

 213:     unregister_chrdev_region(p_FPGA->FPGA_devt, 1);

 214: //========ioremap_nocache==========

 215:         iounmap((void *)FPGA_wSTART);

 216:  

 217:        release_mem_region(FPGA_START,SIZE_OF_DEVICE*4);

 218: }

 219: //=======================================================================

 220:  

 221: //=========================蝯?撽?蝔?撌乩?===============================

 222: static void __exit socle_FPGA_cleanup(void)

 223: {

 224:     socle_FPGA_remove_cdev(&socle_FPGA);

 225:  

 226: }

 227: //=======================================================================

 228:  

 229:  

 230: module_init(socle_FPGA_init);

 231: module_exit(socle_FPGA_cleanup);

 232:  

 233: MODULE_DESCRIPTION("Socle FPGA Driver");

 234: MODULE_LICENSE("GPL");