[syslinux] syslinux current dir

Ferenc Wagner wferi at niif.hu
Fri May 11 08:37:26 PDT 2007


"H. Peter Anvin" <hpa at zytor.com> writes:

> Wagner Ferenc wrote:
>>> That makes sense, and *should* be implementable.
>> 
>> Do you mean that I should implement it? :)
>> My asm-fu is rather weak, but might try...
>
> If you're willing to try it, go for it.  I suggest making the new cwd a
> command-line option (append) to the config file, but that's only one
> alternative.

So here we go, my first shot at the problem.  It doesn't work.  Also,
I find it somewhat uglier than necessary, but my asm skills are nearly
nonexistent...  The concept should be clear though, I hope.  I'm not
sure how to send git commits, maybe git diff -p is somewhat usable...
I'm testing with the following syslinux.cfg in the root of the floppy:

serial 1
prompt 1
timeout 100
say say hello

label hello
  config syslinux.cfg
  append elso cWd=dir1 masodik=ertek cwD=dir2 utolso

Unfortunately, uncommenting the mov [CurrentDir],eax statement hangs
syslinux; maybe because I know very little about its concept of the
current directory, maybe becasue I'm not into assembly programming.
Anyway, I'm out of ideas for now, and could use some help or comments.
-- 
Thanks,
Feri.

commit 088b568ccf73e3c5f3cef7cfca7b0a599ceae5c3
Author: Ferenc Wagner <wferi at tac.ki.iif.hu>
Date:   Fri May 11 17:20:32 2007 +0200

    Prepare for changing current working directory
    
    Things seem to work together as expected, but uncommenting the FIXME line
    (which constitutes the main effect) locks up my test.
    Some debugging is in order.

diff --git a/ldlinux.asm b/ldlinux.asm
index 3cfa13e..9c0e92f 100644
--- a/ldlinux.asm
+++ b/ldlinux.asm
@@ -1075,7 +1075,61 @@ search_dos_dir:
 ;
 ; Assumes CS == DS == ES, and trashes BX and CX.
 ;
-searchdir:
+searchdir:	call searchpath
+		test dl,18h		; Subdirectory|Volume Label
+		jnz badfile		; If not a file, it's a bad thing
+
+		; SI and EAX are already set
+		mov edx,eax
+		shr edx,16		; Old 16-bit remnant...
+		and eax,eax		; EAX != 0
+		jz badfile
+		ret			; Done!
+
+;
+; cwdir:
+;
+;	Change current working directory
+;
+;	     On entry:
+;		DS:DI	= directory name
+;	     If successful:
+;		ZF clear
+;	     If unsuccessful
+;		ZF set
+;
+cwdir:		push es
+		mov ax,ds		; Ensure ES == DS
+		mov es,ax
+		call searchpath
+		test dl,10h		; Subdirectory
+		pop es
+		jz badfile
+
+		xor eax,eax
+		xchg eax,[si+file_sector] ; Get sector number and free file structure
+;		mov [CurrentDir],eax    ; FIXME
+		and ax,ax		; Clear ZF
+		ret
+
+;
+; searchpath:
+;
+;	Look up a directory entry
+;
+;	     On entry:
+;		DS:DI	= pathname
+;	     If successful:
+;		ZF clear
+;		SI	= file pointer
+;		EAX	= file length in bytes
+;		DL	= file attributes
+;	     If unsuccessful
+;		ZF set
+;
+; Assumes CS == DS == ES, and trashes BX and CX.
+;
+searchpath:
 		mov eax,[CurrentDir]
 		cmp byte [di],'/'	; Root directory?
 		jne .notroot
@@ -1102,37 +1156,26 @@ searchdir:
 		call mangle_dos_name	; MangledBuf <- component
 		call search_dos_dir
 		pop di
-		jz .notfound		; Pathname component missing
+		jz notfound		; Pathname component missing
 
 		cmp byte [di-1],'/'	; Do we expect a directory
 		je .isdir
-
-		; Otherwise, it should be a file
-.isfile:
-		test dl,18h		; Subdirectory|Volume Label
-		jnz .badfile		; If not a file, it's a bad thing
-
-		; SI and EAX are already set
-		mov edx,eax
-		shr edx,16		; Old 16-bit remnant...
-		and eax,eax		; EAX != 0
-		jz .badfile
-		ret			; Done!
+		ret
 
 		; If we expected a directory, it better be one...
 .isdir:
 		test dl,10h		; Subdirectory
-		jz .badfile
+		jz badfile
 
 		xor eax,eax
 		xchg eax,[si+file_sector] ; Get sector number and free file structure
 		jmp .pathwalk		; Walk the next bit of the path
 
-.badfile:
+badfile:
 		xor eax,eax
 		mov [si],eax		; Free file structure
 
-.notfound:
+notfound:
 		xor eax,eax
 		xor dx,dx
 		ret
diff --git a/ui.inc b/ui.inc
index f78f358..8afc21e 100644
--- a/ui.inc
+++ b/ui.inc
@@ -560,9 +560,8 @@ is_config_file:
 		call strcpy
 		push ds				; not sure if needed
 		mov si,real_mode_seg
-		mov ds,si
+		mov ds,si			; for accessing the command line
 		mov si,cmd_line_here
-		call cwritestr			; debug (writes to EOL, not the parameter only)
 .get_next_opt:	lodsb				; copied from runkernel.inc
 		and al,al
 		jz .cmdline_end
@@ -575,7 +574,21 @@ is_config_file:
 		jne .skip_this_opt
 
 		add si,4			; found CWD command
+		mov di,si
+		push di				; save for printing
+		call cwdir
+		pop di
+		mov si,di			; in case we skip
+		jnz .skip_this_opt
+		pop ds				; restore DS
+		push ds
+		mov si,err_cwdir		; for printing the error
 		call cwritestr
+		mov si,real_mode_seg		; then change back
+		mov ds,si
+		mov si,di
+		call cwritestr			; for printing the directory
+		call crlf
 
 .skip_this_opt:	lodsb
 		cmp al,' '
@@ -607,6 +620,7 @@ is_disk_image	equ is_bad_image
 
 		section .data
 err_badimage	db 'Invalid image type for this media type!', CR, LF, 0
+err_cwdir	db 'Cannot change working directory to ', 0
 
 		align 2, db 0
 kerneltype_table:

commit b2167f8dbe62b35f10eb44db8349bf4b0137e3ab
Author: Ferenc Wagner <wferi at tac.ki.iif.hu>
Date:   Fri May 11 12:32:56 2007 +0200

    Parse the CMD option for a new config file.
    
    Now for debugging only, printing some text on the
    console without any effect.

diff --git a/ui.inc b/ui.inc
index 97d361e..f78f358 100644
--- a/ui.inc
+++ b/ui.inc
@@ -558,6 +558,31 @@ is_config_file:
 		mov si,KernelCName		; Save the config file name, for posterity
 		mov di,ConfigName
 		call strcpy
+		push ds				; not sure if needed
+		mov si,real_mode_seg
+		mov ds,si
+		mov si,cmd_line_here
+		call cwritestr			; debug (writes to EOL, not the parameter only)
+.get_next_opt:	lodsb				; copied from runkernel.inc
+		and al,al
+		jz .cmdline_end
+		cmp al,' '
+		jbe .get_next_opt
+		dec si
+		mov eax,[si]
+		or eax,202020h			; Force lower case (except =)
+		cmp eax,'cwd='
+		jne .skip_this_opt
+
+		add si,4			; found CWD command
+		call cwritestr
+
+.skip_this_opt:	lodsb
+		cmp al,' '
+		ja .skip_this_opt
+		dec si
+		jmp short .get_next_opt
+.cmdline_end:	pop ds				; restore DS
 		popa
 		call openfd
 		call reset_config




More information about the Syslinux mailing list