Skip to content

Commit

Permalink
. 修正碎片插槽计算。
Browse files Browse the repository at this point in the history
. 改进pxe。
  • Loading branch information
yaya2007 committed Nov 27, 2023
1 parent a13f36c commit 19c4f81
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 34 deletions.
4 changes: 4 additions & 0 deletions ChangeLog_UEFI.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
更新说明:
2023-11-27 (yaya)
修正碎片插槽计算。
改进pxe。

2023-10-14 (yaya)
修正增加变量menu_tab_ext引入的问题。
修正font函数。
Expand Down
4 changes: 3 additions & 1 deletion stage2/asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,8 @@ VARIABLE(menu_mem) //0x8388 菜单 char *

. = EXT_C(main) + 0x190 //0x8390

VARIABLE(efi_pxe_buf) //char * 2023-11-24
.long 0, 0
.long 0
.long 0
.long 0
Expand Down Expand Up @@ -618,7 +620,7 @@ VARIABLE(system_functions) //IMG(0x8300)
.extent ABS(EXT_C(grub_read)) //27
.extent ABS(EXT_C(grub_close)) //28
.extent ABS(EXT_C(get_device_by_drive)) //29 grub_disk_data *
.extent 0 //30 reserved
.extent ABS(EXT_C(tftp_write)) //30 int
VARIABLE(disk_read_hook)
.extent 0 //31
.extent ABS(EXT_C(devread)) //32
Expand Down
34 changes: 25 additions & 9 deletions stage2/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -842,7 +842,8 @@ map_to_svbus (grub_efi_physical_address_t address)
#endif

//复制碎片插槽
grub_memmove ((char *)((char *)(grub_size_t)address + 0x148), (char *)&disk_fragment_map, FRAGMENT_MAP_SLOT_SIZE);
// grub_memmove ((char *)((char *)(grub_size_t)address + 0x148), (char *)&disk_fragment_map, FRAGMENT_MAP_SLOT_SIZE);
grub_memmove ((char *)((char *)(grub_size_t)address + 0x148), (char *)disk_fragment_map, FRAGMENT_MAP_SLOT_SIZE);
}

//使用于get_efi_device_boot_path,find_specified_file,chainloader_func,command_func,uuid_func
Expand Down Expand Up @@ -1484,6 +1485,13 @@ chainloader_func (char *arg, int flags)
}

printf_debug("current_drive=%x, current_partition=%x\n",current_drive,current_partition);
if (current_drive == 0x21) //2023-11-24
{
dp = pd_dp; //网起设备路径
temp = pd_handle; //网起设备句柄
}
else
{
// if (current_drive >= 0xa0) //使用光盘启动镜像的句柄和路径 2023-10-14
// current_partition = 0xffff;
//如果当前设备是(cd-1),使用光盘的路径;如果当前设备是(cd-1,0),使用光盘启动镜像的路径。 2023-10-16
Expand All @@ -1503,6 +1511,7 @@ chainloader_func (char *arg, int flags)
dp = grub_efi_get_device_path (part_data->part_handle);
temp = part_data->part_handle;
}
}

if (debug > 1)
grub_efi_print_device_path(dp);
Expand Down Expand Up @@ -7246,9 +7255,11 @@ unload_fragment_slot (unsigned int from) //卸载碎片插槽
void *start;
int len;

q = (struct fragment_map_slot *)&disk_fragment_map; //q=碎片映射插槽起始位置 *q=插槽尺寸 b6e0
// q = (struct fragment_map_slot *)&disk_fragment_map; //q=碎片映射插槽起始位置 *q=插槽尺寸 b6e0
q = (struct fragment_map_slot *)disk_fragment_map; //q=碎片映射插槽起始位置 *q=插槽尺寸 b6e0
// filename = (char *)q + FRAGMENT_MAP_SLOT_SIZE; //碎片映射插槽终止位置
grub_size_t size = (grub_size_t)&disk_fragment_map + FRAGMENT_MAP_SLOT_SIZE;
// grub_size_t size = (grub_size_t)&disk_fragment_map + FRAGMENT_MAP_SLOT_SIZE;
grub_size_t size = (grub_size_t)disk_fragment_map + FRAGMENT_MAP_SLOT_SIZE;
q = fragment_map_slot_find(q, from); //q=from驱动器在碎片映射插槽起始位置
if (q) //0/1=没有找到驱动器/找到驱动器位置
{
Expand Down Expand Up @@ -8221,9 +8232,11 @@ struct drive_map_slot
df = get_device_by_drive (from,1);
if (df && df->fragment == 1) //有碎片
{
q = (struct fragment_map_slot *)&disk_fragment_map; //碎片插槽起始
// q = (struct fragment_map_slot *)&disk_fragment_map; //碎片插槽起始
q = (struct fragment_map_slot *)disk_fragment_map; //碎片插槽起始
// filename = (char *)q + FRAGMENT_MAP_SLOT_SIZE; //碎片插槽结束
grub_size_t size = (grub_size_t)&disk_fragment_map + FRAGMENT_MAP_SLOT_SIZE;
// grub_size_t size = (grub_size_t)&disk_fragment_map + FRAGMENT_MAP_SLOT_SIZE;
grub_size_t size = (grub_size_t)disk_fragment_map + FRAGMENT_MAP_SLOT_SIZE;
q = fragment_map_slot_find(q, from); //从碎片插槽查找from驱动器
if (q) //q=0/非0=没有找到/from驱动器在碎片插槽位置
{
Expand Down Expand Up @@ -8493,14 +8506,15 @@ struct drive_map_slot
if (to == ram_drive) //如果to=rd
start_byte += rd_base; //起始字节+rd基址
/////////////////////////////////////////////////////////////////////////////////////////////////////以下插入分配内存

if (to == 0x21) //网络驱动器
#if 0 //2023-11-24
if (to == 0x21) //网络驱动器
{
// disk_drive_map[i].start_sector = ((unsigned long long)(grub_size_t)(char*)efi_pxe_buf | 0x200) & 0xfffffffffffffe00; //此处是内存起始字节!!!
start_sector = ((unsigned long long)(grub_size_t)(char*)efi_pxe_buf | 0x200) & 0xfffffffffffffe00; //此处是内存起始字节!!!
efi_pxe_buf = 0;
}
else //其他
#endif
{
if (prefer_top) //分配4GB以上内存
{
Expand Down Expand Up @@ -8690,7 +8704,8 @@ struct drive_map_slot
grub_memmove64 ((unsigned long long)(grub_size_t)p1, (unsigned long long)(grub_size_t)map_start_sector, DRIVE_MAP_FRAGMENT * 8);
grub_memmove64 ((unsigned long long)(grub_size_t)p2, (unsigned long long)(grub_size_t)map_start_sector, DRIVE_MAP_FRAGMENT * 8);
//查找父插槽To_
q = (struct fragment_map_slot *)&disk_fragment_map;
// q = (struct fragment_map_slot *)&disk_fragment_map;
q = (struct fragment_map_slot *)disk_fragment_map;
q = fragment_map_slot_find(q, primeval_to);
struct fragment *to_ = (struct fragment *)&q->fragment_data;

Expand Down Expand Up @@ -8755,7 +8770,8 @@ struct drive_map_slot
goto no_fragment;
}
//查找空槽
q = (struct fragment_map_slot *)&disk_fragment_map;
// q = (struct fragment_map_slot *)&disk_fragment_map;
q = (struct fragment_map_slot *)disk_fragment_map;
filename = (char *)q;
q = fragment_map_slot_empty(q);
//出界检查
Expand Down
2 changes: 1 addition & 1 deletion stage2/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -2248,7 +2248,7 @@ char *CMD_RUN_ON_EXIT;
char *SCRATCHADDR;
char *mbr;
char *disk_buffer;
struct fragment_map_slot *disk_fragment_map;
//struct fragment_map_slot *disk_fragment_map;
//char *

void grub_console_init (void);
Expand Down
8 changes: 6 additions & 2 deletions stage2/disk_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -3052,7 +3052,8 @@ grub_efidisk_readwrite (int drive, grub_disk_addr_t sector,
if (df->fragment)
{
//从碎片插槽查找Form驱动器
q = (struct fragment_map_slot *)&disk_fragment_map;
// q = (struct fragment_map_slot *)&disk_fragment_map;
q = (struct fragment_map_slot *)disk_fragment_map;
q = fragment_map_slot_find (q, from_drive);
//确定Form扇区起始在哪个碎片
data = (struct fragment *)&q->fragment_data;
Expand Down Expand Up @@ -5028,7 +5029,8 @@ EFI_STATUS grub_hook_1st_cdrom_stop(VOID) //钩第一光盘结束
}
#endif


grub_efi_handle_t pd_handle;
grub_efi_device_path_t *pd_dp;
//void GRUB_MOD_INIT_efinet(void);
//int force_pxe_as_boot_device = 0;
void grub_efidisk_init (void);
Expand Down Expand Up @@ -5116,6 +5118,8 @@ grub_efidisk_init (void) //efidisk初始化
run_line((char *)"set ?_BOOT=%@root%",1);
// QUOTE_CHAR = '\"';
*saved_dir = 0;
pd_handle = image->device_handle; //2023-11-24
pd_dp = dp;
cmain ();
return;
}
Expand Down
56 changes: 40 additions & 16 deletions stage2/fsys_pxe.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,20 @@ static unsigned int pxe_saved_pos, pxe_cur_ofs, pxe_read_ofs; //保存的指针,
extern PXENV_TFTP_OPEN_t pxe_tftp_open; /* now it is defined in asm.S 现在它在asm.S中定义*/ //TFTP打开
static char filename[128];
static char *pxe_tftp_name = filename;
char *efi_pxe_buf = 0;

//extern unsigned int ROM_int15;
//extern unsigned int ROM_int13;
//extern unsigned int ROM_int13_dup;
extern struct drive_map_slot bios_drive_map[DRIVE_MAP_SIZE + 1];

static int pxe_open (char* name);
int pxe_dir (char *dirname);
grub_u32_t pxe_read_blk (grub_u32_t buf, grub_u32_t num);

static int tftp_open(const char *dirname);
static grub_u32_t tftp_get_size(void);
static grub_u32_t tftp_read_blk (grub_u32_t buf, grub_u32_t num);
int tftp_write (const char *name);
static void tftp_close (void);
static void tftp_unload(void);

Expand Down Expand Up @@ -217,7 +218,8 @@ BOOTPLAYER *discover_reply = 0; //引导播放器
static void set_basedir(char *config);
static void set_basedir(char *config) //设置基本目录
{
unsigned int n;
// unsigned int n;
int n; //2023-11-24
grub_u8_t path_sep = (cur_pxe_type == PXE_FILE_TYPE_TFTP && server_is_dos) ? '\\' : '/'; //路径分隔
n = grub_strlen (config); //字符串尺寸

Expand Down Expand Up @@ -735,18 +737,17 @@ pxe_read (unsigned long long buf, unsigned long long len, unsigned int write) //
FILEMAX. return 1 if succeed, 0 if fail. */ //获取尺寸并将其保存在FILEMAX中。 如果成功则返回1,如果失败则返回0
struct pxe_dir_info //目录信息
{
char path[512]; //路径
char *dir[512]; //目录
char data[]; //数据
} *P_DIR_INFO = NULL;
char path[512]; //路径 尺寸0x200 e3d64c0 /boot/dir.txt
char *dir[512]; //目录 尺寸0x1000 e3d66c0 e3d76c0 e3d76c5 e3d76d2 ...
char data[]; //数据 尺寸0x2e00 e3d76c0 bcd\0\a bcdedit.exe\0\a boot.sdi\0\a bootmgr.exe\0\a wimboot\0\a
} *P_DIR_INFO = NULL;//尺寸0x4000

int pxe_dir (char *dirname);
int pxe_dir (char *dirname) //pxe查目录
{
int ret;
char ch;
ret = 1;
ch = nul_terminate (dirname); //用"0"替换"\0"
ch = nul_terminate (dirname); //以00替换止字符串的空格,回车,换行,水平制表符

if (print_possibilities) //如果存在打印可能性
{
Expand All @@ -771,16 +772,17 @@ int pxe_dir (char *dirname) //pxe查目录
{
int i;
char *p = P_DIR_INFO->data;
memset(P_DIR_INFO,0,16384);
if (substring(dir_tmp,P_DIR_INFO->path,1) != 0) //判断子字符串
{
memset(P_DIR_INFO,0,16384);
grub_strcpy(P_DIR_INFO->path,dir_tmp);
if (pxe_open(dir_tmp))
{
if (pxe_read((unsigned long long)(grub_size_t)P_DIR_INFO->data,13312,GRUB_READ))
// if (pxe_read((unsigned long long)(grub_size_t)P_DIR_INFO->data,13312,GRUB_READ)) //13312计算错误
if (pxe_read((unsigned long long)(grub_size_t)P_DIR_INFO->data,filemax,GRUB_READ)) //替换filemax,是因为读长了会把后面无用的字符串读入 2023-11-24
{
P_DIR_INFO->dir[0] = P_DIR_INFO->data;
for (i = 1;i < 512 && (p = skip_to(0x100,p));++i)
for (i = 1;i < 512 && (p = skip_to(0x100,p));++i) //遇到首个"回车,换行",使用'\0'替换.然后跳过之后的"回车,换行,空格,水平制表符",
{
P_DIR_INFO->dir[i] = p;
}
Expand Down Expand Up @@ -838,19 +840,20 @@ static int tftp_open(const char *name) //tftp打开
if (!tftp_get_size())
return 0;

tftp_close ();
// tftp_close (); //2023-11-24
status = efi_call_3 (b->allocate_pool, GRUB_EFI_BOOT_SERVICES_DATA, //启动服务数据 4
filemax + 0x200, (void**)&efi_pxe_buf); //(分配池,存储器类型->装载数据,分配字节,返回分配地址}
if (status != GRUB_EFI_SUCCESS) //失败
{
printf_errinfo ("Couldn't allocate pool.");
return 0;
}
memset(efi_pxe_buf,0,filemax); //2023-11-24

status = efi_call_10 (pxe_entry->mtftp, //tftp功能
pxe_entry, //pxe结构
GRUB_EFI_PXE_BASE_CODE_TFTP_READ_FILE, //TFTP读文件
efi_pxe_buf, //缓存
(char *)efi_pxe_buf, //缓存
0,
(grub_efi_uint64_t *)(grub_size_t)&filemax,//缓存尺寸
NULL, //块尺寸
Expand Down Expand Up @@ -896,13 +899,35 @@ static grub_u32_t tftp_get_size(void) //TFTP获得文件尺寸
return filemax;
}

static grub_u32_t tftp_read_blk (grub_u32_t buf, grub_u32_t num);
static grub_u32_t tftp_read_blk (grub_u32_t buf, grub_u32_t num)
{
return 0;
}

static void tftp_close (void);
int tftp_write (const char *name) //tftp写 2023-11-24
{
grub_efi_status_t status;

status = efi_call_10 (pxe_entry->mtftp, //tftp功能
pxe_entry, //pxe结构
GRUB_EFI_PXE_BASE_CODE_TFTP_WRITE_FILE, //TFTP写文件
(char *)efi_pxe_buf, //缓存
1, //可以覆盖服务器上的文件
(grub_efi_uint64_t *)(grub_size_t)&filemax,//缓存尺寸
NULL, //块尺寸
(IP4 *)(grub_size_t)&pxe_sip, //服务器IP
(char *)name, //文件名
NULL,
0);
if (status != GRUB_EFI_SUCCESS) //失败
{
printf_errinfo ("Couldn't open file.");
return 0;
}

return 1;
}

static void tftp_close (void) //tftp关闭
{
grub_efi_boot_services_t *b; //引导服务
Expand All @@ -913,7 +938,6 @@ static void tftp_close (void) //tftp关闭
efi_pxe_buf = 0;
}

static void tftp_unload(void);
static void tftp_unload(void) //tftp卸载
{
if (! pxe_entry)
Expand Down
14 changes: 9 additions & 5 deletions stage2/shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ struct linux_kernel_header
unsigned int kernel_alignment;
unsigned char relocatable;
unsigned char min_alignment;
#define LINUX_XLF_KERNEL_64 (1<<0) //1 64位内
#define LINUX_XLF_KERNEL_64 (1<<0) //1 64位内内核
#define LINUX_XLF_CAN_BE_LOADED_ABOVE_4G (1<<1) //2 可加载4G以上
#define LINUX_XLF_EFI_HANDOVER_32 (1<<2) //4 支持 EFI32 Handover
#define LINUX_XLF_EFI_HANDOVER_64 (1<<3) //8 支持 EFI64 Handover
Expand Down Expand Up @@ -2243,7 +2243,7 @@ extern int is64bit;

extern int errorcheck;
extern unsigned int pxe_restart_config;
extern char *efi_pxe_buf;
extern grub_size_t *efi_pxe_buf;
extern unsigned int saved_pxe_ip;
extern unsigned char saved_pxe_mac[6];

Expand Down Expand Up @@ -4229,14 +4229,16 @@ typedef struct grub_efi_pxe
grub_efi_pxe_base_code_tftp_opcode_t operation, //运作方式 要执行的操作类型。
char *buffer_ptr, //指向数据缓冲区的指针。 如果dont_use_buffer为TRUE,则忽略读取文件。
grub_efi_boolean_t overwrite, //覆盖,仅用于写文件操作。 如果可以覆盖远程服务器上的文件,则为TRUE。
grub_efi_uint64_t *buffer_size, //缓冲区尺寸 对于获得文件尺寸操作,*buffer_size返回所请求文件的尺寸。对于读文件和写文件操作,
grub_efi_uint64_t *buffer_size, //缓冲区尺寸 对于获取文件尺寸操作,*buffer_size返回所请求文件的尺寸。对于读文件和写文件操作,
//此参数设置为指定的缓冲区尺寸。 对于读取文件操作,如果返回EFI_BUFFER_TOO_SMALL,则*buffer_size返回所请求文件的尺寸。
grub_efi_uintn_t *block_size, //块尺寸 在TFTP传输期间要使用的请求块尺寸。 该字段必须至少为512。
//如果此字段为NULL,则将使用实现支持的最大块大小。
grub_u32_t *server_ip, //TFTP/MTFTP服务器IP地址
grub_u32_t *server_ip, //TFTP/MTFTP服务器IP地址
char *filename, //文件名 以Null结尾的ASCII字符串,用于指定目录名称或文件名。 MTFTP读取目录会忽略此内容。
grub_efi_pxe_base_code_mtftp_info_t *info, //指向MTFTP信息的指针。 启动或加入多播TFTP会话需要此信息。
grub_efi_boolean_t dont_use_buffer); //对于正常的TFTP和MTFTP读取文件操作,设置为FALSE。
//TFTP读取目录操作返回的数据格式是一个以null结尾的文件名,后跟一个以null结尾的信息字符串,格式为“尺寸 年-月-日 时:分:秒”
//(即%d%d-%d-%d:%d:%f-注意秒字段可以是十进制数字),其中日期和时间为UTC。
void (*udpwrite) (void); //udp写 将UDP数据包写入网络接口。
void (*udpread) (void); //udp读 从网络接口读取UDP数据包。
void (*setipfilter) (void); //设置过滤器 更新网络设备的IP接收筛选器。
Expand All @@ -4249,7 +4251,7 @@ typedef struct grub_efi_pxe
struct grub_efi_pxe_mode *mode; //模式 指向此设备的EFI_PXE_BASE_CODE_MODE数据的指针。
} grub_efi_pxe_t;


extern int tftp_write (const char *name);

#define GRUB_EFI_BLACK 0x00 //前景黑
#define GRUB_EFI_BLUE 0x01 //前景蓝
Expand Down Expand Up @@ -5763,6 +5765,8 @@ extern struct grub_part_data *partition_info;
extern struct grub_disk_data *previous_struct;
extern struct grub_part_data *get_boot_partition (int drive);
extern void renew_part_data (void);
extern grub_efi_handle_t pd_handle;
extern grub_efi_device_path_t *pd_dp;

struct drive_map_slot
{
Expand Down

0 comments on commit 19c4f81

Please sign in to comment.