3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
4 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include <partition.h>
28 partition_t partition_list
;
29 extern vfs_t vfs_list
;
31 partition_t
*partition_find (char *name
)
33 partition_t
*partition
;
34 for (partition
= partition_list
.next
; partition
!= &partition_list
; partition
= partition
->next
) {
35 if (!strcmp (partition
->name
, name
))
42 /* limited only for _one_ partition per device */
43 partition_t
*partition_findbydev (dev_t
*dev
)
45 unsigned l
= strlen (dev
->devname
);
47 partition_t
*partition
;
48 for (partition
= partition_list
.next
; partition
!= &partition_list
; partition
= partition
->next
) {
49 if (!strncmp (partition
->name
, dev
->devname
, l
))
56 /* find partition by file in current directory */
57 partition_t
*partition_findbyfile (char *file
)
60 strcpy (pwd
, (char *) env_get ("PWD"));
63 for (vfs
= vfs_list
.next
; vfs
!= &vfs_list
; vfs
= vfs
->next
)
64 //printf ("pwd: %s : %s\n", vfs->mountpoint, pwd);
65 if (!strcmp (vfs
->mountpoint
, pwd
) &&
66 !cstrcmp (file
, vfs
->name
)) {
67 if (vfs
->attrib
& VFS_FILEATTR_DIR
) {
68 printf ("ERROR -> this is a directory, not an file\n");
72 /* check permissions */
73 if (vfs
->attrib
& VFS_FILEATTR_SYSTEM
&& strcmp ((char *) env_get ("USER"), "root")) {
74 printf ("ERROR -> only root can do that\n");
78 if (vfs
->attrib
& VFS_FILEATTR_MOUNTED
) {
79 partition_t
*p
= (partition_t
*) mount_find ((char *) env_get ("PWD"));
84 printf ("ERROR -> device not respond\n");
94 printf ("No such file : %s\n", file
);
99 partition_t
*partition_add (dev_t
*dev
, fs_t
*fs
, unsigned sector
)
106 for (i
= 0; i
< 256; i
++) {
107 sprintf (name
, "%s%u", dev
->devname
, i
);
109 if (partition_find (name
) == 0)
113 kprintf ("-> %s\n", name
);
115 partition_t
*partition
;
117 /* alloc and init context */
118 partition
= (partition_t
*) kmalloc (sizeof (partition_t
));
123 memset (partition
, 0, sizeof (partition_t
));
125 strcpy (partition
->name
, name
);
129 /* check for hd'c' name - hda, hdb are pair of first cable; hdc, hdb are pair of second cable */
130 if (strlen (dev
->devname
) > 7) {
131 if (dev
->devname
[7] < 'c')
132 partition
->base_io
= 0x1F0;
134 partition
->base_io
= 0x170;
136 partition
->base_io
= 0;
139 partition
->fs
= (fs_t
*) fs_detect (partition
);
143 if (!partition
->fs
) {
148 /* first partition sector on hdd */
149 partition
->sector_start
= sector
;
151 if (!partition
->fs
->handler
) {
152 kprintf ("ERROR -> fs handler is missing !\n");
157 if (!partition
->fs
->handler (FS_ACT_INIT
, (char *) partition
, NULL
, NULL
)) {
163 partition
->next
= &partition_list
;
164 partition
->prev
= partition_list
.prev
;
165 partition
->prev
->next
= partition
;
166 partition
->next
->prev
= partition
;
171 bool partition_del (partition_t
*partition
)
174 partition
->next
->prev
= partition
->prev
;
175 partition
->prev
->next
= partition
->next
;
184 unsigned partition_table (dev_t
*dev
)
186 unsigned char block
[512];
191 unsigned l
= strlen (dev
->devname
);
199 switch (dev
->devname
[7]) {
218 /* read first sector from drive */
219 if (!dev
->handler (DEV_ACT_READ
, &p
, block
, "", 0))
223 for (i
= 0; i
< 4; i
++) {
224 /* calculate MBR partition table address */
225 ptable_t
*table
= (ptable_t
*) ((void *) block
+ 446 + i
* sizeof (ptable_t
));
230 kprintf ("-> partition type %x - 0x%x (%d)\n", table
->type
, table
->lba
, table
->blocks
);
232 partition_t
*pnew
= 0;
234 switch (table
->type
) {
236 pnew
= partition_add (dev
, fs_supported ("ext2"), table
->lba
);
239 pnew
= partition_add (dev
, fs_supported ("zexfs"), table
->lba
);
247 unsigned partition_table_new (dev_t
*dev
, ptable_t
*ntable
)
249 unsigned char block
[512];
254 unsigned l
= strlen (dev
->devname
);
262 switch (dev
->devname
[7]) {
281 /* read first sector from drive */
282 if (!dev
->handler (DEV_ACT_READ
, &p
, block
, "", 0))
286 for (i
= 0; i
< 4; i
++) {
287 /* calculate MBR partition table address */
288 ptable_t
*table
= (ptable_t
*) ((void *) block
+ 446 + i
* sizeof (ptable_t
));
290 /* when partition type is filled, rewrite old entry */
292 memcpy (table
, &ntable
[i
], sizeof (ptable_t
));
294 memcpy (&ntable
[i
], table
, sizeof (ptable_t
));
296 DPRINT (DBG_FS
, "-> partition type %x - 0x%x (%d)", table
->type
, table
->lba
, table
->blocks
);
299 /* write into first sector of drive */
300 if (!dev
->handler (DEV_ACT_WRITE
, &p
, block
, "", 0))
306 unsigned int init_partition ()
308 partition_list
.next
= &partition_list
;
309 partition_list
.prev
= &partition_list
;