GRUB on DOC: 2Mb issues

David Woodhouse dwmw2 at infradead.org
Wed Aug 30 12:31:36 EDT 2000


dwmw2 at infradead.org said:
>  I can hack this up and get it to work on the 512-byte devices if you
> like.

I've hacked it up. It doesn't yet work but I'm going home. I've committed 
the changes to makecsum.c, and that should now work on both types of device 
- it definitely works on the 512-byte-page devices.

The actual Grub loader code doesn't yet work so I haven't yet committed it. 
It's horribly ugly too. Patch below.


Index: doc_stage1.S
===================================================================
RCS file: /home/cvs/mtd/grub/doc_stage1.S,v
retrieving revision 1.8
diff -u -r1.8 doc_stage1.S
--- doc_stage1.S	2000/06/01 00:49:18	1.8
+++ doc_stage1.S	2000/08/30 15:30:51
@@ -29,19 +29,18 @@
  *  defines for the code go here
  */
 
+#define LOADLEN (((STAGE2_SIZE + 0xff) & ~0xff) >> 8)
+#define GRUBLOADOFS	0x300
+
 #ifdef OLDGRUB /* Loading Erich's old grub */
 
-#define LOADLEN (((STAGE2_SIZE + 0xff) & ~0xff) >> 8)
-#define GRUBSTART 0x8000
-#define GRUBLOADSEG	0x7e0
-#define GRUBLOADOFS	0x200
+#define GRUBSTART	0x8000
+#define GRUBLOADSEG	0x7d0
 
 #else /* Loading FSF grub */
 
-#define LOADLEN (((((STAGE2_SIZE + 0xff) & ~0xff) + 0x200)) >> 8)
-#define GRUBSTART 0x8200
-#define GRUBLOADSEG	0x800
-#define GRUBLOADOFS	0x000
+#define GRUBSTART	0x8200
+#define GRUBLOADSEG	0x7f0
 
 #endif
 
@@ -103,7 +102,7 @@
 	movw	$int19,0x0064
 
 		/* Copy ourself into the new segment we've just reserved */
-	movw	$0x80, %cx
+	movw	$0x200, %cx
 	cld
 	pushw	%cs
 	popw	%ds
@@ -127,18 +126,14 @@
 		/* Set up our target address for writing stage2 */
 	movw	$GRUBLOADSEG, %ax
 	movw	%ax, %es
-#if	GRUBLOADOFS == 0
-	xorw	%di, %di
-#else
 	movw	$GRUBLOADOFS, %di
-#endif
 
-		/* Contents of DiskOnChip are loaded at 0000:8000 */
-		/* The first 0x200 bytes of this is in fact this bootloader,
-		 *   and it replaces the bootloader which CVS grub has now
-		 *   added to the beginning of stage2
-		 * Stage2 proper starts at 0x08200, which is convenient.
-		 */
+		/* Stage2 proper starts at offset 0x300 on the flash. We
+		   have defined the load address GRUBLOADSEG so that
+		   we're loading this to 0x8000:0000 or 0x8000:0200, 
+		   depending on whether this is old or GNU Grub, 
+		   respectively.
+		*/
 
 	cld
 
@@ -157,12 +152,157 @@
 
 		/* Load %CX with the number of 256-byte blocks to load */	
 	movw	$LOADLEN, %cx
+
+		/* 
+		   Basically, we know that the DiskOnChip IPL ROM will 
+		   load only the first 256 bytes of each 512-byte page
+		   from a 512-byte-page device, but it'll load _all_
+		   the data from a 256-byte-page device.
+		   
+		   Therefore, we put the code to handle 256-byte-page
+		   devices at offset 0x100, where we know it won't get
+		   loaded if we're actually on a 512-byte-page device.
+		   We put the code to handle 512-byte-page devices at
+		   0x200, in the knowledge that it'll get loaded to 
+		   offset 0x100 if it's appropriate.
+
+		   Now, we don't have to probe the device, we just 
+		   jump to the code at 0x100, because we _know_ that 
+		   the IPL ROM will have loaded the correct code there.
+		   
+		   This is SICK. I love it. 
+		*/
+
+	jmp	mainloop
+
+	/* Routines used by both 256- and 512- byte/page loaders.
+
+                /* doc_cmd:      Send a command to the flash chip */
+doc_cmd:
+                /* Enable CLE line to flash */
+        movb    $CSDN_CTRL_FLASH_IO + CSDN_CTRL_WP + CSDN_CTRL_CLE + CSDN_CTRL_CE, BX_CSDNControl
+                /* Dummy */
+        incw    -4(%bx)
+                /* Write the actual command */
+        movb    %ah,BX_SlowIO
+        movb    %ah,(%si)
+
+                /* doc_wait:     Wait for the DiskOnChip to be ready */
+doc_wait:
+        incw    BX_ChipID
+l38:    
+        testb   $0x80,BX_CSDNControl
+        jz      l38
+        test    BX_CSDNControl,%dx
+        ret
+                
+
+/*
+ * message: write the string pointed to by %si
+ *
+ *   WARNING: trashes %si, %ax, and %bx
+ */
+
+	/*
+	 * Use BIOS "int 10H Function 0Eh" to write character in teletype mode
+	 *	%ah = 0xe	%al = character
+	 *	%bh = page	%bl = foreground color (graphics modes)
+	 */
+1:
+	movw	$0x0001, %bx
+	movb	$0xe, %ah
+	int	$0x10		/* display a byte */
+
+message:
+	lodsb
+	cmpb	$0, %al
+	jne	1b	/* if not end of string, jmp to display */
+	ret
+
+	/* Hex output routines, used at one point in debugging */	
+
+doc_seg:	.word 0
+	
+int19_execed_string:	.string "Loading GRUB from DiskOnChip\n\r"
+
+
+
+	
+	
+		/* Code for 256-byte-page devices. */
+	.org 0x100
+mainloop:	
+mainloop256:
+                /* We're still reading a block */
+//      testw   $0xff, %di
+//      jnz     readbyte
+
+                /* Send new READ0 command */
+
+        movw    %di, %ax
+        xorb    %ah, %ah
+        call    doc_cmd
+
+                /* Start of new block. Set address */
+        movb    $CSDN_CTRL_FLASH_IO + CSDN_CTRL_WP + CSDN_CTRL_ALE + CSDN_CTRL_CE, BX_CSDNControl
+        incw    BX_ChipID
+
+                /* We sent bits 0-7, then 8-15, then 16-23 */
+        movw    %di, %dx
+                /* Bits 0-7 are always zero */
+        movb    $0,BX_SlowIO
+        movb    $0,SI_CSDN_IO
+                        /* Bits 8-15 */
+        movb    %dh,BX_SlowIO
+        movb    %dh,SI_CSDN_IO
+                /* Bits 16-23 */
+        .byte   0xb2 /* movb adrbytehi, %dl */
+adrbytehi256:
+        .byte   0
+        movb    %dl,BX_SlowIO
+        movb    %dl,SI_CSDN_IO
+
+                /* Clear the ALE line to the flash chip */
+        movb    $CSDN_CTRL_FLASH_IO + CSDN_CTRL_WP + CSDN_CTRL_CE, BX_CSDNControl
+        call    doc_wait
+
+        pushw   %cx             /* Store the 'blocks remaining' count */
+        movw    $0x100, %cx     /* Set up to copy 0x100 bytes */
+readbyte256:       
+        testb   BX_SlowIO,%al   /* dummy read */
+        movsb                   /* movb SI_CSDN_IO ;  stosb would be more obvious, */
+        decw    %si             /*  but would take an extra byte. */
+        loop    readbyte256
+
+
+        testw   $0xffff, %di    /* Check if we've done a whole 0x10000 bytes */
+        jnz     endloop256      /* No - continue regardless */
+                /* Yes - increase %es */
+        movw    %es, %cx
+        addb    $0x10, %ch
+        movw    %cx, %es
+
+        incb    %cs:adrbytehi256           /* If so, increase the high byte too */
+
+endloop256:        
+        popw    %cx             /* Restore the 'blocks remaining' count */
+        loop    mainloop256     /* Loop till completely done */
+good256:   
+                /* Run it:       jmpf 0:2000 */
+
+       .byte   0xea
+        .word   GRUBSTART,0
 
-mainloop:
-		/* We're still reading a block */
-//	testw	$0xff, %di
-//	jnz	readbyte
+	.org 0x1ff
+	.byte 0 /* checksum */
 
+	
+	
+		/* Code for 512-byte-page devices. */
+
+	.org 0x200
+mainloop512:
+
 		/* Send new READ command - is it READ0 or READ1? */
 
 	movw	%di, %ax
@@ -188,7 +328,7 @@
 	movb	%dh,SI_CSDN_IO
 		/* Bits 17-23 are also zero */
 	.byte	0xb2 /* movb adrbytehi, %dl */
-adrbytehi:
+adrbytehi512:
 	.byte	0
 	movb	%dl,BX_SlowIO
 	movb	%dl,SI_CSDN_IO
@@ -199,117 +339,34 @@
 
 	pushw	%cx		/* Store the 'blocks remaining' count */
 	movw	$0x100, %cx	/* Set up to copy 0x100 bytes */
-readbyte:	
+readbyte512:	
 	testb	BX_SlowIO,%al	/* dummy read */
 	movsb			/* movb SI_CSDN_IO ;  stosb would be more obvious, */
 	decw	%si		/*  but would take an extra byte. */
-	loop	readbyte
+	loop	readbyte512
 
 
 	testw	$0xffff, %di	/* Check if we've done a whole 0x10000 bytes */
-	jnz	endloop		/* No - continue regardless */
+	jnz	endloop512		/* No - continue regardless */
 		/* Yes - increase %es */
 	movw	%es, %cx
 	addb	$0x10, %ch
 	movw	%cx, %es
 
 	addb	$0x80, %cs:adrbit16	/* Increase bit 16 */
-	jnc	endloop			/* Did it overflow? */
-	incb	%cs:adrbytehi		/* If so, increase the high byte too */
+	jnc	endloop512			/* Did it overflow? */
+	incb	%cs:adrbytehi512		/* If so, increase the high byte too */
 
-endloop:	
+endloop512:	
 	popw	%cx		/* Restore the 'blocks remaining' count */
-	loop	mainloop	/* Loop till completely done */
-good:	
+	loop	mainloop512	/* Loop till completely done */
+good512:	
 		/* Run it:	 jmpf 0:2000 */
 
 	.byte	0xea
 	.word	GRUBSTART,0
-
-		/* doc_cmd:	 Send a command to the flash chip */
-doc_cmd:
-		/* Enable CLE line to flash */
-	movb	$CSDN_CTRL_FLASH_IO + CSDN_CTRL_WP + CSDN_CTRL_CLE + CSDN_CTRL_CE, BX_CSDNControl
-		/* Dummy */
-	incw	-4(%bx)
-		/* Write the actual command */
-	movb	%ah,BX_SlowIO
-	movb	%ah,(%si)
 
-		/* doc_wait:	 Wait for the DiskOnChip to be ready */
-doc_wait:
-	incw	BX_ChipID
-l38:	
-	testb	$0x80,BX_CSDNControl
-	jz	l38
-	test	BX_CSDNControl,%dx
-	ret
-		
+	.org 0x2ff
+	.byte 0 /* checksum */
 
 	
-doc_seg:	.word 0
-	
-int19_execed_string:	.string "Loading GRUB from DiskOnChip\n\r"
-
-/*
- * message: write the string pointed to by %si
- *
- *   WARNING: trashes %si, %ax, and %bx
- */
-
-	/*
-	 * Use BIOS "int 10H Function 0Eh" to write character in teletype mode
-	 *	%ah = 0xe	%al = character
-	 *	%bh = page	%bl = foreground color (graphics modes)
-	 */
-1:
-	movw	$0x0001, %bx
-	movb	$0xe, %ah
-	int	$0x10		/* display a byte */
-
-message:
-	lodsb
-	cmpb	$0, %al
-	jne	1b	/* if not end of string, jmp to display */
-	ret
-
-	/* Hex output routines, used at one point in debugging */	
-#if 0
-phword:
-	pushw	%ax
-	xchgb	%al,%ah
-	call	phbyte
-	movb	%ah,%al
-	call	phbyte
-	popw	%ax
-	ret
-
-
-phbyte:
-	pushw	%ax
-	movb	%al, %ah
-	shrb	$4,%al
-	call	phnibble
-	movb	%ah, %al
-	call	phnibble
-	popw	%ax
-	ret
-
-phnibble:
-	pushw	%ax
-	andb	$0xf,%al
-	addb	$48,%al
-	cmpb	$57,%al
-	jna	ph1
-	add	$7,%al
-ph1:	mov	$0xe,%ah
-	int	$0x10
-	popw	%ax
-	ret
-#endif
-
-#if 0
-		/* Cause an error if this code was too large. */
-	.org 0xff
-	.byte 0 /* Placement of checksum byte */
-#endif	




--
dwmw2




To unsubscribe, send "unsubscribe mtd" to majordomo at infradead.org



More information about the linux-mtd mailing list