# nvdimm\_bus

说实话，对于nvdimm\_bus中的成员含义还知之甚少。不过暂时还不影响对这个结构体生成过程的理解。

## 函数原型揭示的秘密

首先我们看一下创建nvdimm\_bus这个结构调用的函数，看看它能带给我们什么信息：

```
struct nvdimm_bus *nvdimm_bus_register(struct device *parent,
		struct nvdimm_bus_descriptor *nd_desc)
```

从总可以看到，生成nvdimm\_bus结构体需要两个成员：

* parent: 父节点
* nd\_desc:描述信息

父节点含义很明确，那这个描述信息是什么，在哪里呢？

## 数据结构的关联

从数据结构的角度上看，刚才的问题就可以从acpi\_nfit\_desc结构体中找到：

```
    acpi_nfit_desc
    +-----------------------------------------------+
    |dev                                            | = point to an acpi_device
    |    (struct device*)                           |
    +-----------------------------------------------+
    |acpi_header                                    |
    |    (struct acpi_table_header)                 |
    +-----------------------------------------------+
    |nd_desc                                        | *  <-----------------------------------+
    |    (struct nvdimm_bus_descriptor)             |                                        |
    |    +------------------------------------------+                                        |
    |    |attr_groups                               | = acpi_nfit_attribute_groups           |
    |    |      (struct attribute_group**)          |                                        |
    |    |provider_name                             | = "ACPI.NFIT"                          |
    |    |      (char *)                            |                                        |
    |    |                                          |                                        |
    |    +------------------------------------------+                                        |
    |    |ndctl                                     | = acpi_nfit_ctl                        |
    |    |      (ndctl_fn)                          |                                        |
    |    |flush_probe                               | = acpi_nfit_flush_probe                |
    |    |clear_to_send                             | = acpi_nfit_clear_to_send              |
    |    |                                          |                                        |
    |    +------------------------------------------+                                        |
    |nvdimm_bus                                     | *                                      |
    |    (struct nvdimm_bus*)                       |                                        |
    |    +------------------------------------------+                                        |
    |    |nd_desc                                   | point to the above nd_desc  -----------+
    |    |      (struct nvdimm_bus_descriptor*)     |
    |    |dev                                       |
    |    |      (struct device)                     |
    |    |      +-----------------------------------+
    |    |      |name                               | "ndbus%d"
    |    |      |groups                             | = nd_desc->attr_groups
    |    |      |release                            | = nvdimm_bus_release
    |    |      |                                   |
    |    |      +-----------------------------------+
    |    |list                                      |
    |    |mapping_list                              |
    |    |      (struct list_head)                  |
    |    |                                          |
    +----+------------------------------------------+
```

可以看出，用来创建nvdimm\_bus的描述信息nd\_desc是在acpi\_nfit\_desc中的。这么看是不是感觉清楚了一点点？

## nd\_bus\_driver -> /dev/ndctl0

nvdimm\_bus设备生成之后接下去的事情就交给了对应的驱动 nd\_bus\_driver。这个驱动超级简单，但是作用倒是有点。

```
int nvdimm_bus_create_ndctl(struct nvdimm_bus *nvdimm_bus)
{
	dev_t devt = MKDEV(nvdimm_bus_major, nvdimm_bus->id);
	struct device *dev;

	dev = device_create(nd_class, &nvdimm_bus->dev, devt, nvdimm_bus,
			"ndctl%d", nvdimm_bus->id);

	if (IS_ERR(dev))
		dev_dbg(&nvdimm_bus->dev, "failed to register ndctl%d: %ld\n",
				nvdimm_bus->id, PTR_ERR(dev));
	return PTR_ERR_OR_ZERO(dev);
}
```

可以看到主要的工作就是创建了/dev/ndctl%d设备。这下终于知道这个设备文件是如何来的了。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://richardweiyang-2.gitbook.io/kernel-exploring/00-brief_navigation/02-nvdimm_bus.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
