Linux 커 널 구동 모델 --- 장치 버스 구동
내 가 보기에 모델 은 일련의 사무 에 대해 추상 적 이 고 통일 적 이 며 관 리 를 하 는 것 이다.나타 나 는 차원 적 관계.한 회사 에 부서, 팀, 개인 같은 조직 관계 가 있 는 것 과 같다.그러면 이렇게 하 는 장점 은 바로 관리 하기 편리 하 다 는 것 이다.
Linux 구동 모델
리 눅 스 의 세계 에서 C 언어 를 극치 로 운용 하 는데 여기 서 는 단순히 구조 체 로 상상 해 서 는 안 되 고 데이터 구조 뒤의 의 미 를 체득 해 야 하 며 구조 체 유형 으로 만 이해 해 서 는 안 된다.c + + 에 서 는 클래스 라 는 더 좋 은 표현 이 있 습 니 다.모든 유형 을 유형 으로 상상 하면 더 잘 이해 할 수 있다.그 중에서 구조 체 의 구성원 변 수 는 속성 으로 분류 되 는데 그 중에서 함수 포인터 류 는 이런 종류 가 가지 고 있 는 방법 과 비교 된다.한 인물 의 고유 혈 조 (속성) 와 이 인물 의 공격 스 킬 (방법) 을 비교 합 니 다.이런 구 조 는 리 눅 스에 서 흔히 볼 수 있다.
구동 모형
Linux 에서 가장 흔히 볼 수 있 는 구동 모델 은 바로 장치 (dev) - 버스 (bus) - 구동 (drv), 이런 모델 구조 이다.리 눅 스에 서 클래스 는 일반적으로 업무 의 추상 적 이 고 통용 되 는 공 통 된 내용 을 추출한다.장치 유형 은 이 장치 의 구체 적 인 통용 속성 을 설명 하 는 것 이 더 많다.bus 는 dev 와 drv 의 다리, 유대 입 니 다.dev 와 drv 의 관 계 는 바로 bus 로 연결 되 는 것 이다.drv 는 더 많은 방법 을 설명 합 니 다. 이런 장 치 는 그 가 어떤 기능 을 가지 고 있 는 지, 일반적으로 drv 에서 설명 합 니 다.
dev bus drv 의 형식 은 kernel \ include \ linux \ \ device. h 파일 에 정 의 됩 니 다.
dev 타 입 - struct device
리 눅 스에 서 장 치 는 광범 위 한 개념 이지 특정한 실체 장 치 를 가리 키 는 것 이 아니다.추상 적 인 설비 이 므 로 실체 설비 로 취급 하지 마라.
struct device {
struct device *parent;
struct device_private *p;
struct kobject kobj;
struct bus_type *bus; /* type of bus device is on */
struct device_driver *driver; /* which driver has allocated this
device */
void *platform_data; /* Platform specific data, device
core doesn't touch it */
void *driver_data; /* Driver data, set and get with
dev_set/get_drvdata */
....
}
struct device_private {
struct klist klist_children;
struct klist_node knode_parent;
struct klist_node knode_driver;
struct klist_node knode_bus;
struct list_head deferred_probe;
struct device *device;
};
bus 타 입 - struct bustype
이곳 의 bus 역시 광범 위 한 개념 으로 cpu 의 실제 버스 가 아니 라 프로그램 에서 가상 으로 만들어 진 코드 구조 입 니 다.
struct bus_type {
const char *name;
const char *dev_name;
struct device *dev_root;
struct subsys_private *p;
int (*match)(struct device *dev, struct device_driver *drv);
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
int (*probe)(struct device *dev);
}
struct subsys_private {
struct klist klist_devices;
struct klist klist_drivers;
struct bus_type *bus;
}
drv 타 입 - struct devicedriver
drv 역시 광범 위 한 의미 에서 의 구동 으로 특정한 외부 장치 의 구동 이 아니다.여기 서도 추상 화 되 었 지만 구체 적 인 외부 장치 구동 은 반드시 이 데이터 구 조 를 바탕 으로 하 는 것 이다.약간 c + + 중국 과 외국 에서 구동 되 는 아버지 같은 느낌 이에 요.
struct device_driver {
const char *name;
struct bus_type *bus;
struct driver_private *p;
int (*probe) (struct device *dev);
}
struct driver_private {
struct kobject kobj;
struct klist klist_devices;
struct klist_node knode_bus;
struct module_kobject *mkobj;
struct device_driver *driver;
};
구동 인터페이스
등 록 된 인터페이스 마다 register 가 있 는데 그 와 대응 하 는 unregister 인터페이스 가 있 습 니 다. 예 를 들 어 int driverregister (struct device driver * drv) 와 그 에 게 void driver 가 있어 야 합 니 다.unregister (struct device driver * drv) 인터페이스.주로 자원 의 방출 등 관련 작업 에 사용 된다.
버스 관련
drv 와 dev 의 초기 화 는 모두 bus 와 관련 되 기 때문에 Liux 에서 bus 는 모두 초기 화 를 해 야 dev 와 drv 에 등 록 될 때 사용 할 수 있 습 니 다.인터페이스 정 의 는 \ \ drivers \ base \ bus. c int busregister(struct bus_type *bus)
int bus_register(struct bus_type *bus)
{
int retval;
struct subsys_private *priv;
priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL); // bus p
priv->bus = bus;//p bus bus
bus->p = priv;// bus p p
/* bus p , dev drv */
klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);
klist_init(&priv->klist_drivers, NULL, NULL);
}
dev 관련
인 터 페 이 스 는 \ drivers \ base \ core. c 로 정의 되 며, 실 체 는 대부분 device 로 작 동 합 니 다.add 완성.아래 에 소 개 된 dev 등록 과정 은 bus 에 drv 가 등 록 된 상황 에서 dev 등록 함수 의 호출 과정 을 말 합 니 다. 만약 에 bus 에 drv 가 없다 면 호출 과정 은 이렇게 복잡 하지 않 습 니 다.만약 bus 가 일치 하 는 drv 가 없다 면 현재 dev 의 구동 이 없 거나 아직 등록 되 지 않 았 다 는 것 을 설명 합 니 다. 괜 찮 습 니 다. drv 가 등록 할 때 장 치 를 한 번 훑 어보 고 bus 의 probe 방법 을 실행 합 니 다.int device_register(struct device *dev)—》int device_add(struct device *dev)
int device_add(struct device *dev)
{
if (dev->init_name) {
// init_name dev
dev_set_name(dev, "%s", dev->init_name);
dev->init_name = NULL;
}
// bus_add_device->klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
// dev p bus -》bus p dev , bus 。
error = bus_add_device(dev);
bus_probe_device(dev);
}
//
bus_probe_device(dev)-》device_initial_probe(dev)-》__device_attach(dev, true)-》ret = bus_for_each_drv(dev->bus, NULL, &data,__device_attach_driver)-》int __device_attach_driver;
// -- bus drv dev 。 fn--- -》__device_attach_driver
int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
void *data, int (*fn)(struct device_driver *, void *))
{
while ((drv = next_driver(&i)) && !error)
error = fn(drv, data);
}
__device_attach_driver(struct device_driver *drv, void *_data)
{
ret = driver_match_device(drv, dev);// bus match , ,bus match 。drv->bus->match(dev, drv)
if (ret == 0) {
/* no match */
return 0;
}
return driver_probe_device(drv, dev);
}
driver_probe_device(drv, dev);-》really_probe(dev, drv);
really_probe(struct device *dev, struct device_driver *drv)
{
dev->driver = drv;
if (dev->bus->probe) {
ret = dev->bus->probe(dev);
}
else if (drv->probe) {
ret = drv->probe(dev);
}
// ,dev p drv drv p dev , drv 。
// klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
driver_bound(dev);
}
drv 관련
마찬가지 로 아래 drv 의 등록 도 bus 위 dev 가 있 는 상황 에서 분석 합 니 다.drv 등록 함수 대부분 busadd_driver 완료.인터페이스 정 의 는 \ \ drivers \ base \ \ driver. c int driverregister(struct device_driver *drv)-》bus_add_driver(drv);
int bus_add_driver(struct device_driver *drv)
{
struct bus_type *bus;
struct driver_private *priv;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);// drv p
klist_init(&priv->klist_devices, NULL, NULL);// p dev , dev , dev , drv 。
priv->driver = drv;//p drv drv
drv->p = priv;//drv p , p drv 。
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);// drv p bus , bus p drv , bus , dev 。
error = driver_attach(drv);
}
driver_attach-》bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);
int __driver_attach(struct device *dev, void *data)
{
ret = driver_match_device(drv, dev);// dev , bus match dev drv 。
if (ret == 0) {
/* no match */
return 0;
}
if (!dev->driver)
driver_probe_device(drv, dev);// dev , , bus probe , drv probe, dev , 。
}
bus_for_each_dev 는 drv 와 등록 할 때 유사 합 니 다. bus 의 모든 dev 를 가 져 와 서 이 드라이브 와 일치 합 니 다.일치 하 는 방법 은driver_attach
총결산
전체적으로 말 하면 리 눅 스에 있 는 코드 가 정말 많 습 니 다. 모두 이해 하 는 것 은 정말 불가능 합 니 다. 이 글 을 포함 하여 저도 주제 와 관련 이 없 는 코드 와 내용 을 많이 삭 제 했 습 니 다.예 를 들 어 코드 에 디 버 깅 과 관련 된 파일 시스템 과 관련 된 내용 이 많 습 니 다. 저 는 붙 이지 않 았 습 니 다. 이런 내용 은 주로 / sys / class / 디 렉 터 리 에서 의 차원 관계 관리 이기 때문에 본 고의 주제 와 큰 관련 이 없 기 때문에 코드 를 보 는 것 도 마찬가지 입 니 다. 너무 관련 된 것 이 아니 라 직접적 으로 생략 합 니 다. 경험 이 유한 하기 때 문 입 니 다.그리고 어떤 것 이 관련 되 고 어떤 것 이 부차적인 것 인지 어떻게 판단 하 는 지 경험 을 잘 쌓 아야 합 니 다. 모든 일 에는 과정 이 있 습 니 다. 점점 익숙해 지고 접촉 을 많이 하면 의식 이 생 길 것 입 니 다.
후속
처음에 공부 할 때 도 인터넷 에서 자 료 를 찾 아 다른 사람의 이 해 를 먼저 보고 대체적인 주 된 부분 을 만 진 다음 에 스스로 코드 를 보고 정확 한 이해 여 부 를 검증 했다.많은 자 료 를 본 후에 이론 구 조 는 명확 하 게 말 했 지만 마음속 에 의문 이 하나 있다. 이 물건 을 어디 에 쓰 면 좋 을 지.말하자면 이론 과 실제 의 결합 이 부족 하 다 는 것 이다.그래서 저 는 뒤에 이 구동 모델 의 인 스 턴 스 플랫폼 버스 의 활용 을 소개 하 는 글 을 쓸 것 입 니 다.이론 과 실례 의 결합 분석 은 너 로 하여 금 이 지식 점 을 더욱 잘 이해 하 게 할 것 이다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Rails Turbolinks를 페이지 단위로 비활성화하는 방법원래 Turobolinks란? Turbolinks는 링크를 생성하는 요소인 a 요소의 클릭을 후크로 하고, 이동한 페이지를 Ajax에서 가져옵니다. 그 후, 취득 페이지의 데이터가 천이 전의 페이지와 동일한 것이 있...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.