-(* Iterate dev_base_head -> list_head dev_list -> ... *)
-and do_dev_list image kernel_version dev_base_head offset size =
- (* The list_head points into the middle of the structure.
- * Adjust this address to point to the start of the
- * structure.
- *)
- let addr = Int64.sub dev_base_head (Int64.of_int offset) in
-
- printf "do_dev_list, size = %d\n" size;
-
- let image =
- let rec loop image addr =
- let mapped = Virt_mem_mmap.is_mapped_range image.mem addr size in
- let image =
- if not mapped then
- Virt_mem_types.load_memory image addr size
- else
- image in
- let dev = get_net_device kernel_version image.mem addr in
- printf "net_device_name = %S\n" dev.net_device_name;
- let addr = Option.get dev.net_device_dev_list'next in
- if addr <> dev_base_head then
- loop image addr
- else
- image
- in
- loop image addr in
- image, Some dev_base_head
+(* Map dev_base_head -> list_head dev_list -> ... *)
+and map_dev_list kernel_version image lh_addr f =
+ let { field_offset = offset } =
+ field_signature_of_net_device_dev_list'next kernel_version in
+ let lh = Virt_mem_list_head.create image lh_addr offset in
+
+ let size = net_device_size kernel_version in
+ let image, lh = Virt_mem_list_head.load_all lh size in
+
+ let net_devices, _ =
+ Virt_mem_list_head.fold lh ([], 0) (
+ fun (net_devices, i) addr ->
+ if i > max_net_devices then
+ failwith (sprintf (f_"%s: too many network devices") image.domname);
+
+ let net_device = get_net_device kernel_version image.mem addr in
+ let net_devices = f net_device :: net_devices in
+ (net_devices, i+1)
+ ) in
+
+ image, net_devices