Well, with this simple patch I'm able to load initrd from a different disk. It's not finished, it's just to ask you if I'm going in the right direction... I have also some suggestion/question: - many boot sector I saw use [bp+xx] addressing to gain some bytes. Why don't you use such method? - had syslinux been tested with usb floppy? You test dl however using usb floppy dl == 0x80 - in debugentrypt you use sometimes [Z+...] and sometimes not (see [Z+DataArea] and [DataArea]) .. - old bios specification state that you should reset disk and retry 3 times but you don't perhaps for size problems however you should do so to load others parts (kernel and others big stuff) - you load entire FAT but on large disks (FAT16) you load 128K instead of some sectors (I don't think kernel/initrd get so defragged). It's not better to use a simple cache? What's the best method to make patch for syslinux? Just use usually patch and send them to you? freddy77 Patch: --- syslinux-2.08.orig/ldlinux.asm 2003-12-04 04:47:57.000000000 +0100 +++ syslinux-2.08/ldlinux.asm 2003-12-18 23:21:48.000000000 +0100 @@ -694,25 +694,33 @@ ; on. ; jmp 0:.next .next: ; ; Tell the user we got this far ; mov si,syslinux_banner call writestr +; begin - freddy77 + call load_fat + jmp load_fat_next +; end - freddy77 ; ; Remember, the boot sector loaded only the first cluster of LDLINUX.SYS. ; We can really only rely on a single sector having been loaded. Hence ; we should load the FAT into RAM and start chasing pointers... ; +; begin - freddy77 + +load_fat: +; end - freddy77 xor ax,ax cwd inc dx ; DX:AX <- 64K div word [bxBytesPerSec] ; sectors/64K mov si,ax push es mov bx,fat_seg ; Load into fat_seg:0000 mov es,bx @@ -730,20 +738,25 @@ call getlinsecsr sub cx,bp jz fat_load_done ; Last moby? add eax,ebp ; Advance sector count mov bx,es ; Next 64K moby add bx,1000h mov es,bx jmp short fat_load_loop fat_load_done: pop es +; begin - freddy77 + ret + +load_fat_next: +; end - freddy77 ; ; Fine, now we have the FAT in memory. How big is a cluster, really? ; Also figure out how many clusters will fit in an 8K buffer, and how ; many sectors and bytes that is ; mov edi,[bxBytesPerSec] ; Used a lot below mov eax,[SecPerClust] mov si,ax ; Also used a lot mul di mov [ClustSize],eax ; Bytes/cluster @@ -1436,20 +1449,27 @@ %ifdef debug ; This code for debugging only debug_magic dw 0D00Dh ; Debug code sentinel %endif AppendLen dw 0 ; Bytes in append= command OntimeoutLen dw 0 ; Bytes in ontimeout command OnerrorLen dw 0 ; Bytes in onerror command KbdTimeOut dw 0 ; Keyboard timeout (if any) CmdLinePtr dw cmd_line_here ; Command line advancing pointer initrd_flag equ $ initrd_ptr dw 0 ; Initial ramdisk pointer/flag +; begin - freddy77 + +change_disk_msg db 'Insert disk #' +initrd_span db 0 + db ' and press a key', CR, LF, 0 + +; end - freddy77 VKernelCtr dw 0 ; Number of registered vkernels ForcePrompt dw 0 ; Force prompt AllowImplicit dw 1 ; Allow implicit kernels SerialPort dw 0 ; Serial port base (or 0 for no serial port) VGAFontSize dw 16 ; Defaults to 16 byte font UserFont db 0 ; Using a user-specified font ScrollAttribute db 07h ; White on black (for text mode) ; ; Stuff for the command line; we do some trickery here with equ to avoid ; tons of zeros appended to our file and wasting space --- syslinux-2.08.orig/runkernel.inc 2003-08-22 05:39:37.000000000 +0200 +++ syslinux-2.08/runkernel.inc 2003-12-18 23:16:18.000000000 +0100 @@ -156,20 +156,32 @@ .notkeep: %endif push es ; Save ES -> real_mode_seg push cs pop es ; Set ES <- normal DS mov di,initrd_cmd mov cx,initrd_cmd_len repe cmpsb jne not_initrd +; begin - freddy77 + ; detect change needed + lodsw + cmp ah, ':' + je set_initrd_span + xor ax,ax + dec si + dec si +set_initrd_span: + mov [es:initrd_span], al +; end - freddy77 + mov di,InitRD push si ; mangle_dir mangles si call mangle_name ; Mangle ramdisk name pop si cmp byte [es:InitRD],NULLFILE ; Null filename? seta byte [es:initrd_flag] ; Set flag if not not_initrd: pop es ; Restore ES -> real_mode_seg skip_this_opt: lodsb ; Load from command line cmp al,' ' ja skip_this_opt @@ -287,20 +299,28 @@ call cwritestr ; ; Now see if we have an initial RAMdisk; if so, do requisite computation ; We know we have a new kernel; the old_kernel code already will have objected ; if we tried to load initrd using an old kernel ; load_initrd: test byte [initrd_flag],1 jz nk_noinitrd +; begin - freddy77 + ; detect change needed + cmp byte [initrd_span], 0 + je no_change_disk +retry_disk: + call change_disk +no_change_disk: +; end - freddy77 push es ; ES->real_mode_seg push ds pop es ; We need ES==DS mov si,InitRD mov di,InitRDCName call unmangle_name ; Create human-readable name sub di,InitRDCName mov [InitRDCNameLen],di mov di,InitRD call searchdir ; Look for it in directory @@ -322,25 +342,39 @@ mov [es:su_ramdiskat],edx ; Load address call loadinitrd ; Load initial ramdisk jmp short initrd_end initrd_notthere: mov si,err_noinitrd call cwritestr mov si,InitRDCName call cwritestr mov si,crlf_msg +; begin - freddy77 + cmp byte [initrd_span], 0 + jne retry_disk +; end - freddy77 jmp abort_load no_high_mem: mov si,err_nohighmem ; Error routine jmp abort_load +; begin - freddy77 +change_disk: + mov si, change_disk_msg + call cwritestr + xor ax, ax + int 16h + call load_fat + ret +; end - freddy77 + initrd_end: nk_noinitrd: ; ; Abandon hope, ye that enter here! We do no longer permit aborts. ; call abort_check ; Last chance!! mov si,ready_msg call cwritestr