Skip to content

Commit

Permalink
. fat 支持长文件名(只限英文)。支持将镜象格式化为卷或者磁盘。
Browse files Browse the repository at this point in the history
. ntboot 支持网起 wim。例:/efi/grub/ext/ntboot (http)/boot/imgs/boot.wim
  • Loading branch information
yaya2007 committed Dec 16, 2024
1 parent 41bd293 commit 8df8b3f
Show file tree
Hide file tree
Showing 10 changed files with 422 additions and 260 deletions.
19 changes: 9 additions & 10 deletions g4eext/ChangeLog.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
更新说明:
2024-12-08 (a1ive)
增加适用于 G4E 的 iPXE wimboot,用于启动 wim 文件。
BIOS 版与 EFI 版的该文件完全相同,只保留一份即可。
示例:
title boot wim
kernel /EFI/grub/wimboot
initrd @bootx64.efi=/ms/bootmgfw.efi @bcd=/ms/bcd @boot.sdi=/ms/boot.sdi @wgl4_boot.ttf=/ms/wgl4_boot.ttf initrd @aaaa.bat=/ms/start.bat @boot.wim=/ms/winpe.wim
2024-12-16 (yaya)
1. fat 支持长文件名(只限英文)。支持将镜象格式化为卷或者磁盘。
2. ntboot 支持网起 wim。例:/efi/grub/ext/ntboot (http)/boot/imgs/boot.wim

2023-11-27 (yaya)
1. ntboot增加 --test 参数,用于产生一个启动 wim 的 bcd 实例。
可以在虚拟机网起环境执行。其他情况要在实机执行,因为一般虚拟机是只读的。
示例:ntboot /boot/imgs/pe64.wim
示例:ntboot --test /boot/imgs/pe64.wim

2. 增加函数 WIMname。用于 pxe 网起 wim 时,修改 bcd 文件内的 wim 文件名称。
示例:/efi/grub/ext/wimname /boot/imgs/pe64.wim
Expand Down Expand Up @@ -97,7 +93,7 @@ chkpci
fat
在FAT分区上复制创建文件

FAT命令的目标对象必须是FAT12/16/32分区的目录和文件,目前只支持8.3格式
FAT命令的目标对象必须是FAT12/16/32分区的目录和文件

FAT mkdir
创建一个目录,只能一级一级建立目录,不可以同时建立多级目录;
Expand Down Expand Up @@ -131,8 +127,11 @@ FAT mkfile size=SIZE|* file
SIZE是文件大小,可以直接用*代替,大小等于上一个cat —length=0命令的结果。
注:cat --length=0 file命令在GRUB4DOS中用于获取指定文件的大小。

FAT mkfs [/A:unit-size]
FAT mkfs [/A:unit-size] [mbr] 驱动器
格式化磁盘
/A:unit-size:指定一簇的字节尺寸,如 /A:4096。可以变相设置 FAT16/FAT32。
mbr:硬盘格式,即有主分区。
驱动器:如(0),(rd),(hd),(hd1,2)等等

FAT dir [/a*]
列出路径下所有文件及目录。
Expand Down
113 changes: 74 additions & 39 deletions g4eext/fat/fat.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@
* to get this source code & binary: http://grub4dos-chenall.google.com
* For more information.Please visit web-site at http://chenall.net
* 2010-06-24
* 2010-06-24 添加获取当前时间代码.修正dir显示时间日期错误.copy时按原文件复制禁用GRUB4DOS的自动解压功能
* 2010-07-27 减小读取文件次数,解决复制PXE服务器上的文件卡死的问题。
* 2010-06-24 添加获取当前时间代码.修正dir显示时间日期错误.copy时按原文件复制禁用GRUB4DOS的自动解压功能
* 2010-07-27 减小读取文件次数,解决复制PXE服务器上的文件卡死的问题。
*/
#include "grub4dos.h"
#include "fat.h"
Expand Down Expand Up @@ -104,7 +104,7 @@ main (char *arg,int flags)
// if (*(int *)0x8278 < 20101228)
if (*(int *)IMG(0x8278) < 20101228)
{
return !printf("Err grub4dos version\n");
return !printf_errinfo("Err grub4dos version\n");
}

int ret=fat_func (arg , flags);
Expand All @@ -119,9 +119,9 @@ main (char *arg,int flags)

/*
Inidialize a Drive for FatFs Module.
因为GRUB4DOS同一时刻只能访问一个磁盘,操作了其它磁盘以后必须重新初始化FAT磁盘才能使FAT模块正常使用
程序的FatFs Module都是直接针对某个GRUB4DOS磁盘分区的访问,而非整个磁盘。
注:2010-06-03已经整合到diskio函数中了。
因为GRUB4DOS同一时刻只能访问一个磁盘,操作了其它磁盘以后必须重新初始化FAT磁盘才能使FAT模块正常使用
程序的FatFs Module都是直接针对某个GRUB4DOS磁盘分区的访问,而非整个磁盘。
注:2010-06-03已经整合到diskio函数中了。
*/
/*
static int fat_init (void)
Expand All @@ -139,7 +139,7 @@ static int fat_init (void)
}
*/
/*
FatFs Module模块不能直接使用带有盘符信息的GRUB4DOS路径,所以必须分离命令行路径参数的磁盘号和目录提供给FAT模块使用。
FatFs Module模块不能直接使用带有盘符信息的GRUB4DOS路径,所以必须分离命令行路径参数的磁盘号和目录提供给FAT模块使用。
*/
static char* fat_set_path(char *arg);
static char* fat_set_path(char *arg)
Expand All @@ -151,7 +151,7 @@ static char* fat_set_path(char *arg)
}
if (! set_device (arg)) return 0;
// if (! *(++P)) return 0;
/*设置要操作的FAT分区磁盘号和分区号供FatFs模块使用*/
/*设置要操作的FAT分区磁盘号和分区号供FatFs模块使用*/
cur_drive = current_drive;
cur_partition = current_partition;
return strstr(arg,"/");
Expand Down Expand Up @@ -212,7 +212,7 @@ static FRESULT fat_dir (char *arg)
}

if (arg = fat_set_path(arg))
{ /*去掉目录后面的"/",如果有加"/",f_opendir会找不到文件*/
{ /*去掉目录后面的"/",如果有加"/",f_opendir会找不到文件*/
char *P;
for (P = arg;P[1];P++);
if (*P == '/') *P = 0;
Expand All @@ -222,19 +222,19 @@ static FRESULT fat_dir (char *arg)
res = f_opendir(&dir,arg?arg:"");
if (res) return res;

printf("FAT dir:[%s]\n",arg?arg:"/");
printf_debug("FAT dir:[%s]\n",arg?arg:"/");

for (;;)
{
res = f_readdir (&dir, &fno);
if (res || fno.fname[0] == 0) break;
if (fno.fname[0] == '.' || (fno.fattrib & no_attr) || ((fno.fattrib & Attrib) != Attrib)) continue;
printf("%04d-%02d-%02d %02d:%02d:%02d ",(fno.fdate >> 9) + 1980,fno.fdate >> 5 & 15,fno.fdate & 31,fno.ftime >> 11 & 31,fno.ftime >> 5 & 63,fno.ftime & 31);
printf_debug("%04d-%02d-%02d %02d:%02d:%02d ",(fno.fdate >> 9) + 1980,fno.fdate >> 5 & 15,fno.fdate & 31,fno.ftime >> 11 & 31,fno.ftime >> 5 & 63,fno.ftime & 31);
if (fno.fattrib & AM_DIR)
printf(" <%s>\n",fno.fname);
printf_debug(" <%s>\n",fno.fname);
else
{
printf(" %12s %u %s\n",fno.fname,fno.fsize>>20?fno.fsize>>10:fno.fsize,fno.fsize>>20?"KB":"");
printf_debug(" %12s %u %s\n",fno.fname,fno.fsize>>20?fno.fsize>>10:fno.fsize,fno.fsize>>20?"KB":"");
}
}
return 0;
Expand Down Expand Up @@ -287,7 +287,7 @@ static FRESULT fat_mkfile(char *arg)
if (free_space < fil_size)
{
#ifdef DEBUG
printf("Need more space: %lu KB,Current available drive space: %lu KB\n",fil_size - free_space >> 10, free_space >> 10);
printf_debug("Need more space: %lu KB,Current available drive space: %lu KB\n",fil_size - free_space >> 10, free_space >> 10);
#endif
return FR_DENIED;
}
Expand All @@ -310,8 +310,8 @@ static FRESULT fat_info (char *arg)
unsigned long long free_space;
res = fat_free_space(arg,&free_space);
if (res) return res;
printf("FAT sub-type:\t%s\n",fs->fs_type == FS_FAT12?"FAT12":fs->fs_type == FS_FAT16?"FAT16":"FAT32");
printf("Sectors per cluster: %d\n"
printf_debug("FAT sub-type:\t%s\n",fs->fs_type == FS_FAT12?"FAT12":fs->fs_type == FS_FAT16?"FAT16":"FAT32");
printf_debug("Sectors per cluster: %d\n"
"Sectors per FAT: %d\n"
"Number of free clusters: %d\n"
"Total clusters: %d\n"
Expand All @@ -331,13 +331,13 @@ static FRESULT fat_copy (char *arg)
char new_to[256];
unsigned long long f_pos = 0;
unsigned long long fil_size;
UINT br, bw;/*br 读取字节数;bw 写入字节数。*/
UINT br, bw;/*br 读取字节数;bw 写入字节数。*/
FRESULT res;
FIL file;

if (memcmp(arg, "/o", 2) == 0)
{
Mode |= FA_CREATE_ALWAYS;/*有加参数“/o”使用覆盖的模式创建文件*/
Mode |= FA_CREATE_ALWAYS;/*有加参数“/o”使用覆盖的模式创建文件*/
arg = skip_to(0,arg);
}
else Mode |= FA_CREATE_NEW;
Expand All @@ -348,12 +348,12 @@ static FRESULT fat_copy (char *arg)

if (!to)
{
/*如果只提供了源文件名,则目标文件名使用来源文件名复制到当前根目录下*/
/*如果只提供了源文件名,则目标文件名使用来源文件名复制到当前根目录下*/
char *P = to = from;
while(P = strstr(P,"/"))
to = P++;
}
else if (to[strlen(to)-1] == '/') /*如果未提供目标名称,则使用原名复制*/
else if (to[strlen(to)-1] == '/') /*如果未提供目标名称,则使用原名复制*/
{
strcpy(new_to,to);
char *P = to = from;
Expand All @@ -362,7 +362,7 @@ static FRESULT fat_copy (char *arg)
to=new_to;
}

if (debug >1) printf("Copy file: %s ==> %s\n",from,to);
printf_debug("Copy file: %s ==> %s\n",from,to);

#if F_GETFREE
res = fat_free_space("",&f_pos);
Expand All @@ -376,7 +376,7 @@ static FRESULT fat_copy (char *arg)
if (f_pos < fil_size)
{
#ifdef DEBUG
printf("Need more space: %lu KB,Current available drive space: %lu KB\n",fil_size - f_pos >> 10, f_pos >> 10);
printf_debug("Need more space: %lu KB,Current available drive space: %lu KB\n",fil_size - f_pos >> 10, f_pos >> 10);
#endif
return FR_DENIED;
}
Expand Down Expand Up @@ -404,11 +404,11 @@ static FRESULT fat_copy (char *arg)
while (br)
{
#ifdef DEBUG1
if (debug) printf("Read Bytes:%d\n",br);
printf_debug("Read Bytes:%d\n",br);
#endif
res = f_write(&file, f_buf, br, &bw);
#ifdef DEBUG1
if (debug) printf("Write Bytes:%d\n", bw);
printf_debug ("Write Bytes:%d\n", bw);
#endif
if (res || bw < br || f_pos >= fil_size) break;

Expand Down Expand Up @@ -549,6 +549,7 @@ static int fat_func (char *arg,int flags)
else if (memcmp (arg,"mkfs ",5) == 0)
{
unsigned long long unit = 0;
int mbr = 0;
arg = skip_to (0, arg);
if (memcmp (arg,"/A:", 3) == 0)
{
Expand All @@ -559,8 +560,14 @@ static int fat_func (char *arg,int flags)
}
arg = skip_to (0,arg);
}
if (memcmp (arg,"mbr", 3) == 0) //创建mbr,硬盘格式 2024-11-25
{
arg += 3;
mbr = 1;
arg = skip_to (0,arg);
}
arg = fat_set_path(arg);
res = f_mkfs(0,1,(UINT)unit);
res = f_mkfs(0,(mbr?0:1),(UINT)unit);
if (res == 0 ) res = fat_info(arg);
}
#endif
Expand Down Expand Up @@ -590,16 +597,16 @@ static int fat_func (char *arg,int flags)

if (res) {
#ifdef DEBUG
printf("FAT Error: %s\n",fat_err[res]);
printf_debug("FAT Error: %s\n",fat_err[res]);
#else
printf("FAT error: %d\n",res);
printf_debug("FAT error: %d\n",res);
#endif
errnum = 0xff;
}
return !res;
};

/*以下内容本来是要放在DISKIO.C的,因为只有几个函数,为了方便就直接整合到这里来了*/
/*以下内容本来是要放在DISKIO.C的,因为只有几个函数,为了方便就直接整合到这里来了*/

/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
Expand All @@ -611,7 +618,7 @@ static DSTATUS disk_initialize (BYTE drv)
current_drive = cur_drive;
current_partition = cur_partition;
#ifdef DEBUG1
if (debug>1) printf("Current drive:%x,%x,%d,%d\n",current_drive,current_partition,fs->id,fs->fs_type);
printf_debug("Current drive:%x,%x,%d,%d\n",current_drive,current_partition,fs->id,fs->fs_type);
#endif
if (real_open_partition(0))
{
Expand All @@ -624,13 +631,13 @@ static DSTATUS disk_initialize (BYTE drv)
/* Return Disk Status */
/*-----------------------------------------------------------------------*/
/*
 注:为了防止在进行其它操作时切换了GRUB4DOS的当前磁盘和分区号导致FAT模块的操作失败。
 在这个函数里面重新指定FAT分区(也就是上面的初始化操作),以保证FAT模块正常使用。
 注:为了防止在进行其它操作时切换了GRUB4DOS的当前磁盘和分区号导致FAT模块的操作失败。
 在这个函数里面重新指定FAT分区(也就是上面的初始化操作),以保证FAT模块正常使用。
*/
static DSTATUS disk_status (BYTE drv);
static DSTATUS disk_status (BYTE drv)
{
if (disk_initialize(0))/*重新指定要操作的FAT分区,写在这里使得每次调用FAT模块时都执行一次*/
if (disk_initialize(0))/*重新指定要操作的FAT分区,写在这里使得每次调用FAT模块时都执行一次*/
return STA_NOINIT;

if (fs->id && fs->fs_type) return 0;
Expand Down Expand Up @@ -685,7 +692,7 @@ static DRESULT disk_write (
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
/*注:因为程序目前不需要使用这些功能,所以这个函数是一个空函数,直接返回。*/
/*注:因为程序目前不需要使用这些功能,所以这个函数是一个空函数,直接返回。*/
static DRESULT disk_ioctl (BYTE drv, BYTE ctrl, void *buff);
static DRESULT disk_ioctl (
BYTE drv, /* Physical drive nmuber (0..) */
Expand Down Expand Up @@ -717,9 +724,9 @@ static DRESULT disk_ioctl (
}

/*
函数用于设置新建文件、文件夹日期时间,因为不知如何获取时间,所以使用了一个固定的时间,目前是使用程序编译的时间。
如果你知道并且想使用系统时间。可以自己添加代码进去。
2010-06-24已添加获取当前时间代码.
函数用于设置新建文件、文件夹日期时间,因为不知如何获取时间,所以使用了一个固定的时间,目前是使用程序编译的时间。
如果你知道并且想使用系统时间。可以自己添加代码进去。
2010-06-24已添加获取当前时间代码.
*/
static DWORD get_fattime (void);
static DWORD get_fattime (void)
Expand All @@ -733,16 +740,44 @@ static void get_G4E_image(void)
{
grub_size_t i;

//在内存0-0x9ffff, 搜索特定字符串"GRUB4EFI",获得GRUB_IMGE
//在内存0-0x9ffff, 搜索特定字符串"GRUB4EFI",获得GRUB_IMGE
for (i = 0x40100; i <= 0x9f100 ; i += 0x1000)
{
if (*(unsigned long long *)i == 0x4946453442555247) //比较数据
if (*(unsigned long long *)i == 0x4946453442555247) //比较数据
{
g4e_data = *(grub_size_t *)(i+16); //GRUB4DOS_for_UEFI入口
g4e_data = *(grub_size_t *)(i+16); //GRUB4DOS_for_UEFI入口
return;
}
}
return;
}

#if _USE_LFN
WCHAR ff_convert (WCHAR wch, UINT dir)
{
if (wch < 0x80) {
/* ASCII Char */
return wch;
}

/* I don't support unicode it is too big! */
return 0;
}

WCHAR ff_wtoupper (WCHAR wch)
{
if (wch < 0x80) {
/* ASCII Char */
if (wch >= 'a' && wch <= 'z') {
wch &= ~0x20;
}
return wch;
}

/* I don't support unicode it is too big! */
return 0;
}
#endif

#include "ff.c"

8 changes: 7 additions & 1 deletion g4eext/fat/ff.c
Original file line number Diff line number Diff line change
Expand Up @@ -2142,6 +2142,7 @@ FRESULT f_write (
clst = fp->org_clust; /* Follow from the origin */
if (clst == 0) /* When there is no cluster chain, */
fp->org_clust = clst = create_chain(fp->fs, 0); /* Create a new cluster chain */
ext_data_1 = clust2sect(fp->fs, fp->org_clust); //导出新建文件的起始相对逻辑扇区 2024-11-07
} else { /* Middle or end of the file */
clst = create_chain(fp->fs, fp->curr_clust); /* Follow or stretch cluster chain */
}
Expand Down Expand Up @@ -3246,6 +3247,7 @@ FRESULT f_mkfs (
ST_DWORD(tbl+8, 63); /* Partition start in LBA */
ST_DWORD(tbl+12, n_vol); /* Partition size in LBA */
ST_WORD(tbl+64, 0xAA55); /* Signature */
ST_DWORD(tbl-6, 0x11223344); /*Disk Signature 2024-11-25*/
if (disk_write(drv, fs->win, 0, 1) != RES_OK)
return FR_DISK_ERR;
md = 0xF8;
Expand Down Expand Up @@ -3282,11 +3284,15 @@ FRESULT f_mkfs (
tbl[BS_BootSig32] = 0x29; /* Extended boot signature */
mem_cpy(tbl+BS_VolLab32, "NO NAME FAT32 ", 19); /* Volume label, FAT signature */
} else {
if (fmt == FS_FAT12) //完善BPB信息 2024-11-07
mem_cpy(tbl+BS_VolLab, "NO NAME FAT12 ", 19); /* Volume label, FAT signature */
else
mem_cpy(tbl+BS_VolLab, "NO NAME FAT16 ", 19); /* Volume label, FAT signature */
ST_DWORD(tbl+BS_VolID, n); /* VSN */
ST_WORD(tbl+BPB_FATSz16, n_fat); /* Number of sectors per FAT */
tbl[BS_DrvNum] = 0x80; /* Drive number */
tbl[BS_BootSig] = 0x29; /* Extended boot signature */
mem_cpy(tbl+BS_VolLab, "NO NAME FAT ", 19); /* Volume label, FAT signature */
// mem_cpy(tbl+BS_VolLab, "NO NAME FAT ", 19); /* Volume label, FAT signature */
}
ST_WORD(tbl+BS_55AA, 0xAA55); /* Signature (Offset is fixed here regardless of sector size) */
if (disk_write(drv, tbl, b_vol, 1) != RES_OK) /* Original (VBR) */
Expand Down
4 changes: 2 additions & 2 deletions g4eext/fat/ff.h
Original file line number Diff line number Diff line change
Expand Up @@ -466,8 +466,8 @@ TCHAR* f_gets (TCHAR*, int, FIL*); /* Get a string from the file */

/* Unicode support functions */
#if _USE_LFN /* Unicode - OEM code conversion */
WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */
WCHAR ff_wtoupper (WCHAR); /* Unicode upper-case conversion */
WCHAR ff_convert (WCHAR wch, UINT dir); /* OEM-Unicode bidirectional conversion */
WCHAR ff_wtoupper (WCHAR wch); /* Unicode upper-case conversion */
#if _USE_LFN == 3 /* Memory functions */
void* ff_memalloc (UINT); /* Allocate memory block */
void ff_memfree (void*); /* Free memory block */
Expand Down
Loading

0 comments on commit 8df8b3f

Please sign in to comment.