container_of에서 포인터의 값 문제.....

wizard1483의 이미지

안녕하세요. 제가 지금 ldd3판을 보면서 공부 중 입니다.

궁금한 것이 아래의 open 함수입니다. container_of에서 첫 인자로 inode->i_cdev를 넘겨주고

구조체를 scull_dev를 넘겨줍니다. 그리고 위치를 cdev를 넘겨줍니다.

container_of 매크로의 활용은 이해를 했습니다.

즉, scull_dev구조체와 cdev 멤버와 비교해서 offset값을 구해서 inode->i_cdev - offset을 해서

구조체 시작 주소를 구하는 것으로 이해를 했습니다.

문제는~! inode랑 scull_dev 구조체는 서로가 다릅니다. container_of 연산이 끝나면

원래 원하던 scull_dev구조체의 시작 주소가 아니고 inode의 주소 어딘가로 가게 되는게 아닌가요?

int scull_open(struct inode *inode, struct file *filp)
{
struct scull_dev *dev; /* device information */
dev = container_of(inode->i_cdev, struct scull_dev, cdev); <====== 이해가 안가요.
filp->private_data = dev; /* for other methods */
/* now trim to 0 the length of the device if open was write-only */
if ( (filp->f_flags & O_ACCMODE) = = O_WRONLY) {
scull_trim(dev); /* ignore errors */
}
return 0; /* success */
}

bushi의 이미지

struct inode 의 i_cdev 는 struct cdev*
struct scull_dev 의 cdev 는 struct cdev

cdev_init() 호출 때 아규먼트로 struct cdev* 와 더불어 전달한 file_operations{} 의 멤버함수가 받는 struct inode* 의 i_cdev 가 가르키는게 뭐였으면 좋으시겠습니까 ?

wizard1483의 이미지

아직도 잘 이해가 안가지만 i_cdev가 scull_dev의 cdev를 가르켜야 하는것 같습니다.

wizard1483의 이미지

dev = container_of(inode->i_cdev, struct scull_dev, cdev);

여기를 보면은 inode->i_dev는 inode struct에 i_dev를 가리키고 있습니다.
근데 container_of를 들어가면

#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})

type cast가 됩니다. cast된 주고에서 offset값을 빼게 됩니다.

근데 궁급한 것이 inode->i_cdev의 주소가 0x100이라고 하면은

type cast가 되어도 0x100이 맞나요? 그럼 그 앞뒤의 데이터는 inode struct의 데이터가 들어가 잇고

0x100에 member 만큼의 offset을 빼는거 맞나요?