1 /* $NetBSD: ustarfs.c,v 1.7 2008/04/28 20:23:19 martin Exp $ */
4 * Copyright (c) 2004 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <lib/libsa/stand.h>
33 #include <lib/libkern/libkern.h>
35 #include <machine/param.h>
36 #include <machine/sbd.h>
37 #include <machine/sector.h>
42 static bool __ustarfs_file(int, char *, size_t *);
43 static bool __block_read(uint8_t *, int);
44 static bool __block_read_n(uint8_t *, int, int);
45 static void __change_volume(int);
46 static int __block2volume(int);
47 static int __volume_offset(int);
48 static int __next_block(int);
50 enum { USTAR_BLOCK_SIZE
= 8192 };/* Check src/distrib/common/buildfloppies.sh */
57 ustarfs_load(const char *file
, void **addrp
, size_t *sizep
)
64 if (DEVICE_CAPABILITY
.active_device
== NVSRAM_BOOTDEV_HARDDISK
)
65 maxblk
= 0x1fffffff; /* no limit */
66 else if (DEVICE_CAPABILITY
.active_device
== NVSRAM_BOOTDEV_FLOPPYDISK
)
68 * Although phisical format isn't 2D, volume size is
69 * limited to size of 2D.
71 maxblk
= (77 + 76) * 13;
73 printf("not supported device.\n");
77 /* Truncate to ustar block boundary */
78 __volume
.max_block
= (maxblk
/ (USTAR_BLOCK_SIZE
>> DEV_BSHIFT
)) *
79 (USTAR_BLOCK_SIZE
>> DEV_BSHIFT
);
80 __volume
.current_volume
= 0;
83 while (/*CONSTCOND*/1) {
84 if (!__ustarfs_file(block
, fname
, &sz
))
87 if (strcmp(file
, fname
) == 0)
89 block
+= (ROUND_SECTOR(sz
) >> DEV_BSHIFT
) + 1;
91 block
++; /* skip tar header */
95 sz
= ROUND_SECTOR(sz
);
96 if ((*addrp
= alloc(sz
)) == 0) {
97 printf("%s: can't allocate memory.\n", __func__
);
101 if (!__block_read_n(*addrp
, block
, sz
>> DEV_BSHIFT
)) {
102 printf("%s: can't load file.\n", __func__
);
111 __ustarfs_file(int start_block
, char *file
, size_t *size
)
115 if (!__block_read(buf
, start_block
)) {
116 printf("can't read tar header.\n");
119 if (((*(uint32_t *)(buf
+ 256)) & 0xffffff) != 0x757374) {
120 printf("bad tar magic.\n");
123 *size
= strtoul((char *)buf
+ 124, 0, 0);
124 strncpy(file
, (char *)buf
, 16);
130 __block_read_n(uint8_t *buf
, int blk
, int count
)
135 vol
= __block2volume(blk
);
136 if (vol
!= __volume
.current_volume
) {
137 __change_volume(vol
);
138 __volume
.current_volume
= vol
;
141 cnt
= __next_block(vol
) - blk
;
145 if (!sector_read_n(0, buf
, __volume_offset(blk
), cnt
))
149 buf
+= cnt
* DEV_BSIZE
;
156 __block_read(uint8_t *buf
, int blk
)
160 vol
= __block2volume(blk
);
162 if (vol
!= __volume
.current_volume
) {
163 __change_volume(vol
);
164 __volume
.current_volume
= vol
;
167 return sector_read(0, buf
, __volume_offset(blk
));
171 __change_volume(int volume
)
176 while (/*CONSTCOND*/1) {
177 printf("insert disk %d, and press return...", volume
+ 1);
178 while (getchar() != '\r')
181 if (!sector_read(0, buf
, 0))
183 if (*(uint32_t *)buf
!= 0x55535441) { /* "USTAR" */
184 printf("invalid magic.\n");
187 if ((i
= buf
[8] - '0') != volume
+ 1) {
188 printf("invalid volume number. disk=%d requested=%d\n",
197 __block2volume(int blk
)
200 if (blk
< __volume
.max_block
)
203 blk
-= __volume
.max_block
;
205 return (blk
/ (__volume
.max_block
- 16)) + 1;
209 __volume_offset(int blk
)
212 if (blk
< __volume
.max_block
)
215 blk
-= __volume
.max_block
;
217 return blk
% (__volume
.max_block
- 16) + 16;
221 __next_block(int vol
)
224 return __volume
.max_block
+ vol
* (__volume
.max_block
- 16);