디바이스 파일은 장치의 유형을 나타내는 메이저 넘버와 장치 내에서 인스턴스를 구별하는 마이너 넘버를 조합한 디바이스 넘버로 표현합니다. 유저 레벨에서는 stat() system call 로 디바이스 정보를 구합니다. struct stat 의 st_rdev 필드에 디바이스 넘버는 저장합니다.
이 디바이스 넘버의 크기가 커널(배포판)에 따라 달라집니다. 최근 커널 레벨은 32bit를 major 12bit와 minor 20bit로 표현하고, 유저 레벨은 32bit를 minor 12bit, major 12bit, minor 8bit 로 표현합니다.
유저 레벨에서 디바이스 넘버를 참조할 때 sysmacro.h 의 major, minor 매크로를 사용하면 됩니다.
* 커널 2.4.x - unsigned short였던 kdev_t 으로 디바이스 넘버(major/minor) 저장합니다. minor number 8bit: 0x00ff major number 8bit: 0xff00
* 커널 2.4.2 의 glibc(유저레벨) - dev_t st_rdev 는 8 bytes 사이즈입니다. typedef __dev_t dev_t; typedef __u_quad_t __dev_t; /* Type of device numbers. */ __extension__ typedef unsigned long long int __u_quad_t;
- major 8bit, minor 8bit 로 디바이스 넘버를 저장합니다. minor number 8bit: 0x00ff major number 8bit: 0xff00
- /usr/include/sys/sysmacros.h # define major(dev) ((int)(((dev) >> 8) & 0xff)) # define minor(dev) ((int)((dev) & 0xff))
* 커널 2.6.x - unsigned short였던 kdev_t가 없어지고 unsigned int인 dev_t로 바뀌면서 32bit 로 확장되었습니다. minor number 20bit: 0x000f ffff major nubmer 12bit: 0xfff0 0000
* 커널 2.4.21, 2.6.x 의 glibc(유저레벨) - 하위 2bytes 는 예전대로 minor 8bit, major 8bit 와 호환되지만, 상위 2bytes 를 추가로 사용합니다. minor number 20bit(앞12bit, 뒤8bit): 0xfff0 00ff major number 12bit(가운데 12bit) : 0x000f ff00
- /usr/include/sys/sysmacros.h __extension__ extern __inline unsigned int gnu_dev_major (unsigned long long int __dev) __THROW { return ((__dev >> 8) & 0xfff) | ((unsigned int) (__dev >> 32) & ~0xfff); }
__extension__ extern __inline unsigned int gnu_dev_minor (unsigned long long int __dev) __THROW { return (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff); } # define major(dev) gnu_dev_major (dev) # define minor(dev) gnu_dev_minor (dev) | |