forked from xuzhongxing/fuchsia-notes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fshost.txt
274 lines (202 loc) · 11.1 KB
/
fshost.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
fshost是文件系统服务进程。
zircon/system/core/devmgr/fshost.c: main()
_fs_root = zx_get_startup_handle(PA_HND(PA_USER0, 0));
拿到与devmgr通信通道
devfs_root = zx_get_startup_handle(PA_HND(PA_USER0, 1));
svc_root = zx_get_startup_handle(PA_HND(PA_USER0, 2));
zx_handle_t devmgr_loader = zx_get_startup_handle(PA_HND(PA_USER0, 3));
这个是fshost为devmgr提供loader服务的handle
fshost_event = zx_get_startup_handle(PA_HND(PA_USER1, 0));
fshost_start();
setup_bootfs();
把/boot下的内容从bootdata里提出来
setup_bootfs_vmo()
system分区也是直接映射在内存里的vmo
zx_vmar_map(zx_vmar_root_self(), 0, vmo, 0, size, ZX_VM_FLAG_PERM_READ, &address);
映射vmo
bootfs_create(&bfs, bootfs_vmo)
这里把复制的bootfs vmo映射好
bootfs_parse(&bfs, callback, &cd);
vfs_global_init(vfs_create_global_root());
vfs_create_global_root()
创建memfs的根"<root>"
memfs::global_vfs_root = root;
fuchsia_start()
zx_object_signal(fshost_event, 0, FSHOST_SIGNAL_READY);
vfs_connect_global_root_handle(_fs_root);
vfs_connect_root_handle(memfs::global_vfs_root, h);
vn->vfs()->ServeDirectory(fbl::RefPtr<fs::Vnode>(vn), fbl::move(ch));
vn->Serve(this, fbl::move(channel), ZX_FS_RIGHT_ADMIN);
vfs->ServeConnection(fbl::make_unique<Connection>(
vfs, fbl::WrapRefPtr(this), fbl::move(channel), flags));
connection->Serve()
wait_.set_object(channel_.get());
return wait_.Begin(vfs_->async());
vfs处理消息的入口实际上在Connection::HandleMessage(zxrio_msg_t* msg)
fs_root = fs_root_clone()
vfs_create_global_root_handle(&h)
zx::channel::create(0, &h1, &h2)
vn->vfs()->ServeDirectory(fbl::RefPtr<fs::Vnode>(vn),
fbl::move(h1))
*out = h2.release()
fs_root是通道的一头
fdio_ns_bind(ns, "/system", fs_clone("system"))
zx_channel_create(0, &h0, &h1)
fdio_open_at(fs_root, path, FS_DIR_FLAGS, h1)
zxrio_connect(dir, h, ZXRIO_OPEN, flags, 0755, path)
把h1发送给fs_root另一头的事件处理
return h0
要创建loader service的服务端口了
loader_service_create_fs(NULL, &loader_service)
loader_service_create_default(async, root_dir_fd, -1, fs_lib_paths,out);
loader_service_create(async, &fd_ops, NULL, &svc);
loader_service_addref(svc);
loader_service_attach(loader_service, devmgr_loader);
block_device_watcher(zx_job_default(), netboot);
在添加了block device之后,根据块设备类型bind相应的block设备驱动
fd = openat(dirfd, name, O_RDWR)
vopenat(dirfd, path, flags, ap);
__fdio_open_at(&io, dirfd, path, flags, mode)
iodir = fdio_iodir(&path, dirfd)
iodir->ops->open(iodir, clean, fdio_flags_to_zxio(flags), mode, io);
==mxdir_open(fdio_t* io, const char* path,uint32_t flags, uint32_t mode,fdio_t** out)
zxrio_open_handle(vn->remote, path, flags, mode, out);
zxrio_getobject(h, ZXFIDL_OPEN, path, flags, mode, &info, &control_channel)
fdio_from_handles(control_channel, &info.extra, out)
io = fdio_remote_create(handle, 0);
rio->io.ops = &zx_remote_ops;
fd = fdio_bind_to_fd(io, -1, 0)
如果是netboot则只处理partition containers
如果是普通启动,则处理fvm里的分区类型
mount(fd, "/fs" PATH_BLOB, DISK_FORMAT_BLOBFS, &options, launch_blobfs);
"/fs"被bind到root fs上
fmount(device_fd, mount_point.get(), df, options, cb);
mounter.Mount(unique_fd(device_fd), df, *options, cb);
MountNativeFs("/boot/bin/blobfs", fbl::move(device), options, cb);
PrepareHandles(fbl::move(device));
fdio_transfer_fd(device_fd, FS_FD_BLOCKDEVICE, &handles_[1], &ids_[1]);
fdio_unbind_from_fd(fd, &io)
把blobfs分区解除bind
io->ops->unwrap(io, handles, types)
==zxrio_unwrap
把这个remote io里封装的handle拿出来
把分区设备对应的远程channel handle拿到
argv = "/boot/bin/blobfs mount"
LaunchAndMount(cb, options, argv, argc);
cb(argc, argv, handles_, ids_, num_handles_)
==launch_blobfs
devmgr_launch(job, "blobfs:/blob",&fshost_launch_load, NULL, argc, argv, NULL, -1,hnd, ids, len, NULL, FS_FOR_FSPROC);
转入blobfs.txt
然后会等待blobfs ready
root_是和mountee handle相通的
ioctl_vfs_mount_fs(fd_, &root_)
Vfs::Ioctl
Vfs::InstallRemote(vn, fbl::move(h));
vn->AttachRemote(fbl::move(h)
launch_blob_init();
pkgfs_launch
cmd = "bin/pkgsvr+1cef414eec640908458393fa66f69d96a6cf2bd9220a86ae805b8eec6c672a14"
devmgr_launch_cmdline("fshost", job, "pkgfs",
&pkgfs_launch_load, (void*)(intptr_t)fs_blob_fd, cmd,
&h1, (const uint32_t[]){ PA_HND(PA_USER0, 0) }, 1,
&proc, FS_DATA | FS_BLOB | FS_SVC);
devmgr_launch(job, name, load, ctx, argc, (const char* const*)argv, NULL, -1,
handles, types, hcount, proc, flags);
pkgfs_launch_load
pkgfs_ldsvc_load_blob(ctx, "", file, &vmo);
vmo是bin/pkgsvr
通过env zircon.system.pkgfs.file.bin/pkgsvr 从blobfs里加载的
pkgfs_ldsvc_start(fs_blob_fd, &ldsvc);
loader_service_create(NULL, &pkgfs_ldsvc_ops,
(void*)(intptr_t)fs_blob_fd,
&service);
创建一个loader service
这个service会借助pkgfs_ldsvc_load_object,以及devmgr_config.txt里定义的
环境变量(包含了hash)来加载ld.so.1
这个是pkgsvr的dynlink.c阶段要使用的load service, 它需要从blobfs里加载ld.so.1
loader_service_connect(service, ldsvc);
launchpad_use_loader_service(lp, ldsvc);
把这个service handle发送给pkgsvr
launchpad_load_from_vmo(lp, vmo);
加载bin/pkgsvr
launchpad_go(lp, proc, &errmsg)
pkgfs_finish(proc, h0);
fdio_open_at(pkgfs_root, "system", FS_DIR_FLAGS, h1)
打开pkgfs里的system目录
vfs_install_fs("/system", h0)
然后挂在/system下面
fuchsia_start
======
fs_clone("system")
当root vfs收到ZXRIO_OPEN之后:
vfs_是root_vfs
vnode_是global_root VnodeDir
比如path="system"
Connection::HandleMessage(zxrio_msg_t* msg)
OpenAt(vfs_, vnode_, fbl::move(channel), fbl::StringPiece(path, len), flags, mode);
vfs->Open(fbl::move(parent), &vnode, path, &path, open_flags, mode);
OpenLocked(fbl::move(vndir), out, path, pathout, flags, mode);
Vfs::Walk(vndir, &vndir, path, &path)
这里返回的vndir是要打开的路径的父目录
vfs_name_trim(path, &path, &must_be_dir)
vfs_lookup(fbl::move(vndir), &vn, path);
vn->Lookup(out, name);
得到system目录对应的vnode
vnode->Serve(vfs, fbl::move(channel), open_flags);
vfs->ServeConnection(fbl::make_unique<Connection>(
vfs, fbl::WrapRefPtr(this), fbl::move(channel), flags));
====
devmgr_config.txt有个这个配置:
zircon.system.pkgfs.cmd=bin/pkgsvr+1cef414eec640908458393fa66f69d96a6cf2bd9220a86ae805b8eec6c672a14会让fshost执行pkgsvr
[25123/25205] /usr/bin/env ../../build/images/manifest.py
--output=obj/build/images/devmgr_config.txt
--entry=devmgr.require-system=true
--contents
--rewrite=\*=zircon.system.pkgfs.cmd=\{target\}+\{source\}
--entry=bin/pkgsvr=obj/build/images/system_image.meta/meta.far.merkle
--no-contents
--reset-rewrite
--rewrite=\*=zircon.system.pkgfs.file.\{target\}=\{source\}
--manifest=obj/garnet/go/src/pmd/pkgsvr.meta/meta/contents
--reset-rewrite
--include=bin/devhost.asan
--include=bin/devhost
--rewrite=bin/devhost.asan=devmgr.devhost.asan=true
--rewrite=bin/devhost=devhost.asan.strict=false
--manifest=obj/build/images/boot.manifest
obj/build/images/blob_merkleroot.manifest:1cef414eec640908458393fa66f69d96a6cf2bd9220a86ae805b8eec6c672a14=obj/build/images/system_image.meta/meta.far
pkgsvr在garnet/go下面
====
obj/build/images/system_image.meta/meta.far
这个文件是system文件系统清单,被包括在blob.manifest里
它的来历:
由pm生成
[25121/25205] /usr/bin/env ../../build/gn_run_binary.sh ../../buildtools/linux-x64/clang/bin host_x64/pm
-k ../../build/development.key
-o obj/build/images/system_image.meta
-m obj/build/images/system_image.manifest build
-depfile
====
system_image.manifest由monolith package生成。topaz/products/default包含了所有的package
具体见build/gn/packages.gni
system_image.manifest的具体的命令行是rsp文件,太长
====
pkgfs_finish里会把/pkgfs/system重新导出为/system
/pkgfs/package目录下的内容是由obj/build/images/pkgsvr_index规定的
[25114/25205] /usr/bin/env ../../build/images/manifest.py
--contents
--output=obj/build/images/pkgsvr_index
@obj/peridot/bin/agents/clipboard/clipboard_agent.pkgsvr_index.rsp
@obj/topaz/bin/ermine/config.pkgsvr_index.rsp
@obj/garnet/bin/debugserver/debugserver.pkgsvr_index.rsp
@obj/peridot/tests/queue_persistence/queue_persistence_test_agent.pkgsvr_index.rsp
@obj/peridot/tests/chain/chain_test_child_module.pkgsvr_index.rsp
@obj/garnet/bin/http/http.pkgsvr_index.rsp
@obj/topaz/examples/mondrian_test/mondrian_test.pkgsvr_index.rsp
@obj/peridot/bin/device_runner_monitor/device_runner_monitor.pkgsvr_index.rsp
@obj/garnet/drivers/bluetooth/hci/passthrough/bthci_passthrough.pkgsvr_index.rsp
...
zircon.system.pkgfs.cmd=bin/pkgsvr+3dc81b791f8399af55fa0ce7616d99f8f1097164ac134181706e287f8a16412c
zircon.system.pkgfs.file.bin/pkgsvr=fe8f07e0750162db30cb46e8d2de2f766334dd0a1801bbb004c33165eb7f8310
zircon.system.pkgfs.file.lib/ld.so.1=2bf62c6046947e2dc25a90931627f9b98315d5de0f7ed52927ea2e6bd3d4eb28
zircon.system.pkgfs.file.lib/libfdio.so=18f12ca1964442473363cdfa631550d2a48ae4d96a347946cf7acbb342cf30d8