fatfs/src/ff.c
FRESULT f_fdisk (
	BYTE pdrv,			/* Physical drive number */
	const DWORD* szt,	/* Pointer to the size table for each partitions */
	void* work			/* Pointer to the working buffer (null: use heap memory) */
)
{
	UINT i, n, sz_cyl, tot_cyl, b_cyl, e_cyl, p_cyl;
	BYTE s_hd, e_hd, *p, *buf = (BYTE*)work;
	DSTATUS stat;
	DWORD sz_disk, sz_part, s_part;
	FRESULT res;


	stat = disk_initialize(pdrv);
	if (stat & STA_NOINIT) return FR_NOT_READY;
	if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
	if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_disk)) return FR_DISK_ERR;

	buf = (BYTE*)work;
#if FF_USE_LFN == 3
	if (!buf) buf = ff_memalloc(FF_MAX_SS);	/* Use heap memory for working buffer */
#endif
	if (!buf) return FR_NOT_ENOUGH_CORE;

	/* Determine the CHS without any consideration of the drive geometry */
	for (n = 16; n < 256 && sz_disk / n / 63 > 1024; n *= 2) ;
	if (n == 256) n--;
	e_hd = (BYTE)(n - 1);
	sz_cyl = 63 * n;
	tot_cyl = sz_disk / sz_cyl;

	/* Create partition table */
	mem_set(buf, 0, FF_MAX_SS);
	p = buf + MBR_Table; b_cyl = 0;
	for (i = 0; i < 4; i++, p += SZ_PTE) {
		p_cyl = (szt[i] <= 100U) ? (DWORD)tot_cyl * szt[i] / 100 : szt[i] / sz_cyl;	/* Number of cylinders */
		if (p_cyl == 0) continue;
		s_part = (DWORD)sz_cyl * b_cyl;
		sz_part = (DWORD)sz_cyl * p_cyl;
		if (i == 0) {	/* Exclude first track of cylinder 0 */
			s_hd = 1;
			s_part += 63; sz_part -= 63;
		} else {
			s_hd = 0;
		}
		e_cyl = b_cyl + p_cyl - 1;	/* End cylinder */
		if (e_cyl >= tot_cyl) LEAVE_MKFS(FR_INVALID_PARAMETER);

		/* Set partition table */
		p[1] = s_hd;						/* Start head */
		p[2] = (BYTE)(((b_cyl >> 2) & 0xC0) | 1);	/* Start sector */
		p[3] = (BYTE)b_cyl;					/* Start cylinder */
		p[4] = 0x07;						/* System type (temporary setting) */
		p[5] = e_hd;						/* End head */
		p[6] = (BYTE)(((e_cyl >> 2) & 0xC0) | 63);	/* End sector */
		p[7] = (BYTE)e_cyl;					/* End cylinder */
		st_dword(p + 8, s_part);			/* Start sector in LBA */
		st_dword(p + 12, sz_part);			/* Number of sectors */

		/* Next partition */
		b_cyl += p_cyl;
	}
	st_word(p, 0xAA55);		/* MBR signature (always at offset 510) */

	/* Write it to the MBR */
	res = (disk_write(pdrv, buf, 0, 1) == RES_OK && disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR;
	LEAVE_MKFS(res);
}
/*-----------------------------------------------------------------------*/
/* Create Partition Table on the Physical Drive                          */
/*-----------------------------------------------------------------------*/
Create Partition Table on the Physical Drive
Create Partition Table on the Physical Drive
FRESULT f_fdisk (
	BYTE pdrv,			
	const DWORD* szt,	
	void* work			
)
{
	UINT i, n, sz_cyl, tot_cyl, b_cyl, e_cyl, p_cyl;
	BYTE s_hd, e_hd, *p, *buf = (BYTE*)work;
	DSTATUS stat;
	DWORD sz_disk, sz_part, s_part;
	FRESULT res;
	stat = disk_initialize(pdrv);
	if (stat & STA_NOINIT) return FR_NOT_READY;
	if (stat & STA_PROTECT) return FR_WRITE_PROTECTED;
	if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &sz_disk)) return FR_DISK_ERR;
	buf = (BYTE*)work;
#if FF_USE_LFN == 3
	if (!buf) buf = ff_memalloc(FF_MAX_SS);	
#endif
	if (!buf) return FR_NOT_ENOUGH_CORE;
	for (n = 16; n < 256 && sz_disk / n / 63 > 1024; n *= 2) ;
	if (n == 256) n--;
	e_hd = (BYTE)(n - 1);
	sz_cyl = 63 * n;
	tot_cyl = sz_disk / sz_cyl;
	mem_set(buf, 0, FF_MAX_SS);
	p = buf + MBR_Table; b_cyl = 0;
	for (i = 0; i < 4; i++, p += SZ_PTE) {
		p_cyl = (szt[i] <= 100U) ? (DWORD)tot_cyl * szt[i] / 100 : szt[i] / sz_cyl;	
		if (p_cyl == 0) continue;
		s_part = (DWORD)sz_cyl * b_cyl;
		sz_part = (DWORD)sz_cyl * p_cyl;
		if (i == 0) {	
			s_hd = 1;
			s_part += 63; sz_part -= 63;
		} else {
			s_hd = 0;
		}
		e_cyl = b_cyl + p_cyl - 1;	
		if (e_cyl >= tot_cyl) LEAVE_MKFS(FR_INVALID_PARAMETER);
		p[1] = s_hd;						
		p[2] = (BYTE)(((b_cyl >> 2) & 0xC0) | 1);	
		p[3] = (BYTE)b_cyl;					
		p[4] = 0x07;						
		p[5] = e_hd;						
		p[6] = (BYTE)(((e_cyl >> 2) & 0xC0) | 63);	
		p[7] = (BYTE)e_cyl;					
		st_dword(p + 8, s_part);			
		st_dword(p + 12, sz_part);			
		b_cyl += p_cyl;
	}
	st_word(p, 0xAA55);		
	res = (disk_write(pdrv, buf, 0, 1) == RES_OK && disk_ioctl(pdrv, CTRL_SYNC, 0) == RES_OK) ? FR_OK : FR_DISK_ERR;
	LEAVE_MKFS(res);
}
FRESULT f_fdisk ( BYTE pdrv , const DWORD * szt , void * work ) { UINT i , n , sz_cyl , tot_cyl , b_cyl , e_cyl , p_cyl ; BYTE s_hd , e_hd , * p , * buf = ( BYTE * ) work ; DSTATUS stat ; DWORD sz_disk , sz_part , s_part ; FRESULT res ; stat = disk_initialize ( pdrv ) ; if ( stat & STA_NOINIT ) return FR_NOT_READY ; if ( stat & STA_PROTECT ) return FR_WRITE_PROTECTED ; if ( disk_ioctl ( pdrv , GET_SECTOR_COUNT , & sz_disk ) ) return FR_DISK_ERR ; buf = ( BYTE * ) work ; #if FF_USE_LFN == 3 if ( ! buf ) buf = ff_memalloc ( FF_MAX_SS ) ; #endif if ( ! buf ) return FR_NOT_ENOUGH_CORE ; for ( n = 16 ; n < 256 && sz_disk / n / 63 > 1024 ; n *= 2 ) ; if ( n == 256 ) n -- ; e_hd = ( BYTE ) ( n - 1 ) ; sz_cyl = 63 * n ; tot_cyl = sz_disk / sz_cyl ; mem_set ( buf , 0 , FF_MAX_SS ) ; p = buf + MBR_Table ; b_cyl = 0 ; for ( i = 0 ; i < 4 ; i ++ , p += SZ_PTE ) { p_cyl = ( szt [ i ] <= 100U ) ? ( DWORD ) tot_cyl * szt [ i ] / 100 : szt [ i ] / sz_cyl ; if ( p_cyl == 0 ) continue ; s_part = ( DWORD ) sz_cyl * b_cyl ; sz_part = ( DWORD ) sz_cyl * p_cyl ; if ( i == 0 ) { s_hd = 1 ; s_part += 63 ; sz_part -= 63 ; } else { s_hd = 0 ; } e_cyl = b_cyl + p_cyl - 1 ; if ( e_cyl >= tot_cyl ) LEAVE_MKFS ( FR_INVALID_PARAMETER ) ; p [ 1 ] = s_hd ; p [ 2 ] = ( BYTE ) ( ( ( b_cyl >> 2 ) & 0xC0 ) | 1 ) ; p [ 3 ] = ( BYTE ) b_cyl ; p [ 4 ] = 0x07 ; p [ 5 ] = e_hd ; p [ 6 ] = ( BYTE ) ( ( ( e_cyl >> 2 ) & 0xC0 ) | 63 ) ; p [ 7 ] = ( BYTE ) e_cyl ; st_dword ( p + 8 , s_part ) ; st_dword ( p + 12 , sz_part ) ; b_cyl += p_cyl ; } st_word ( p , 0xAA55 ) ; res = ( disk_write ( pdrv , buf , 0 , 1 ) == RES_OK && disk_ioctl ( pdrv , CTRL_SYNC , 0 ) == RES_OK ) ? FR_OK : FR_DISK_ERR ; LEAVE_MKFS ( res ) ; }
Create Partition Table on the Physical Drive
Create Partition Table on the Physical Drive
/* Physical drive number */ /* Pointer to the size table for each partitions */ /* Pointer to the working buffer (null: use heap memory) */ /* Use heap memory for working buffer */ /* Determine the CHS without any consideration of the drive geometry */ /* Create partition table */ /* Number of cylinders */ /* Exclude first track of cylinder 0 */ /* End cylinder */ /* Set partition table */ /* Start head */ /* Start sector */ /* Start cylinder */ /* System type (temporary setting) */ /* End head */ /* End sector */ /* End cylinder */ /* Start sector in LBA */ /* Number of sectors */ /* Next partition */ /* MBR signature (always at offset 510) */ /* Write it to the MBR */