Troy Telford ttelford.groups@gmail.com writes:
On Thursday, May 20, 2010 12:56:48 pm Eric W. Biederman wrote:
Troy Telford ttelford.groups@gmail.com writes:
On Wednesday, May 19, 2010 05:42:36 am Eric W. Biederman wrote:
The kernel initialization code as of boot protocol 2.10 is now reading the kernel_alignment field. With the field left the kernel attempts to align things to 4GB which is unlikely to work, so change the alignment to the kernels normal value of 16MB so newer kernels process by mkelfImage will boot.
Signed-off-by: "Eric W. Biederman" ebiederm@xmission.com
I've applied the patch and built it. (Twice - once against svn, and once against 2.7.0. It doesn't seem to matter).
The change to work for any of the machines I'm trying it on (mostly the old HDAMA LinuxBIOS machines, but some newer hardware as well).
Odd. That change was enough to get it to work in my testing. In the case that doesn't reboot now could you try adding an earlyprintk=ttyS0,115200 to your command line? With a little luck that will give you some output.
Lady luck rarely smiles upon me. This looks like this is no exception.
I modified the kernel command line to add the 'earlyprintk=<foo>' at the end of the command line, and the result is the same:
- no output until the system rebooted (when using kexec)
- no output at all (etherboot)
Ugh.
I can think of two things that might be useful.
1) Add a print statement into mkelfImage that prints the value of kernel_alignment Most of the fields are already printed so this just requires tweaking linux-i386/convert_params.c
Where you still have a reboot in the kexec case I am a little curious if everything applied ok.
2) What needs to happen is to get a kernel instrumented up with a bunch of debug prints to see where it is failing. The attached linux-debug.S is a serial console print statement that I cut and past into early boot to get print statements before the normal print statement infrastructure initializes. I am posting this more as documentation than anything else.
There are some deep issues with mkelfimage that looks like they need to be fixed for it to survive long term. The current bug with kernel_alignment was caused by not initializing the kernel parameters like the normal kernel does. I think that needs to be fixed, but I'm not going to have time to look at that for a little while yet.
Eric
#if 1 /* Base Address */ #define TTYS0_BASE 0x3f8 /* Data */ #define TTYS0_RBR (TTYS0_BASE+0x00) #define TTYS0_TBR (TTYS0_BASE+0x00) /* Control */ #define TTYS0_IER (TTYS0_BASE+0x01) #define TTYS0_IIR (TTYS0_BASE+0x02) #define TTYS0_FCR (TTYS0_BASE+0x02) #define TTYS0_LCR (TTYS0_BASE+0x03) #define TTYS0_MCR (TTYS0_BASE+0x04)
#define TTYS0_DLL (TTYS0_BASE+0x00) #define TTYS0_DLM (TTYS0_BASE+0x01) /* Status */ #define TTYS0_LSR (TTYS0_BASE+0x05) #define TTYS0_MSR (TTYS0_BASE+0x06) #define TTYS0_SCR (TTYS0_BASE+0x07)
#define TTYS0_BAUD 9600 #define TTYS0_DIV (115200/TTYS0_BAUD) #define TTYS0_DIV_LO (TTYS0_DIV&0xFF) #define TTYS0_DIV_HI ((TTYS0_DIV >> 8)&0xFF)
#if ((115200%TTYS0_BAUD) != 0) #error Bad ttyS0 baud rate #endif
#define TTYS0_INIT \ /* disable interrupts */ \ movb $0x00, %al ; \ movw $TTYS0_IER, %dx ; \ outb %al, %dx ; \ ; \ /* enable fifos */ \ movb $0x01, %al ; \ movw $TTYS0_FCR, %dx ; \ outb %al, %dx ; \ ; \ /* Set Baud Rate Divisor to TTYS0_BAUD */ \ movw $TTYS0_LCR, %dx ; \ movb $0x83, %al ; \ outb %al, %dx ; \ ; \ movw $TTYS0_DLL, %dx ; \ movb $TTYS0_DIV_LO, %al ; \ outb %al, %dx ; \ ; \ movw $TTYS0_DLM, %dx ; \ movb $TTYS0_DIV_HI, %al ; \ outb %al, %dx ; \ ; \ movw $TTYS0_LCR, %dx ; \ movb $0x03, %al ; \ outb %al, %dx
/* uses: ax, dx */ #define TTYS0_TX_AL \ mov %al, %ah ; \ 9: mov $TTYS0_LSR, %dx ; \ inb %dx, %al ; \ test $0x20, %al ; \ je 9b ; \ mov $TTYS0_TBR, %dx ; \ mov %ah, %al ; \ outb %al, %dx
/* uses: ax, dx */ #define TTYS0_TX_CHAR(byte) \ mov byte, %al ; \ TTYS0_TX_AL
/* uses: eax, dx */ #define TTYS0_TX_HEX32(lword) \ mov lword, %eax ; \ shr $28, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $24, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $20, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $16, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $12, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $8, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ shr $4, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %eax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL
/* uses: rax, dx */ #define TTYS0_TX_HEX64(lword) \ mov lword, %rax ; \ shr $60, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $56, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $52, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $48, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $44, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $40, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $36, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $32, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $28, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $24, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $20, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $16, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $12, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $8, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ shr $4, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL ; \ ; \ mov lword, %rax ; \ and $0x0f, %al ; \ add $'0', %al ; \ cmp $'9', %al ; \ jle 9f ; \ add $39, %al ; \ 9: ; \ TTYS0_TX_AL
#define DEBUG(x) TTYS0_TX_CHAR($x) ; TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') #define DEBUG_TX_HEX32(x) TTYS0_TX_HEX32(x); TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') #define DEBUG_TX_HEX64(x) TTYS0_TX_HEX64(x); TTYS0_TX_CHAR($'\r') ; TTYS0_TX_CHAR($'\n') #endif
#if 1 #include <linux/console.h> #include <asm/io.h>
static void ttys0_write(struct console *console, const char *str, unsigned len);
static struct console minimal_serial_console = { write: ttys0_write, flags: CON_ENABLED, next: NULL, };
/* Base Address */ #define TTYS0 0x3f8 /* Data */ #define TTYS0_RBR (TTYS0+0x00) #define TTYS0_TBR (TTYS0+0x00) /* Control */ #define TTYS0_IER (TTYS0+0x01) #define TTYS0_IIR (TTYS0+0x02) #define TTYS0_FCR (TTYS0+0x02) #define TTYS0_LCR (TTYS0+0x03) #define TTYS0_MCR (TTYS0+0x04)
#define TTYS0_DLL (TTYS0+0x00) #define TTYS0_DLM (TTYS0+0x01) /* Status */ #define TTYS0_LSR (TTYS0+0x05) #define TTYS0_MSR (TTYS0+0x06) #define TTYS0_SCR (TTYS0+0x07)
#define TTYS0_BAUD 115200 #define TTYS0_DIV (115200/TTYS0_BAUD)
static void ttys0_init(void) { /* disable interrupts */ outb(0x0, TTYS0_IER); /* enable fifo's */ outb(0x01, TTYS0_FCR); /* Set Baud Rate Divisor to TTYS0_BAUD */ outb(0x83, TTYS0_LCR); outb(TTYS0_DIV & 0xFF, TTYS0_DLL); outb((TTYS0_DIV >> 8) & 0xFF, TTYS0_DLM); outb(0x03, TTYS0_LCR);
} static void ttys0_tx_byte(unsigned byte) { while((inb(TTYS0_LSR) & 0x20) == 0) ; outb(byte, TTYS0_TBR); } static void ttys0_write(struct console *console, const char *str, unsigned len) { static int firsttime = 1; int c; if ((console->next) || (console_drivers != &minimal_serial_console)) return; if (firsttime) { firsttime = 0; ttys0_init(); } while(len--) { c = *str++; if (c == '\n') { ttys0_tx_byte('\r'); } ttys0_tx_byte(c); } }
#endif
#if 1 console_drivers = &minimal_serial_console; #endif xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx static void put_hex(unsigned long val) { static const char digit[] = "0123456789abcdef"; char buf[sizeof(val)*2 +1]; int i,j; for(j = 0, i = sizeof(val)*8 -4; i >= 0; i -= 4, j++) { buf[j] = digit[(val >> i) & 0xf]; } buf[j] = '\0'; puts(buf); } xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx #if 1 /* Base Address */ #define TTYS0 0x3f8 #define TTYS0_LSR (TTYS0+0x05) #define TTYS0_TBR (TTYS0+0x00)
static void serial_tx_byte(unsigned byte) { /* Wait until I can send a byte */ while((inb(TTYS0_LSR) & 0x20) == 0) ; outb(byte, TTYS0_TBR); /* Wait until the byte is transmitted */ while(!(inb(TTYS0_LSR) & 0x40)) ; } static void serial_puts(const char *str) { int c; while( ( c = *str++ ) != '\0') { if (c == '\n') { serial_tx_byte('\r'); } serial_tx_byte(c); } } #endif
static void puts(const char *s) { vid_puts(s); #if 1 serial_puts(s); #endif } xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx #if 1 /* Base Address */ #define TTYS0 0x3f8 #define TTYS0_LSR (TTYS0+0x05) #define TTYS0_TBR (TTYS0+0x00)
static void serial_tx_byte(unsigned byte) { /* Wait until I can send a byte */ while((inb(TTYS0_LSR) & 0x20) == 0) ; outb(byte, TTYS0_TBR); /* Wait until the byte is transmitted */ while(!(inb(TTYS0_LSR) & 0x40)) ; } static void serial_tx_hex(unsigned long val) { int i,j; for(j = 0, i = sizeof(val)*8 -4; i >= 0; i -= 4, j++) { unsigned digit; digit = ((val >> i) & 0xf) + '0'; if (digit > '9') digit += 39; serial_tx_byte(digit); } } static void serial_nl(void) { serial_tx_byte('\r'); serial_tx_byte('\n'); } static void debug(unsigned byte) { serial_tx_byte(byte); serial_nl(); }
static void debug_hex(unsigned byte, unsigned long val) { serial_tx_byte(byte); serial_tx_byte(' '); serial_tx_hex(val); serial_nl(); }
#endif
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX